Spaces:
Running
Running
| const defaults = { | |
| clean: true, | |
| target: 'app', | |
| formats: 'commonjs,umd,umd-min', | |
| 'unsafe-inline': true | |
| } | |
| const buildModes = { | |
| lib: 'library', | |
| wc: 'web component', | |
| 'wc-async': 'web component (async)' | |
| } | |
| const modifyConfig = (config, fn) => { | |
| if (Array.isArray(config)) { | |
| config.forEach(c => fn(c)) | |
| } else { | |
| fn(config) | |
| } | |
| } | |
| module.exports = (api, options) => { | |
| api.registerCommand('build', { | |
| description: 'build for production', | |
| usage: 'vue-cli-service build [options] [entry|pattern]', | |
| options: { | |
| '--mode': `specify env mode (default: production)`, | |
| '--dest': `specify output directory (default: ${options.outputDir})`, | |
| '--modern': `build app targeting modern browsers with auto fallback`, | |
| '--no-unsafe-inline': `build app without introducing inline scripts`, | |
| '--target': `app | lib | wc | wc-async (default: ${defaults.target})`, | |
| '--inline-vue': 'include the Vue module in the final bundle of library or web component target', | |
| '--formats': `list of output formats for library builds (default: ${defaults.formats})`, | |
| '--name': `name for lib or web-component mode (default: "name" in package.json or entry filename)`, | |
| '--filename': `file name for output, only usable for 'lib' target (default: value of --name)`, | |
| '--no-clean': `do not remove the dist directory before building the project`, | |
| '--report': `generate report.html to help analyze bundle content`, | |
| '--report-json': 'generate report.json to help analyze bundle content', | |
| '--skip-plugins': `comma-separated list of plugin names to skip for this run`, | |
| '--watch': `watch for changes`, | |
| '--stdin': `close when stdin ends` | |
| } | |
| }, async (args, rawArgs) => { | |
| for (const key in defaults) { | |
| if (args[key] == null) { | |
| args[key] = defaults[key] | |
| } | |
| } | |
| args.entry = args.entry || args._[0] | |
| if (args.target !== 'app') { | |
| args.entry = args.entry || 'src/App.vue' | |
| } | |
| process.env.VUE_CLI_BUILD_TARGET = args.target | |
| if (args.modern && args.target === 'app') { | |
| process.env.VUE_CLI_MODERN_MODE = true | |
| if (!process.env.VUE_CLI_MODERN_BUILD) { | |
| // main-process for legacy build | |
| await build(Object.assign({}, args, { | |
| modernBuild: false, | |
| keepAlive: true | |
| }), api, options) | |
| // spawn sub-process of self for modern build | |
| const { execa } = require('@vue/cli-shared-utils') | |
| const cliBin = require('path').resolve(__dirname, '../../../bin/vue-cli-service.js') | |
| await execa('node', [cliBin, 'build', ...rawArgs], { | |
| stdio: 'inherit', | |
| env: { | |
| VUE_CLI_MODERN_BUILD: true | |
| } | |
| }) | |
| } else { | |
| // sub-process for modern build | |
| await build(Object.assign({}, args, { | |
| modernBuild: true, | |
| clean: false | |
| }), api, options) | |
| } | |
| delete process.env.VUE_CLI_MODERN_MODE | |
| } else { | |
| if (args.modern) { | |
| const { warn } = require('@vue/cli-shared-utils') | |
| warn( | |
| `Modern mode only works with default target (app). ` + | |
| `For libraries or web components, use the browserslist ` + | |
| `config to specify target browsers.` | |
| ) | |
| } | |
| await build(args, api, options) | |
| } | |
| delete process.env.VUE_CLI_BUILD_TARGET | |
| }) | |
| } | |
| async function build (args, api, options) { | |
| const fs = require('fs-extra') | |
| const path = require('path') | |
| const webpack = require('webpack') | |
| const { chalk } = require('@vue/cli-shared-utils') | |
| const formatStats = require('./formatStats') | |
| const validateWebpackConfig = require('../../util/validateWebpackConfig') | |
| const { | |
| log, | |
| done, | |
| info, | |
| logWithSpinner, | |
| stopSpinner | |
| } = require('@vue/cli-shared-utils') | |
| log() | |
| const mode = api.service.mode | |
| if (args.target === 'app') { | |
| const bundleTag = args.modern | |
| ? args.modernBuild | |
| ? `modern bundle ` | |
| : `legacy bundle ` | |
| : `` | |
| logWithSpinner(`Building ${bundleTag}for ${mode}...`) | |
| } else { | |
| const buildMode = buildModes[args.target] | |
| if (buildMode) { | |
| const additionalParams = buildMode === 'library' ? ` (${args.formats})` : `` | |
| logWithSpinner(`Building for ${mode} as ${buildMode}${additionalParams}...`) | |
| } else { | |
| throw new Error(`Unknown build target: ${args.target}`) | |
| } | |
| } | |
| if (args.dest) { | |
| // Override outputDir before resolving webpack config as config relies on it (#2327) | |
| options.outputDir = args.dest | |
| } | |
| const targetDir = api.resolve(options.outputDir) | |
| const isLegacyBuild = args.target === 'app' && args.modern && !args.modernBuild | |
| // resolve raw webpack config | |
| let webpackConfig | |
| if (args.target === 'lib') { | |
| webpackConfig = require('./resolveLibConfig')(api, args, options) | |
| } else if ( | |
| args.target === 'wc' || | |
| args.target === 'wc-async' | |
| ) { | |
| webpackConfig = require('./resolveWcConfig')(api, args, options) | |
| } else { | |
| webpackConfig = require('./resolveAppConfig')(api, args, options) | |
| } | |
| // check for common config errors | |
| validateWebpackConfig(webpackConfig, api, options, args.target) | |
| if (args.watch) { | |
| modifyConfig(webpackConfig, config => { | |
| config.watch = true | |
| }) | |
| } | |
| if (args.stdin) { | |
| process.stdin.on('end', () => { | |
| process.exit(0) | |
| }) | |
| process.stdin.resume() | |
| } | |
| // Expose advanced stats | |
| if (args.dashboard) { | |
| const DashboardPlugin = require('../../webpack/DashboardPlugin') | |
| modifyConfig(webpackConfig, config => { | |
| config.plugins.push(new DashboardPlugin({ | |
| type: 'build', | |
| modernBuild: args.modernBuild, | |
| keepAlive: args.keepAlive | |
| })) | |
| }) | |
| } | |
| if (args.report || args['report-json']) { | |
| const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer') | |
| modifyConfig(webpackConfig, config => { | |
| const bundleName = args.target !== 'app' | |
| ? config.output.filename.replace(/\.js$/, '-') | |
| : isLegacyBuild ? 'legacy-' : '' | |
| config.plugins.push(new BundleAnalyzerPlugin({ | |
| logLevel: 'warn', | |
| openAnalyzer: false, | |
| analyzerMode: args.report ? 'static' : 'disabled', | |
| reportFilename: `${bundleName}report.html`, | |
| statsFilename: `${bundleName}report.json`, | |
| generateStatsFile: !!args['report-json'] | |
| })) | |
| }) | |
| } | |
| if (args.clean) { | |
| await fs.remove(targetDir) | |
| } | |
| return new Promise((resolve, reject) => { | |
| webpack(webpackConfig, (err, stats) => { | |
| stopSpinner(false) | |
| if (err) { | |
| return reject(err) | |
| } | |
| if (stats.hasErrors()) { | |
| return reject(`Build failed with errors.`) | |
| } | |
| if (!args.silent) { | |
| const targetDirShort = path.relative( | |
| api.service.context, | |
| targetDir | |
| ) | |
| log(formatStats(stats, targetDirShort, api)) | |
| if (args.target === 'app' && !isLegacyBuild) { | |
| if (!args.watch) { | |
| done(`Build complete. The ${chalk.cyan(targetDirShort)} directory is ready to be deployed.`) | |
| info(`Check out deployment instructions at ${chalk.cyan(`https://cli.vuejs.org/guide/deployment.html`)}\n`) | |
| } else { | |
| done(`Build complete. Watching for changes...`) | |
| } | |
| } | |
| } | |
| // test-only signal | |
| if (process.env.VUE_CLI_TEST) { | |
| console.log('Build complete.') | |
| } | |
| resolve() | |
| }) | |
| }) | |
| } | |
| module.exports.defaultModes = { | |
| build: 'production' | |
| } | |