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