UNPKG

zoro-cli

Version:

https://github.com/vuejs/vue-cli

271 lines (233 loc) 7.64 kB
const path = require('path') const PnpWebpackPlugin = require('pnp-webpack-plugin') const { resolveCwd } = require('zoro-cli-util/resolve') const cwd = process.cwd() module.exports = ({ api, options, envUtil, args, pkg }) => { const { node } = options const isProd = envUtil.isProduction() // const useThreads = isProd && options.parallel api.chainWebpack(webpackConfig => { const isLegacyBundle = args.modern && !args.modernBuild const { context = cwd, baseUrl, inlineLimit = 1024 * 10 } = options const { output, resolve } = webpackConfig // context webpackConfig.context(context) // output output.path(api.resolve(args.dest || options.outputDir)) let filename = `[name]${isLegacyBundle ? '-legacy' : ''}` if (isProd) { filename += options.filenameHashing ? '.[contenthash:8]' : '' } filename += '.js' output.filename(filename) if (baseUrl) { output.publicPath(baseUrl) } if (args.watch || args.w) { webpackConfig.watch(true) } // resolve // resolve.symlinks = false may cause HMR to fail https://github.com/vuejs/vue-cli/issues/1559#issuecomment-413427651 // resolve.symlinks = true may cause module resolution to fail when using tools that symlink packages (like npm link) // so to cover the most common use case, set it to true resolve.set('symlinks', true) resolve.extensions.merge(['.js', '.jsx', '.ts', '.tsx', '.vue', '.json']) resolve.modules.add('node_modules') resolve.alias .set('root', api.resolve('.')) .set('src', api.resolve('src')) .set('tests', api.resolve('tests')) .set('test', api.resolve('test')) .set('mock', api.resolve('mock')) .set('axios', 'axios/dist/axios.min') .set( 'vue$', options.runtimeCompiler ? 'vue/dist/vue.esm.js' : 'vue/dist/vue.runtime.esm.js', ) webpackConfig.resolveLoader.modules.add('node_modules') // Ignored files should not have calls to import/require. webpackConfig.module.noParse( /^(vue|vue-router|vuex|vuex-router-sync|react|react-dom)$/, ) // pnp if (pkg && pkg.installConfig && pkg.installConfig.pnp) { api.configureWebpack(() => ({ resolve: { plugins: [PnpWebpackPlugin], }, resolveLoader: { plugins: [PnpWebpackPlugin.moduleLoader(module)], }, })) } /** * loaders begin */ // js is handled by babel // vue if (resolveCwd('vue')) { /* eslint-disable import/no-extraneous-dependencies, import/no-unresolved */ const vueLoaderCacheConfig = api.genCacheConfig('vue-loader', { 'vue-loader': require('vue-loader/package.json').version, '@vue/component-compiler-utils': require('@vue/component-compiler-utils/package.json') .version, 'vue-template-compiler': require('vue-template-compiler/package.json') .version, }) const vueRule = webpackConfig.module .rule('vue') .test(/\.vue$/) .use('cache-loader') .loader('cache-loader') .options(vueLoaderCacheConfig) .end() // if (useThreads) { // vueRule.use('thread-loader').loader('thread-loader') // } vueRule .use('vue-loader') .loader('vue-loader') .options( { compilerOptions: { preserveWhitespace: false, }, ...vueLoaderCacheConfig, }, ) webpackConfig.plugin('vue-loader').use(require('vue-loader/lib/plugin')) /* eslint-enable import/no-extraneous-dependencies, import/no-unresolved */ } // static assets const { outputImgDir, outputMediaDir, outputFontsDir } = options const baseFileName = options.filenameHashing ? '[name].[hash:8].[ext]' : '[name].[ext]?[hash:8]' // html if (options.html) { webpackConfig.module .rule('html') .test(/\.html?$/) .use('file-loader') .loader('file-loader') .options({ name: '[name].[ext]' }) } // images webpackConfig.module .rule('images') .test(/\.(png|jpe?g|gif|webp)(\?.*)?$/) .use('url-loader') .loader('url-loader') .options({ limit: inlineLimit, name: path.posix.join(outputImgDir, baseFileName), }) // svg // do not base64-inline SVGs. // https://github.com/facebookincubator/create-react-app/pull/1180 webpackConfig.module .rule('svg') .test(/\.(svg)(\?.*)?$/) .use('file-loader') .loader('file-loader') .options({ name: path.posix.join(outputImgDir, baseFileName), }) // media webpackConfig.module .rule('media') .test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/) .use('url-loader') .loader('url-loader') .options({ limit: inlineLimit, name: path.posix.join(outputMediaDir, baseFileName), }) // fonts webpackConfig.module .rule('fonts') .test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i) .use('url-loader') .loader('url-loader') .options({ limit: inlineLimit, name: path.posix.join(outputFontsDir, baseFileName), }) // Other common pre-processors webpackConfig.module .rule('pug') .test(/\.pug$/) .use('pug-plain-loader') .loader('pug-plain-loader') .end() /** * loaders end */ // shims // node if (!node) { webpackConfig.node.merge({ // prevent webpack from injecting useless setImmediate polyfill because Vue // source contains it (although only uses it if it's native). setImmediate: false, // process is injected via DefinePlugin, although some 3rd party // libraries may require a mock to work properly (#934) process: 'mock', // prevent webpack from injecting mocks to Node native modules // that does not make sense for the client dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty', }) } /** * plugins begin */ // define webpackConfig.plugin('define').use(require('webpack/lib/DefinePlugin'), [ { 'process.env': { NODE_ENV: JSON.stringify(envUtil.getNodeEnv()), MOCK: JSON.stringify(process.env.MOCK), }, }, ]) webpackConfig .plugin('case-sensitive-paths') .use(require('case-sensitive-paths-webpack-plugin')) // analyze if (args.analyze) { webpackConfig .plugin('analyze') .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [ { analyzerMode: 'static', reportFilename: path.join('..', '_webpack_analyze_', 'report.html'), openAnalyzer: false, generateStatsFile: true, statsFilename: path.join('..', '_webpack_analyze_', 'stats.json'), statsOptions: null, logLevel: 'silent', }, ]) } // friendly error plugin displays very confusing errors when webpack // fails to resolve a loader, so we provide custom handlers to improve it const { transformer, formatter } = require('../util/resolveLoaderError') webpackConfig .plugin('friendly-errors') .use(require('friendly-errors-webpack-plugin'), [ { additionalTransformers: [transformer], additionalFormatters: [formatter], }, ]) /** * plugins end */ }) }