You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							238 lines
						
					
					
						
							7.3 KiB
						
					
					
				
			
		
		
	
	
							238 lines
						
					
					
						
							7.3 KiB
						
					
					
				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' | 
						|
}
 | 
						|
 |