1 | const path = require('path')
|
2 | const findBabelConfig = require('find-babel-config')
|
3 | const findPostcssConfig = require('postcss-load-config')
|
4 | const logger = require('@poi/logger')
|
5 | const inferHTML = require('./utils/inferHTML')
|
6 | const readProjectPkg = require('./utils/readProjectPkg')
|
7 | const normalizeEntry = require('./utils/normalizeEntry')
|
8 | const getFilename = require('./utils/getFilename')
|
9 | const getPublicPath = require('./utils/getPublicPath')
|
10 | const getHotEntry = require('./utils/getHotEntry')
|
11 | const getExternals = require('./utils/getExternals')
|
12 |
|
13 | async function handleBabel(options) {
|
14 | const { file, config } = await findBabelConfig(process.cwd(), 2)
|
15 |
|
16 | if (file) {
|
17 |
|
18 |
|
19 |
|
20 | logger.debug('babel config location', file)
|
21 | options.config.babelrc = false
|
22 |
|
23 | if (config.babelrc !== false) {
|
24 | options.config.extends = file
|
25 | }
|
26 | } else {
|
27 |
|
28 |
|
29 | options.config.babelrc = false
|
30 | }
|
31 |
|
32 | if (!options.config.extends) {
|
33 |
|
34 | options.config.presets = [
|
35 | [require.resolve('babel-preset-poi'), { jsx: options.jsx }]
|
36 | ]
|
37 | }
|
38 |
|
39 | options.config.cacheDirectory = true
|
40 |
|
41 | return options
|
42 | }
|
43 |
|
44 | function handleHTML({ html, minimize, env }) {
|
45 | if (html === false) return false
|
46 |
|
47 | const htmls = Array.isArray(html) ? html : [html || {}]
|
48 |
|
49 | const defaultHtmlOption = Object.assign({ env }, inferHTML())
|
50 |
|
51 | return htmls.map((h, i) => {
|
52 | return Object.assign(
|
53 | {
|
54 | minify: {
|
55 | collapseWhitespace: minimize,
|
56 | minifyCSS: minimize,
|
57 | minifyJS: minimize
|
58 | }
|
59 | },
|
60 | defaultHtmlOption,
|
61 | h
|
62 | )
|
63 | })
|
64 | }
|
65 |
|
66 | module.exports = async ({ options, command, env }) => {
|
67 | options = Object.assign(
|
68 | {
|
69 | entry: readProjectPkg().main || 'index.js',
|
70 | cwd: process.cwd(),
|
71 | vue: {},
|
72 | css: {},
|
73 | hash: !options.format && command === 'build'
|
74 | },
|
75 | options
|
76 | )
|
77 |
|
78 | options.devServer = Object.assign(
|
79 | {
|
80 | host: options.host || process.env.HOST || '0.0.0.0',
|
81 | port: options.port || process.env.PORT || 4000
|
82 | },
|
83 | options.devServer
|
84 | )
|
85 | options.babel = Object.assign(
|
86 | {
|
87 | jsx: 'react',
|
88 | config: {}
|
89 | },
|
90 | options.babel
|
91 | )
|
92 |
|
93 | options.entry = normalizeEntry(options.entry)
|
94 | options.filename = getFilename(options.hash, options.filename)
|
95 | options.outDir = path.resolve(options.outDir || 'dist')
|
96 | options.publicPath = getPublicPath(command, options.publicPath)
|
97 | options.hotReload = options.hotReload !== false && command === 'develop'
|
98 | options.hotEntry = getHotEntry(options.hotEntry)
|
99 | options.minimize =
|
100 | typeof options.minimize === 'boolean'
|
101 | ? options.minimize
|
102 | : command === 'build'
|
103 | options.html =
|
104 | options.format || command === 'test'
|
105 | ? false
|
106 | : handleHTML({
|
107 | minimize: options.minimize,
|
108 | env,
|
109 | html: options.html
|
110 | })
|
111 | options.sourceMap = options.format
|
112 | ? false
|
113 | : options.sourceMap === false || typeof options.sourceMap === 'string'
|
114 | ? options.sourceMap
|
115 | : command === 'build'
|
116 | ? 'source-map'
|
117 | : command === 'test' ? 'inline-source-map' : 'eval-source-map'
|
118 |
|
119 | options.externals = getExternals(options).concat(options.externals || [])
|
120 | options.babel = await handleBabel(options.babel)
|
121 |
|
122 | if (options.postcss === undefined) {
|
123 | const postcssConfig = await findPostcssConfig({}, options.cwd, {
|
124 | argv: false
|
125 | }).catch(err => {
|
126 | if (err.message.includes('No PostCSS Config found')) {
|
127 |
|
128 | return {}
|
129 | }
|
130 | throw err
|
131 | })
|
132 |
|
133 | if (postcssConfig.file) {
|
134 | logger.debug('postcss config location', postcssConfig.file)
|
135 |
|
136 |
|
137 |
|
138 | options.postcss = {
|
139 | config: {
|
140 | path: postcssConfig.file
|
141 | }
|
142 | }
|
143 | } else {
|
144 |
|
145 |
|
146 | options.postcss = {
|
147 | plugins: []
|
148 | }
|
149 | }
|
150 | }
|
151 |
|
152 | options.postcss = options.postcss || {}
|
153 |
|
154 | options.css = {
|
155 | minimize: options.minimize,
|
156 | extract:
|
157 | typeof options.css.extract === 'boolean'
|
158 | ? options.css.extract
|
159 | : command === 'build',
|
160 | extractLoader: options.css.extractLoader,
|
161 | sourceMap:
|
162 | typeof options.css.sourceMap === 'boolean'
|
163 | ? options.css.sourceMap
|
164 | : command === 'develop' && Boolean(options.sourceMap),
|
165 | postcss: options.postcss,
|
166 | cssModules: options.css.modules,
|
167 | styleLoader: 'vue-style-loader',
|
168 | filename: options.filename.css,
|
169 | chunkFilename: options.filename.chunk.replace(/\.js$/, '.css')
|
170 | }
|
171 |
|
172 | if (options.entry === undefined && !options.format) {
|
173 | const mainField = readProjectPkg().main
|
174 | if (mainField) {
|
175 | logger.debug('webpack', 'Using main field in package.json as entry point')
|
176 | options.entry = mainField
|
177 | }
|
178 | }
|
179 |
|
180 | return options
|
181 | }
|