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 | options.devServer = Object.assign(
|
78 | {
|
79 | host: process.env.HOST || '0.0.0.0',
|
80 | port: process.env.PORT || 4000
|
81 | },
|
82 | options.devServer
|
83 | )
|
84 | options.babel = Object.assign(
|
85 | {
|
86 | jsx: 'react',
|
87 | config: {}
|
88 | },
|
89 | options.babel
|
90 | )
|
91 |
|
92 | options.entry = normalizeEntry(options.entry)
|
93 | options.filename = getFilename(options.hash, options.filename)
|
94 | options.outDir = path.resolve(options.outDir || 'dist')
|
95 | options.publicPath = getPublicPath(command, options.publicPath)
|
96 | options.hotReload = options.hotReload !== false && command === 'develop'
|
97 | options.hotEntry = getHotEntry(options.hotEntry)
|
98 | options.minimize =
|
99 | typeof options.minimize === 'boolean'
|
100 | ? options.minimize
|
101 | : command === 'build'
|
102 | options.html =
|
103 | options.format || command === 'test'
|
104 | ? false
|
105 | : handleHTML({
|
106 | minimize: options.minimize,
|
107 | env,
|
108 | html: options.html
|
109 | })
|
110 | options.sourceMap = options.format
|
111 | ? false
|
112 | : options.sourceMap === false || typeof options.sourceMap === 'string'
|
113 | ? options.sourceMap
|
114 | : command === 'build'
|
115 | ? 'source-map'
|
116 | : command === 'test' ? 'inline-source-map' : 'eval-source-map'
|
117 |
|
118 | options.externals = getExternals(options).concat(options.externals || [])
|
119 | options.babel = await handleBabel(options.babel)
|
120 |
|
121 | if (options.postcss === undefined) {
|
122 | const postcssConfig = await findPostcssConfig({}, options.cwd, {
|
123 | argv: false
|
124 | }).catch(err => {
|
125 | if (err.message.includes('No PostCSS Config found')) {
|
126 |
|
127 | return {}
|
128 | }
|
129 | throw err
|
130 | })
|
131 |
|
132 | if (postcssConfig.file) {
|
133 | logger.debug('postcss config location', postcssConfig.file)
|
134 |
|
135 |
|
136 |
|
137 | options.postcss = {
|
138 | config: {
|
139 | path: postcssConfig.file
|
140 | }
|
141 | }
|
142 | } else {
|
143 |
|
144 |
|
145 | options.postcss = {
|
146 | plugins: []
|
147 | }
|
148 | }
|
149 | }
|
150 |
|
151 | options.postcss = options.postcss || {}
|
152 |
|
153 | options.css = {
|
154 | minimize: options.minimize,
|
155 | extract:
|
156 | typeof options.css.extract === 'boolean'
|
157 | ? options.css.extract
|
158 | : command === 'build',
|
159 | sourceMap: Boolean(options.sourceMap),
|
160 | postcss: options.postcss,
|
161 | cssModules: options.css.modules,
|
162 | styleLoader: 'vue-style-loader',
|
163 | filename: options.filename.css,
|
164 | chunkFilename: options.filename.chunk.replace(/\.js$/, '.css')
|
165 | }
|
166 |
|
167 | if (options.entry === undefined && !options.format) {
|
168 | const mainField = readProjectPkg().main
|
169 | if (mainField) {
|
170 | logger.debug('webpack', 'Using main field in package.json as entry point')
|
171 | options.entry = mainField
|
172 | }
|
173 | }
|
174 |
|
175 | return options
|
176 | }
|