UNPKG

zoro-cli

Version:

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

165 lines (148 loc) 4.65 kB
const path = require('path') const globby = require('globby') const { error } = require('zoro-cli-util/logger') function genNestedEntry(entryDir) { const entry = {} const arr = globby.sync(['**/*.{js,jsx,ts,tsx}'], { cwd: entryDir, gitignore: true, }) arr.forEach(rawName => { const key = rawName.replace(/.(js|jsx|ts|tsx)$/, '') entry[key] = path.join(entryDir, rawName) }) return entry } module.exports = ({ api, options, envUtil, args }) => { if (options.target !== 'app') return api.chainWebpack(webpackConfig => { const isProd = envUtil.isProduction() const { entryDir } = options // entry if (entryDir) { webpackConfig.entryPoints.clear() const entry = genNestedEntry(entryDir) Object.keys(entry).forEach(name => { webpackConfig .entry(name) // use absolute path for windows .add(path.resolve(options.outputJsDir, entry[name])) }) } // code splitting if (isProd || args.split) { const cacheGroups = { vendors: false, default: false, } let split = options.split || args.split if (typeof split !== 'string') { split = 'common' } if (split === 'vendors') { cacheGroups.vendors = { name: 'vendors', test: /[\\/]node_modules[\\/]/, priority: -10, chunks: 'initial', } } else if (split === 'common') { cacheGroups.common = { name: 'common', minChunks: 2, priority: -20, reuseExistingChunk: true, chunks: 'initial', } } else { error('"split" must be specified to one of ["vendors", "common"]') } // code splitting webpackConfig.optimization.splitChunks({ cacheGroups, }) } const fs = require('fs') // HTML const nohtml = options.nohtml || args.nohtml if (!nohtml) { const { metadata = {} } = options const htmlPath = api.resolve('src/assets/template/index.html') Object.keys(webpackConfig.entryPoints.entries() || {}).forEach(entry => { const htmlOptions = { filename: path.posix.join( options.outputHtmlDir || '', `${entry}.html`, ), chunks: ['vendors', 'common', entry], NODE_ENV: process.env.NODE_ENV, ...metadata.base, ...metadata[entry], } // template path const entryHtmlPath = htmlPath.replace('index', entry) if (fs.existsSync(entryHtmlPath)) { htmlOptions.template = entryHtmlPath } else if (fs.existsSync(htmlPath)) { htmlOptions.template = htmlPath } // minify HTML all the time Object.assign(htmlOptions, { minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: false, collapseBooleanAttributes: true, removeScriptTypeAttributes: true, // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency', }) webpackConfig .plugin(`html-${entry}`) .use(require('html-webpack-plugin'), [htmlOptions]) }) } // FIXME: inject preload/prefetch to HTML // const PreloadPlugin = require('preload-webpack-plugin') // webpackConfig.plugin('preload').use(PreloadPlugin, [ // { // rel: 'preload', // include: 'initial', // fileBlacklist: [/\.map$/, /hot-update\.js$/], // }, // ]) // webpackConfig.plugin('prefetch').use(PreloadPlugin, [ // { // rel: 'prefetch', // include: 'asyncChunks', // }, // ]) // copy static assets in public/ if (fs.existsSync(api.resolve('public'))) { const copyTo = api.resolve(args.dest || options.outputDir) webpackConfig.plugin('copy').use(require('copy-webpack-plugin'), [ [ { from: api.resolve('public'), to: copyTo, ignore: ['.DS_Store', '.gitkeep'], }, ], ]) } // profile if (args.profile) { webpackConfig .plugin('profile') .use(require('webpack/lib/debug/ProfilingPlugin'), [ { // do not nested folder here, the plugin is stuid to generate intermediate folders outputPath: '_webpack_profile_events.json', }, ]) } }) }