UNPKG

5.04 kBJavaScriptView Raw
1const path = require('path')
2const findBabelConfig = require('find-babel-config')
3const findPostcssConfig = require('postcss-load-config')
4const logger = require('@poi/logger')
5const inferHTML = require('./utils/inferHTML')
6const readProjectPkg = require('./utils/readProjectPkg')
7const normalizeEntry = require('./utils/normalizeEntry')
8const getFilename = require('./utils/getFilename')
9const getPublicPath = require('./utils/getPublicPath')
10const getHotEntry = require('./utils/getHotEntry')
11const getExternals = require('./utils/getExternals')
12
13async function handleBabel(options) {
14 const { file, config } = await findBabelConfig(process.cwd(), 2)
15
16 if (file) {
17 // If root babel config file is found
18 // We set `babelrc` to the its path
19 // To prevent `babel-loader` from loading it again
20 logger.debug('babel config location', file)
21 options.config.babelrc = false
22 // You can use `babelrc: false` to disable the config file itself
23 if (config.babelrc !== false) {
24 options.config.extends = file
25 }
26 } else {
27 // If not found
28 // We set `babelrc` to `false` for the same reason
29 options.config.babelrc = false
30 }
31
32 if (!options.config.extends) {
33 // Use our default preset when no babelrc was specified
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
44function 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
66module.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 // Return empty options for PostCSS
127 return {}
128 }
129 throw err
130 })
131
132 if (postcssConfig.file) {
133 logger.debug('postcss config location', postcssConfig.file)
134
135 // Only feed the config path to postcss-loader
136 // In order to let postcss-loader ask webpack to watch it
137 options.postcss = {
138 config: {
139 path: postcssConfig.file
140 }
141 }
142 } else {
143 // No PostCSS config file was found
144 // Set `plugins` to an empty array so `postcss-loader` won't try to find config file again
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}