UNPKG

5.28 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
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 // Return empty options for PostCSS
128 return {}
129 }
130 throw err
131 })
132
133 if (postcssConfig.file) {
134 logger.debug('postcss config location', postcssConfig.file)
135
136 // Only feed the config path to postcss-loader
137 // In order to let postcss-loader ask webpack to watch it
138 options.postcss = {
139 config: {
140 path: postcssConfig.file
141 }
142 }
143 } else {
144 // No PostCSS config file was found
145 // Set `plugins` to an empty array so `postcss-loader` won't try to find config file again
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), // Only enable CSS sourceMap in dev mode
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}