first commit
This commit is contained in:
11
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-lib-js.html
generated
vendored
Normal file
11
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-lib-js.html
generated
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
|
||||
<% if (htmlWebpackPlugin.options.cssExtract) { %>
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
|
||||
<% } %>
|
||||
|
||||
<script>
|
||||
console.log(<%- htmlWebpackPlugin.options.libName %>)
|
||||
</script>
|
28
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-lib.html
generated
vendored
Normal file
28
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-lib.html
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="//unpkg.com/vue@<%- htmlWebpackPlugin.options.vueMajor %>"></script>
|
||||
<script src="./<%- htmlWebpackPlugin.options.assetsFileName %>.umd.js"></script>
|
||||
<% if (htmlWebpackPlugin.options.cssExtract) { %>
|
||||
<link rel="stylesheet" href="./<%- htmlWebpackPlugin.options.assetsFileName %>.css">
|
||||
<% } %>
|
||||
|
||||
<div id="app">
|
||||
<demo></demo>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
<% if (htmlWebpackPlugin.options.vueMajor === 3) { %>
|
||||
Vue.createApp({
|
||||
components: {
|
||||
demo: <%- htmlWebpackPlugin.options.libName %>
|
||||
}
|
||||
}).mount('#app')
|
||||
<% } else { %>
|
||||
new Vue({
|
||||
components: {
|
||||
demo: <%- htmlWebpackPlugin.options.libName %>
|
||||
}
|
||||
}).$mount('#app')
|
||||
<% } %>
|
||||
</script>
|
9
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-wc.html
generated
vendored
Normal file
9
app_vue/node_modules/@vue/cli-service/lib/commands/build/demo-wc.html
generated
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<title><%- htmlWebpackPlugin.options.libName %> demo</title>
|
||||
<script src="https://unpkg.com/vue@<%- htmlWebpackPlugin.options.vueMajor %>"></script>
|
||||
<script src="./<%- htmlWebpackPlugin.options.libName %>.js"></script>
|
||||
|
||||
<% for (const comp of htmlWebpackPlugin.options.components) { %>
|
||||
<<%= comp %>></<%= comp %>>
|
||||
<% } %>
|
2
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-lib-no-default.js
generated
vendored
Normal file
2
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-lib-no-default.js
generated
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
import './setPublicPath'
|
||||
export * from '~entry'
|
4
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-lib.js
generated
vendored
Normal file
4
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-lib.js
generated
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
import './setPublicPath'
|
||||
import mod from '~entry'
|
||||
export default mod
|
||||
export * from '~entry'
|
12
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-wc.js
generated
vendored
Normal file
12
app_vue/node_modules/@vue/cli-service/lib/commands/build/entry-wc.js
generated
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
import './setPublicPath'
|
||||
import Vue from 'vue'
|
||||
import wrap from '@vue/web-component-wrapper'
|
||||
|
||||
// runtime shared by every component chunk
|
||||
import 'css-loader/dist/runtime/api.js'
|
||||
import 'vue-style-loader/lib/addStylesShadow'
|
||||
import 'vue-loader/lib/runtime/componentNormalizer'
|
||||
|
||||
window.customElements.define('build-wc-async-app', wrap(Vue, () => import('~root/src/App.vue?shadow')))
|
||||
|
||||
window.customElements.define('build-wc-async-hello-world', wrap(Vue, () => import('~root/src/components/HelloWorld.vue?shadow')))
|
77
app_vue/node_modules/@vue/cli-service/lib/commands/build/formatStats.js
generated
vendored
Normal file
77
app_vue/node_modules/@vue/cli-service/lib/commands/build/formatStats.js
generated
vendored
Normal file
@ -0,0 +1,77 @@
|
||||
module.exports = function formatStats (stats, dir, api) {
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const zlib = require('zlib')
|
||||
const ui = require('cliui')({ width: process.stdout.columns || 80 })
|
||||
const { chalk } = require('@vue/cli-shared-utils')
|
||||
|
||||
const json = stats.toJson({
|
||||
hash: false,
|
||||
modules: false,
|
||||
chunks: false
|
||||
})
|
||||
|
||||
let assets = json.assets
|
||||
? json.assets
|
||||
: json.children.reduce((acc, child) => acc.concat(child.assets), [])
|
||||
|
||||
const seenNames = new Map()
|
||||
const isJS = val => /\.js$/.test(val)
|
||||
const isCSS = val => /\.css$/.test(val)
|
||||
const isMinJS = val => /\.min\.js$/.test(val)
|
||||
assets = assets
|
||||
.map(a => {
|
||||
a.name = a.name.split('?')[0]
|
||||
return a
|
||||
})
|
||||
.filter(a => {
|
||||
if (seenNames.has(a.name)) {
|
||||
return false
|
||||
}
|
||||
seenNames.set(a.name, true)
|
||||
return isJS(a.name) || isCSS(a.name)
|
||||
})
|
||||
.sort((a, b) => {
|
||||
if (isJS(a.name) && isCSS(b.name)) return -1
|
||||
if (isCSS(a.name) && isJS(b.name)) return 1
|
||||
if (isMinJS(a.name) && !isMinJS(b.name)) return -1
|
||||
if (!isMinJS(a.name) && isMinJS(b.name)) return 1
|
||||
return b.size - a.size
|
||||
})
|
||||
|
||||
function formatSize (size) {
|
||||
return (size / 1024).toFixed(2) + ' KiB'
|
||||
}
|
||||
|
||||
function getGzippedSize (asset) {
|
||||
const filepath = api.resolve(path.join(dir, asset.name))
|
||||
const buffer = fs.readFileSync(filepath)
|
||||
return formatSize(zlib.gzipSync(buffer).length)
|
||||
}
|
||||
|
||||
function makeRow (a, b, c) {
|
||||
return ` ${a}\t ${b}\t ${c}`
|
||||
}
|
||||
|
||||
ui.div(
|
||||
makeRow(
|
||||
chalk.cyan.bold(`File`),
|
||||
chalk.cyan.bold(`Size`),
|
||||
chalk.cyan.bold(`Gzipped`)
|
||||
) + `\n\n` +
|
||||
assets.map(asset => makeRow(
|
||||
/js$/.test(asset.name)
|
||||
? chalk.green(path.join(dir, asset.name))
|
||||
: chalk.blue(path.join(dir, asset.name)),
|
||||
formatSize(asset.size),
|
||||
getGzippedSize(asset)
|
||||
)).join(`\n`)
|
||||
)
|
||||
|
||||
const time = stats.endTime - stats.startTime
|
||||
const now = new Date().toISOString()
|
||||
const hash = stats.hash
|
||||
const info = `Build at: ${chalk.white(now)} - Hash: ${chalk.white(hash)} - Time: ${chalk.white(time)}ms`
|
||||
|
||||
return `${ui.toString()}\n\n ${chalk.gray(`Images and other types of assets omitted.`)}\n ${info}\n`
|
||||
}
|
238
app_vue/node_modules/@vue/cli-service/lib/commands/build/index.js
generated
vendored
Normal file
238
app_vue/node_modules/@vue/cli-service/lib/commands/build/index.js
generated
vendored
Normal file
@ -0,0 +1,238 @@
|
||||
const defaults = {
|
||||
clean: true,
|
||||
target: 'app',
|
||||
module: true,
|
||||
formats: 'commonjs,umd,umd-min'
|
||||
}
|
||||
|
||||
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})`,
|
||||
'--no-module': `build app without generating <script type="module"> chunks for modern browsers`,
|
||||
'--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 contents 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
|
||||
|
||||
const { log, execa } = require('@vue/cli-shared-utils')
|
||||
const { allProjectTargetsSupportModule } = require('../../util/targets')
|
||||
|
||||
let needsDifferentialLoading = args.target === 'app' && args.module
|
||||
if (allProjectTargetsSupportModule) {
|
||||
log(
|
||||
`All browser targets in the browserslist configuration have supported ES module.\n` +
|
||||
`Therefore we don't build two separate bundles for differential loading.\n`
|
||||
)
|
||||
needsDifferentialLoading = false
|
||||
}
|
||||
|
||||
args.needsDifferentialLoading = needsDifferentialLoading
|
||||
if (!needsDifferentialLoading) {
|
||||
await build(args, api, options)
|
||||
return
|
||||
}
|
||||
|
||||
process.env.VUE_CLI_MODERN_MODE = true
|
||||
if (!process.env.VUE_CLI_MODERN_BUILD) {
|
||||
// main-process for legacy build
|
||||
const legacyBuildArgs = { ...args, moduleBuild: false, keepAlive: true }
|
||||
await build(legacyBuildArgs, api, options)
|
||||
|
||||
// spawn sub-process of self for modern build
|
||||
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
|
||||
const moduleBuildArgs = { ...args, moduleBuild: true, clean: false }
|
||||
await build(moduleBuildArgs, api, options)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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.needsDifferentialLoading
|
||||
? args.moduleBuild
|
||||
? `module 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.needsDifferentialLoading && !args.moduleBuild
|
||||
|
||||
// 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',
|
||||
moduleBuild: args.moduleBuild,
|
||||
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.emptyDir(targetDir)
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
webpack(webpackConfig, (err, stats) => {
|
||||
stopSpinner(false)
|
||||
if (err) {
|
||||
return reject(err)
|
||||
}
|
||||
|
||||
if (stats.hasErrors()) {
|
||||
return reject(new Error('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'
|
||||
}
|
52
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveAppConfig.js
generated
vendored
Normal file
52
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveAppConfig.js
generated
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
module.exports = (api, args, options) => {
|
||||
// respect inline entry
|
||||
if (args.entry && !options.pages) {
|
||||
api.configureWebpack(config => {
|
||||
config.entry = { app: api.resolve(args.entry) }
|
||||
})
|
||||
}
|
||||
|
||||
const config = api.resolveChainableWebpackConfig()
|
||||
const targetDir = api.resolve(args.dest || options.outputDir)
|
||||
|
||||
// respect inline build destination in copy plugin
|
||||
if (args.dest && config.plugins.has('copy')) {
|
||||
config.plugin('copy').tap(pluginArgs => {
|
||||
pluginArgs[0].patterns.to = targetDir
|
||||
return pluginArgs
|
||||
})
|
||||
}
|
||||
|
||||
if (process.env.VUE_CLI_MODERN_MODE) {
|
||||
const ModernModePlugin = require('../../webpack/ModernModePlugin')
|
||||
const SafariNomoduleFixPlugin = require('../../webpack/SafariNomoduleFixPlugin')
|
||||
|
||||
if (!args.moduleBuild) {
|
||||
// Inject plugin to extract build stats and write to disk
|
||||
config
|
||||
.plugin('modern-mode-legacy')
|
||||
.use(ModernModePlugin, [{
|
||||
targetDir,
|
||||
isModuleBuild: false
|
||||
}])
|
||||
} else {
|
||||
config
|
||||
.plugin('safari-nomodule-fix')
|
||||
.use(SafariNomoduleFixPlugin, [{
|
||||
// as we may generate an addition file asset (if Safari 10 fix is needed)
|
||||
// we need to provide the correct directory for that file to place in
|
||||
jsDirectory: require('../../util/getAssetPath')(options, 'js')
|
||||
}])
|
||||
|
||||
// Inject plugin to read non-modern build stats and inject HTML
|
||||
config
|
||||
.plugin('modern-mode-modern')
|
||||
.use(ModernModePlugin, [{
|
||||
targetDir,
|
||||
isModuleBuild: true
|
||||
}])
|
||||
}
|
||||
}
|
||||
|
||||
return api.resolveWebpackConfig(config)
|
||||
}
|
159
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveLibConfig.js
generated
vendored
Normal file
159
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveLibConfig.js
generated
vendored
Normal file
@ -0,0 +1,159 @@
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
module.exports = (api, { entry, name, formats, filename, 'inline-vue': inlineVue }, options) => {
|
||||
const { log, error } = require('@vue/cli-shared-utils')
|
||||
const abort = msg => {
|
||||
log()
|
||||
error(msg)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const vueMajor = require('../../util/getVueMajor')(api.getCwd())
|
||||
|
||||
const fullEntryPath = api.resolve(entry)
|
||||
|
||||
if (!fs.existsSync(fullEntryPath)) {
|
||||
abort(
|
||||
`Failed to resolve lib entry: ${entry}${entry === `src/App.vue` ? ' (default)' : ''}. ` +
|
||||
`Make sure to specify the correct entry file.`
|
||||
)
|
||||
}
|
||||
|
||||
const isVueEntry = /\.vue$/.test(entry)
|
||||
const libName = (
|
||||
name ||
|
||||
(
|
||||
api.service.pkg.name
|
||||
? api.service.pkg.name.replace(/^@.+\//, '')
|
||||
: path.basename(entry).replace(/\.(jsx?|vue)$/, '')
|
||||
)
|
||||
)
|
||||
filename = filename || libName
|
||||
function genConfig (format, postfix = format, genHTML) {
|
||||
const config = api.resolveChainableWebpackConfig()
|
||||
|
||||
const browserslist = require('browserslist')
|
||||
const targets = browserslist(undefined, { path: fullEntryPath })
|
||||
const supportsIE = targets.some(agent => agent.includes('ie'))
|
||||
|
||||
const webpack = require('webpack')
|
||||
config.plugin('need-current-script-polyfill')
|
||||
.use(webpack.DefinePlugin, [{
|
||||
'process.env.NEED_CURRENTSCRIPT_POLYFILL': JSON.stringify(supportsIE)
|
||||
}])
|
||||
|
||||
// adjust css output name so they write to the same file
|
||||
if (config.plugins.has('extract-css')) {
|
||||
config
|
||||
.plugin('extract-css')
|
||||
.tap(args => {
|
||||
args[0].filename = `${filename}.css`
|
||||
return args
|
||||
})
|
||||
}
|
||||
|
||||
// only minify min entry
|
||||
if (!/\.min/.test(postfix)) {
|
||||
config.optimization.minimize(false)
|
||||
}
|
||||
|
||||
// inject demo page for umd
|
||||
if (genHTML) {
|
||||
const template = isVueEntry ? 'demo-lib.html' : 'demo-lib-js.html'
|
||||
config
|
||||
.plugin('demo-html')
|
||||
.use(require('html-webpack-plugin'), [{
|
||||
template: path.resolve(__dirname, template),
|
||||
inject: false,
|
||||
filename: 'demo.html',
|
||||
libName,
|
||||
vueMajor,
|
||||
assetsFileName: filename,
|
||||
cssExtract: config.plugins.has('extract-css')
|
||||
}])
|
||||
}
|
||||
|
||||
// resolve entry/output
|
||||
const entryName = `${filename}.${postfix}`
|
||||
config.resolve
|
||||
.alias
|
||||
.set('~entry', fullEntryPath)
|
||||
|
||||
// set output target before user configureWebpack hooks are applied
|
||||
config.output.libraryTarget(format)
|
||||
|
||||
// set entry/output after user configureWebpack hooks are applied
|
||||
const rawConfig = api.resolveWebpackConfig(config)
|
||||
|
||||
let realEntry = require.resolve('./entry-lib.js')
|
||||
|
||||
// avoid importing default if user entry file does not have default export
|
||||
if (!isVueEntry) {
|
||||
const entryContent = fs.readFileSync(fullEntryPath, 'utf-8')
|
||||
if (!/\b(export\s+default|export\s{[^}]+as\s+default)\b/.test(entryContent)) {
|
||||
realEntry = require.resolve('./entry-lib-no-default.js')
|
||||
}
|
||||
}
|
||||
|
||||
// externalize Vue in case user imports it
|
||||
rawConfig.externals = [
|
||||
...(Array.isArray(rawConfig.externals) ? rawConfig.externals : [rawConfig.externals]),
|
||||
{
|
||||
...(inlineVue || {
|
||||
vue: {
|
||||
commonjs: 'vue',
|
||||
commonjs2: 'vue',
|
||||
root: 'Vue'
|
||||
}
|
||||
})
|
||||
}
|
||||
].filter(Boolean)
|
||||
|
||||
rawConfig.entry = {
|
||||
[entryName]: realEntry
|
||||
}
|
||||
|
||||
rawConfig.output = Object.assign({
|
||||
library: libName,
|
||||
libraryExport: isVueEntry ? 'default' : undefined,
|
||||
libraryTarget: format,
|
||||
// preserve UDM header from webpack 3 until webpack provides either
|
||||
// libraryTarget: 'esm' or target: 'universal'
|
||||
// https://github.com/webpack/webpack/issues/6522
|
||||
// https://github.com/webpack/webpack/issues/6525
|
||||
globalObject: `(typeof self !== 'undefined' ? self : this)`
|
||||
}, rawConfig.output, {
|
||||
filename: `${entryName}.js`,
|
||||
chunkFilename: `${entryName}.[name].js`,
|
||||
// use dynamic publicPath so this can be deployed anywhere
|
||||
// the actual path will be determined at runtime by checking
|
||||
// document.currentScript.src.
|
||||
publicPath: ''
|
||||
})
|
||||
|
||||
if (format === 'commonjs2') {
|
||||
// #6188
|
||||
delete rawConfig.output.library
|
||||
}
|
||||
|
||||
return rawConfig
|
||||
}
|
||||
|
||||
const configMap = {
|
||||
commonjs: genConfig('commonjs2', 'common'),
|
||||
umd: genConfig('umd', undefined, true),
|
||||
'umd-min': genConfig('umd', 'umd.min')
|
||||
}
|
||||
|
||||
const formatArray = (formats + '').split(',')
|
||||
const configs = formatArray.map(format => configMap[format])
|
||||
if (configs.indexOf(undefined) !== -1) {
|
||||
const unknownFormats = formatArray.filter(f => configMap[f] === undefined).join(', ')
|
||||
abort(
|
||||
`Unknown library build formats: ${unknownFormats}`
|
||||
)
|
||||
}
|
||||
|
||||
return configs
|
||||
}
|
143
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveWcConfig.js
generated
vendored
Normal file
143
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveWcConfig.js
generated
vendored
Normal file
@ -0,0 +1,143 @@
|
||||
const path = require('path')
|
||||
const { resolveEntry, fileToComponentName } = require('./resolveWcEntry')
|
||||
|
||||
module.exports = (api, { target, entry, name, 'inline-vue': inlineVue }) => {
|
||||
// Disable CSS extraction and turn on CSS shadow mode for vue-style-loader
|
||||
process.env.VUE_CLI_CSS_SHADOW_MODE = true
|
||||
|
||||
const { log, error } = require('@vue/cli-shared-utils')
|
||||
const abort = msg => {
|
||||
log()
|
||||
error(msg)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
const cwd = api.getCwd()
|
||||
const webpack = require('webpack')
|
||||
const vueMajor = require('../../util/getVueMajor')(cwd)
|
||||
if (vueMajor === 3) {
|
||||
abort(`Vue 3 support of the web component target is still under development.`)
|
||||
}
|
||||
|
||||
const isAsync = /async/.test(target)
|
||||
|
||||
// generate dynamic entry based on glob files
|
||||
const resolvedFiles = require('globby').sync(entry.split(','), { cwd: api.resolve('.') })
|
||||
|
||||
if (!resolvedFiles.length) {
|
||||
abort(`entry pattern "${entry}" did not match any files.`)
|
||||
}
|
||||
let libName
|
||||
let prefix
|
||||
if (resolvedFiles.length === 1) {
|
||||
// in single mode, determine the lib name from filename
|
||||
libName = name || fileToComponentName('', resolvedFiles[0]).kebabName
|
||||
prefix = ''
|
||||
if (libName.indexOf('-') < 0) {
|
||||
abort(`--name must contain a hyphen when building a single web component.`)
|
||||
}
|
||||
} else {
|
||||
// multi mode
|
||||
libName = prefix = (name || api.service.pkg.name)
|
||||
if (!libName) {
|
||||
abort(`--name is required when building multiple web components.`)
|
||||
}
|
||||
}
|
||||
|
||||
const dynamicEntry = resolveEntry(prefix, libName, resolvedFiles, isAsync)
|
||||
|
||||
function genConfig (minify, genHTML) {
|
||||
const config = api.resolveChainableWebpackConfig()
|
||||
|
||||
// make sure not to transpile wc-wrapper
|
||||
config.module
|
||||
.rule('js')
|
||||
.exclude
|
||||
.add(/vue-wc-wrapper/)
|
||||
|
||||
// only minify min entry
|
||||
if (!minify) {
|
||||
config.optimization.minimize(false)
|
||||
}
|
||||
|
||||
config
|
||||
.plugin('webpack-virtual-modules')
|
||||
.use(require('webpack-virtual-modules'), [{
|
||||
[dynamicEntry.filePath]: dynamicEntry.content
|
||||
}])
|
||||
|
||||
config
|
||||
.plugin('web-component-options')
|
||||
.use(webpack.DefinePlugin, [{
|
||||
'process.env.CUSTOM_ELEMENT_NAME': JSON.stringify(libName)
|
||||
}])
|
||||
|
||||
// enable shadow mode in vue-loader
|
||||
config.module
|
||||
.rule('vue')
|
||||
.use('vue-loader')
|
||||
.tap(options => {
|
||||
options.shadowMode = true
|
||||
return options
|
||||
})
|
||||
|
||||
if (genHTML) {
|
||||
config
|
||||
.plugin('demo-html')
|
||||
.use(require('html-webpack-plugin'), [{
|
||||
template: path.resolve(__dirname, `./demo-wc.html`),
|
||||
inject: false,
|
||||
filename: 'demo.html',
|
||||
libName,
|
||||
vueMajor,
|
||||
components:
|
||||
prefix === ''
|
||||
? [libName]
|
||||
: resolvedFiles.map(file => {
|
||||
return fileToComponentName(prefix, file).kebabName
|
||||
})
|
||||
}])
|
||||
}
|
||||
|
||||
// set entry/output last so it takes higher priority than user
|
||||
// configureWebpack hooks
|
||||
|
||||
// set proxy entry for *.vue files
|
||||
config.resolve
|
||||
.alias
|
||||
.set('~root', api.resolve('.'))
|
||||
|
||||
const rawConfig = api.resolveWebpackConfig(config)
|
||||
|
||||
// externalize Vue in case user imports it
|
||||
rawConfig.externals = [
|
||||
...(Array.isArray(rawConfig.externals) ? rawConfig.externals : [rawConfig.externals]),
|
||||
{ ...(inlineVue || { vue: 'Vue' }) }
|
||||
].filter(Boolean)
|
||||
|
||||
const entryName = `${libName}${minify ? `.min` : ``}`
|
||||
rawConfig.entry = {
|
||||
[entryName]: dynamicEntry.filePath
|
||||
}
|
||||
|
||||
Object.assign(rawConfig.output, {
|
||||
filename: `${entryName}.js`,
|
||||
chunkFilename: `${libName}.[name]${minify ? `.min` : ``}.js`,
|
||||
// use dynamic publicPath so this can be deployed anywhere
|
||||
// the actual path will be determined at runtime by checking
|
||||
// document.currentScript.src.
|
||||
publicPath: ''
|
||||
})
|
||||
|
||||
// to ensure that multiple copies of async wc bundles can co-exist
|
||||
// on the same page.
|
||||
rawConfig.output.uniqueName = `vue-lib-${libName}`
|
||||
|
||||
return rawConfig
|
||||
}
|
||||
|
||||
return [
|
||||
genConfig(false, true),
|
||||
genConfig(true, false)
|
||||
]
|
||||
}
|
67
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveWcEntry.js
generated
vendored
Normal file
67
app_vue/node_modules/@vue/cli-service/lib/commands/build/resolveWcEntry.js
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
const path = require('path')
|
||||
|
||||
const camelizeRE = /-(\w)/g
|
||||
const camelize = str => {
|
||||
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
|
||||
}
|
||||
|
||||
const hyphenateRE = /\B([A-Z])/g
|
||||
const hyphenate = str => {
|
||||
return str.replace(hyphenateRE, '-$1').toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the script to add the component to the custom elements
|
||||
* @param {string} prefix The prefix for the component library
|
||||
* @param {string} component The component name for single entry builds, component file for multi-entry builds
|
||||
* @param {string} file The file for the component
|
||||
* @param {boolean} isAsync Whether to load component async or not
|
||||
*/
|
||||
const createElement = (prefix, component, file, isAsync) => {
|
||||
const { camelName, kebabName } = exports.fileToComponentName(prefix, component)
|
||||
|
||||
return isAsync
|
||||
? `window.customElements.define('${kebabName}', wrap(Vue, () => import('~root/${file}?shadow')))\n`
|
||||
: `import ${camelName} from '~root/${file}?shadow'\n` +
|
||||
`window.customElements.define('${kebabName}', wrap(Vue, ${camelName}))\n`
|
||||
}
|
||||
|
||||
exports.fileToComponentName = (prefix, file) => {
|
||||
const basename = path.basename(file).replace(/\.(jsx?|vue)$/, '')
|
||||
const camelName = camelize(basename)
|
||||
const kebabName = `${prefix ? `${prefix}-` : ``}${hyphenate(basename)}`
|
||||
return {
|
||||
basename,
|
||||
camelName,
|
||||
kebabName
|
||||
}
|
||||
}
|
||||
|
||||
exports.resolveEntry = (prefix, libName, files, isAsync) => {
|
||||
const filePath = path.resolve(__dirname, 'entry-wc.js')
|
||||
const elements =
|
||||
prefix === ''
|
||||
? [createElement('', libName, files[0])]
|
||||
: files.map(file => createElement(prefix, file, file, isAsync)).join('\n')
|
||||
|
||||
function resolveImportPath (mod) {
|
||||
return require.resolve(mod).replace(/\\/g, '\\\\')
|
||||
}
|
||||
|
||||
const content = `
|
||||
import './setPublicPath'
|
||||
import Vue from 'vue'
|
||||
import wrap from '@vue/web-component-wrapper'
|
||||
|
||||
// runtime shared by every component chunk
|
||||
import '${resolveImportPath('css-loader/dist/runtime/api.js')}'
|
||||
import '${resolveImportPath('vue-style-loader/lib/addStylesShadow')}'
|
||||
import '${resolveImportPath('@vue/vue-loader-v15/lib/runtime/componentNormalizer')}'
|
||||
|
||||
${elements}`.trim()
|
||||
|
||||
return {
|
||||
filePath: filePath,
|
||||
content: content
|
||||
}
|
||||
}
|
23
app_vue/node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
generated
vendored
Normal file
23
app_vue/node_modules/@vue/cli-service/lib/commands/build/setPublicPath.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/* eslint-disable no-var */
|
||||
// This file is imported into lib/wc client bundles.
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
var currentScript = window.document.currentScript
|
||||
if (process.env.NEED_CURRENTSCRIPT_POLYFILL) {
|
||||
var getCurrentScript = require('@soda/get-current-script')
|
||||
currentScript = getCurrentScript()
|
||||
|
||||
// for backward compatibility, because previously we directly included the polyfill
|
||||
if (!('currentScript' in document)) {
|
||||
Object.defineProperty(document, 'currentScript', { get: getCurrentScript })
|
||||
}
|
||||
}
|
||||
|
||||
var src = currentScript && currentScript.src.match(/(.+\/)[^/]+\.js(\?.*)?$/)
|
||||
if (src) {
|
||||
__webpack_public_path__ = src[1] // eslint-disable-line
|
||||
}
|
||||
}
|
||||
|
||||
// Indicate to webpack that this file can be concatenated
|
||||
export default null
|
62
app_vue/node_modules/@vue/cli-service/lib/commands/help.js
generated
vendored
Normal file
62
app_vue/node_modules/@vue/cli-service/lib/commands/help.js
generated
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
const { chalk } = require('@vue/cli-shared-utils')
|
||||
const getPadLength = require('../util/getPadLength')
|
||||
|
||||
module.exports = (api, options) => {
|
||||
api.registerCommand('help', args => {
|
||||
const commandName = args._[0]
|
||||
if (!commandName) {
|
||||
logMainHelp()
|
||||
} else {
|
||||
logHelpForCommand(commandName, api.service.commands[commandName])
|
||||
}
|
||||
})
|
||||
|
||||
function logMainHelp () {
|
||||
console.log(
|
||||
`\n Usage: vue-cli-service <command> [options]\n` +
|
||||
`\n Commands:\n`
|
||||
)
|
||||
const commands = api.service.commands
|
||||
const padLength = getPadLength(commands)
|
||||
for (const name in commands) {
|
||||
if (name !== 'help') {
|
||||
const opts = commands[name].opts || {}
|
||||
console.log(` ${
|
||||
chalk.blue(name.padEnd(padLength))
|
||||
}${
|
||||
opts.description || ''
|
||||
}`)
|
||||
}
|
||||
}
|
||||
console.log(`\n run ${
|
||||
chalk.green(`vue-cli-service help [command]`)
|
||||
} for usage of a specific command.\n`)
|
||||
}
|
||||
|
||||
function logHelpForCommand (name, command) {
|
||||
if (!command) {
|
||||
console.log(chalk.red(`\n command "${name}" does not exist.`))
|
||||
} else {
|
||||
const opts = command.opts || {}
|
||||
if (opts.usage) {
|
||||
console.log(`\n Usage: ${opts.usage}`)
|
||||
}
|
||||
if (opts.options) {
|
||||
console.log(`\n Options:\n`)
|
||||
const padLength = getPadLength(opts.options)
|
||||
for (const [flags, description] of Object.entries(opts.options)) {
|
||||
console.log(` ${
|
||||
chalk.blue(flags.padEnd(padLength))
|
||||
}${
|
||||
description
|
||||
}`)
|
||||
}
|
||||
}
|
||||
if (opts.details) {
|
||||
console.log()
|
||||
console.log(opts.details.split('\n').map(line => ` ${line}`).join('\n'))
|
||||
}
|
||||
console.log()
|
||||
}
|
||||
}
|
||||
}
|
74
app_vue/node_modules/@vue/cli-service/lib/commands/inspect.js
generated
vendored
Normal file
74
app_vue/node_modules/@vue/cli-service/lib/commands/inspect.js
generated
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
module.exports = (api, options) => {
|
||||
api.registerCommand(
|
||||
'inspect',
|
||||
{
|
||||
description: 'inspect internal webpack config',
|
||||
usage: 'vue-cli-service inspect [options] [...paths]',
|
||||
options: {
|
||||
'--mode': 'specify env mode (default: development)',
|
||||
'--rule <ruleName>': 'inspect a specific module rule',
|
||||
'--plugin <pluginName>': 'inspect a specific plugin',
|
||||
'--rules': 'list all module rule names',
|
||||
'--plugins': 'list all plugin names',
|
||||
'--verbose': 'show full function definitions in output',
|
||||
'--skip-plugins': 'comma-separated list of plugin names to skip for this run'
|
||||
}
|
||||
},
|
||||
args => {
|
||||
const { chalk, get } = require('@vue/cli-shared-utils')
|
||||
const { toString } = require('webpack-chain')
|
||||
const { highlight } = require('cli-highlight')
|
||||
const config = api.resolveWebpackConfig()
|
||||
const { _: paths, verbose } = args
|
||||
|
||||
let res
|
||||
let hasUnnamedRule
|
||||
if (args.rule) {
|
||||
res = config.module.rules.find(r => r.__ruleNames[0] === args.rule)
|
||||
} else if (args.plugin) {
|
||||
res = config.plugins.find(p => p.__pluginName === args.plugin)
|
||||
} else if (args.rules) {
|
||||
res = config.module.rules.map(r => {
|
||||
const name = r.__ruleNames ? r.__ruleNames[0] : 'Nameless Rule (*)'
|
||||
|
||||
hasUnnamedRule = hasUnnamedRule || !r.__ruleNames
|
||||
|
||||
return name
|
||||
})
|
||||
} else if (args.plugins) {
|
||||
res = config.plugins.map(p => p.__pluginName || p.constructor.name)
|
||||
} else if (paths.length > 1) {
|
||||
res = {}
|
||||
paths.forEach(path => {
|
||||
res[path] = get(config, path)
|
||||
})
|
||||
} else if (paths.length === 1) {
|
||||
res = get(config, paths[0])
|
||||
} else {
|
||||
res = config
|
||||
}
|
||||
|
||||
const output = toString(res, { verbose })
|
||||
console.log(highlight(output, { language: 'js' }))
|
||||
|
||||
// Log explanation for Nameless Rules
|
||||
if (hasUnnamedRule) {
|
||||
console.log(`--- ${chalk.green('Footnotes')} ---`)
|
||||
console.log(`*: ${chalk.green(
|
||||
'Nameless Rules'
|
||||
)} were added through the ${chalk.green(
|
||||
'configureWebpack()'
|
||||
)} API (possibly by a plugin) instead of ${chalk.green(
|
||||
'chainWebpack()'
|
||||
)} (recommended).
|
||||
You can run ${chalk.green(
|
||||
'vue-cli-service inspect'
|
||||
)} without any arguments to inspect the full config and read these rules' config.`)
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
module.exports.defaultModes = {
|
||||
inspect: 'development'
|
||||
}
|
397
app_vue/node_modules/@vue/cli-service/lib/commands/serve.js
generated
vendored
Normal file
397
app_vue/node_modules/@vue/cli-service/lib/commands/serve.js
generated
vendored
Normal file
@ -0,0 +1,397 @@
|
||||
const {
|
||||
info,
|
||||
error,
|
||||
hasProjectYarn,
|
||||
hasProjectPnpm,
|
||||
IpcMessenger
|
||||
} = require('@vue/cli-shared-utils')
|
||||
const getBaseUrl = require('../util/getBaseUrl')
|
||||
|
||||
const defaults = {
|
||||
host: '0.0.0.0',
|
||||
port: 8080,
|
||||
https: false
|
||||
}
|
||||
|
||||
/** @type {import('@vue/cli-service').ServicePlugin} */
|
||||
module.exports = (api, options) => {
|
||||
const baseUrl = getBaseUrl(options)
|
||||
api.registerCommand('serve', {
|
||||
description: 'start development server',
|
||||
usage: 'vue-cli-service serve [options] [entry]',
|
||||
options: {
|
||||
'--open': `open browser on server start`,
|
||||
'--copy': `copy url to clipboard on server start`,
|
||||
'--stdin': `close when stdin ends`,
|
||||
'--mode': `specify env mode (default: development)`,
|
||||
'--host': `specify host (default: ${defaults.host})`,
|
||||
'--port': `specify port (default: ${defaults.port})`,
|
||||
'--https': `use https (default: ${defaults.https})`,
|
||||
'--public': `specify the public network URL for the HMR client`,
|
||||
'--skip-plugins': `comma-separated list of plugin names to skip for this run`
|
||||
}
|
||||
}, async function serve (args) {
|
||||
info('Starting development server...')
|
||||
|
||||
// although this is primarily a dev server, it is possible that we
|
||||
// are running it in a mode with a production env, e.g. in E2E tests.
|
||||
const isInContainer = checkInContainer()
|
||||
const isProduction = process.env.NODE_ENV === 'production'
|
||||
|
||||
const { chalk } = require('@vue/cli-shared-utils')
|
||||
const webpack = require('webpack')
|
||||
const WebpackDevServer = require('webpack-dev-server')
|
||||
const portfinder = require('portfinder')
|
||||
const prepareURLs = require('../util/prepareURLs')
|
||||
const prepareProxy = require('../util/prepareProxy')
|
||||
const launchEditorMiddleware = require('launch-editor-middleware')
|
||||
const validateWebpackConfig = require('../util/validateWebpackConfig')
|
||||
const isAbsoluteUrl = require('../util/isAbsoluteUrl')
|
||||
|
||||
// configs that only matters for dev server
|
||||
api.chainWebpack(webpackConfig => {
|
||||
if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
|
||||
if (!webpackConfig.get('devtool')) {
|
||||
webpackConfig
|
||||
.devtool('eval-cheap-module-source-map')
|
||||
}
|
||||
|
||||
// https://github.com/webpack/webpack/issues/6642
|
||||
// https://github.com/vuejs/vue-cli/issues/3539
|
||||
webpackConfig
|
||||
.output
|
||||
.globalObject(`(typeof self !== 'undefined' ? self : this)`)
|
||||
|
||||
if (
|
||||
!process.env.VUE_CLI_TEST &&
|
||||
(!options.devServer.client ||
|
||||
options.devServer.client.progress !== false)
|
||||
) {
|
||||
// the default progress plugin won't show progress due to infrastructreLogging.level
|
||||
webpackConfig
|
||||
.plugin('progress')
|
||||
.use(require('progress-webpack-plugin'))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// resolve webpack config
|
||||
const webpackConfig = api.resolveWebpackConfig()
|
||||
|
||||
// check for common config errors
|
||||
validateWebpackConfig(webpackConfig, api, options)
|
||||
|
||||
// load user devServer options with higher priority than devServer
|
||||
// in webpack config
|
||||
const projectDevServerOptions = Object.assign(
|
||||
webpackConfig.devServer || {},
|
||||
options.devServer
|
||||
)
|
||||
|
||||
// expose advanced stats
|
||||
if (args.dashboard) {
|
||||
const DashboardPlugin = require('../webpack/DashboardPlugin')
|
||||
webpackConfig.plugins.push(new DashboardPlugin({
|
||||
type: 'serve'
|
||||
}))
|
||||
}
|
||||
|
||||
// entry arg
|
||||
const entry = args._[0]
|
||||
if (entry) {
|
||||
webpackConfig.entry = {
|
||||
app: api.resolve(entry)
|
||||
}
|
||||
}
|
||||
|
||||
// resolve server options
|
||||
const modesUseHttps = ['https', 'http2']
|
||||
const serversUseHttps = ['https', 'spdy']
|
||||
const optionsUseHttps = modesUseHttps.some(modeName => !!projectDevServerOptions[modeName]) ||
|
||||
(typeof projectDevServerOptions.server === 'string' && serversUseHttps.includes(projectDevServerOptions.server)) ||
|
||||
(typeof projectDevServerOptions.server === 'object' && projectDevServerOptions.server !== null && serversUseHttps.includes(projectDevServerOptions.server.type))
|
||||
const useHttps = args.https || optionsUseHttps || defaults.https
|
||||
const protocol = useHttps ? 'https' : 'http'
|
||||
const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
|
||||
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults.port
|
||||
const port = await portfinder.getPortPromise()
|
||||
const rawPublicUrl = args.public || projectDevServerOptions.public
|
||||
const publicUrl = rawPublicUrl
|
||||
? /^[a-zA-Z]+:\/\//.test(rawPublicUrl)
|
||||
? rawPublicUrl
|
||||
: `${protocol}://${rawPublicUrl}`
|
||||
: null
|
||||
const publicHost = publicUrl ? /^[a-zA-Z]+:\/\/([^/?#]+)/.exec(publicUrl)[1] : undefined
|
||||
|
||||
const urls = prepareURLs(
|
||||
protocol,
|
||||
host,
|
||||
port,
|
||||
isAbsoluteUrl(baseUrl) ? '/' : baseUrl
|
||||
)
|
||||
const localUrlForBrowser = publicUrl || urls.localUrlForBrowser
|
||||
|
||||
const proxySettings = prepareProxy(
|
||||
projectDevServerOptions.proxy,
|
||||
api.resolve('public')
|
||||
)
|
||||
|
||||
// inject dev & hot-reload middleware entries
|
||||
let webSocketURL
|
||||
if (!isProduction) {
|
||||
if (publicHost) {
|
||||
// explicitly configured via devServer.public
|
||||
webSocketURL = {
|
||||
protocol: protocol === 'https' ? 'wss' : 'ws',
|
||||
hostname: publicHost,
|
||||
port
|
||||
}
|
||||
} else if (isInContainer) {
|
||||
// can't infer public network url if inside a container
|
||||
// infer it from the browser instead
|
||||
webSocketURL = 'auto://0.0.0.0:0/ws'
|
||||
} else {
|
||||
// otherwise infer the url from the config
|
||||
webSocketURL = {
|
||||
protocol: protocol === 'https' ? 'wss' : 'ws',
|
||||
hostname: urls.lanUrlForConfig || 'localhost',
|
||||
port
|
||||
}
|
||||
}
|
||||
|
||||
if (process.env.APPVEYOR) {
|
||||
webpackConfig.plugins.push(
|
||||
new webpack.EntryPlugin(__dirname, 'webpack/hot/poll?500', { name: undefined })
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const { projectTargets } = require('../util/targets')
|
||||
const supportsIE = !!projectTargets
|
||||
if (supportsIE) {
|
||||
webpackConfig.plugins.push(
|
||||
// must use undefined as name,
|
||||
// to avoid dev server establishing an extra ws connection for the new entry
|
||||
new webpack.EntryPlugin(__dirname, 'whatwg-fetch', { name: undefined })
|
||||
)
|
||||
}
|
||||
|
||||
// fixme: temporary fix to suppress dev server logging
|
||||
// should be more robust to show necessary info but not duplicate errors
|
||||
webpackConfig.infrastructureLogging = { ...webpackConfig.infrastructureLogging, level: 'none' }
|
||||
webpackConfig.stats = 'errors-only'
|
||||
|
||||
// create compiler
|
||||
const compiler = webpack(webpackConfig)
|
||||
|
||||
// handle compiler error
|
||||
compiler.hooks.failed.tap('vue-cli-service serve', msg => {
|
||||
error(msg)
|
||||
process.exit(1)
|
||||
})
|
||||
|
||||
// create server
|
||||
const server = new WebpackDevServer(Object.assign({
|
||||
historyApiFallback: {
|
||||
disableDotRule: true,
|
||||
htmlAcceptHeaders: [
|
||||
'text/html',
|
||||
'application/xhtml+xml'
|
||||
],
|
||||
rewrites: genHistoryApiFallbackRewrites(baseUrl, options.pages)
|
||||
},
|
||||
hot: !isProduction
|
||||
}, projectDevServerOptions, {
|
||||
host,
|
||||
port,
|
||||
|
||||
server: {
|
||||
type: protocol,
|
||||
...(typeof projectDevServerOptions.server === 'object'
|
||||
? projectDevServerOptions.server
|
||||
: {})
|
||||
},
|
||||
|
||||
proxy: proxySettings,
|
||||
|
||||
static: {
|
||||
directory: api.resolve('public'),
|
||||
publicPath: options.publicPath,
|
||||
watch: !isProduction,
|
||||
|
||||
...projectDevServerOptions.static
|
||||
},
|
||||
|
||||
client: {
|
||||
webSocketURL,
|
||||
|
||||
logging: 'none',
|
||||
overlay: isProduction // TODO disable this
|
||||
? false
|
||||
: { warnings: false, errors: true },
|
||||
progress: !process.env.VUE_CLI_TEST,
|
||||
|
||||
...projectDevServerOptions.client
|
||||
},
|
||||
|
||||
open: args.open || projectDevServerOptions.open,
|
||||
setupExitSignals: true,
|
||||
|
||||
setupMiddlewares (middlewares, devServer) {
|
||||
// launch editor support.
|
||||
// this works with vue-devtools & @vue/cli-overlay
|
||||
devServer.app.use('/__open-in-editor', launchEditorMiddleware(() => console.log(
|
||||
`To specify an editor, specify the EDITOR env variable or ` +
|
||||
`add "editor" field to your Vue project config.\n`
|
||||
)))
|
||||
|
||||
// allow other plugins to register middlewares, e.g. PWA
|
||||
// todo: migrate to the new API interface
|
||||
api.service.devServerConfigFns.forEach(fn => fn(devServer.app, devServer))
|
||||
|
||||
if (projectDevServerOptions.setupMiddlewares) {
|
||||
return projectDevServerOptions.setupMiddlewares(middlewares, devServer)
|
||||
}
|
||||
|
||||
return middlewares
|
||||
}
|
||||
}), compiler)
|
||||
|
||||
if (args.stdin) {
|
||||
process.stdin.on('end', () => {
|
||||
server.stopCallback(() => {
|
||||
process.exit(0)
|
||||
})
|
||||
})
|
||||
|
||||
process.stdin.resume()
|
||||
}
|
||||
|
||||
// on appveyor, killing the process with SIGTERM causes execa to
|
||||
// throw error
|
||||
if (process.env.VUE_CLI_TEST) {
|
||||
process.stdin.on('data', data => {
|
||||
if (data.toString() === 'close') {
|
||||
console.log('got close signal!')
|
||||
server.stopCallback(() => {
|
||||
process.exit(0)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
// log instructions & open browser on first compilation complete
|
||||
let isFirstCompile = true
|
||||
compiler.hooks.done.tap('vue-cli-service serve', stats => {
|
||||
if (stats.hasErrors()) {
|
||||
return
|
||||
}
|
||||
|
||||
let copied = ''
|
||||
if (isFirstCompile && args.copy) {
|
||||
try {
|
||||
require('clipboardy').writeSync(localUrlForBrowser)
|
||||
copied = chalk.dim('(copied to clipboard)')
|
||||
} catch (_) {
|
||||
/* catch exception if copy to clipboard isn't supported (e.g. WSL), see issue #3476 */
|
||||
}
|
||||
}
|
||||
|
||||
const networkUrl = publicUrl
|
||||
? publicUrl.replace(/([^/])$/, '$1/')
|
||||
: urls.lanUrlForTerminal
|
||||
|
||||
console.log()
|
||||
console.log(` App running at:`)
|
||||
console.log(` - Local: ${chalk.cyan(urls.localUrlForTerminal)} ${copied}`)
|
||||
if (!isInContainer) {
|
||||
console.log(` - Network: ${chalk.cyan(networkUrl)}`)
|
||||
} else {
|
||||
console.log()
|
||||
console.log(chalk.yellow(` It seems you are running Vue CLI inside a container.`))
|
||||
if (!publicUrl && options.publicPath && options.publicPath !== '/') {
|
||||
console.log()
|
||||
console.log(chalk.yellow(` Since you are using a non-root publicPath, the hot-reload socket`))
|
||||
console.log(chalk.yellow(` will not be able to infer the correct URL to connect. You should`))
|
||||
console.log(chalk.yellow(` explicitly specify the URL via ${chalk.blue(`devServer.public`)}.`))
|
||||
console.log()
|
||||
}
|
||||
console.log(chalk.yellow(` Access the dev server via ${chalk.cyan(
|
||||
`${protocol}://localhost:<your container's external mapped port>${options.publicPath}`
|
||||
)}`))
|
||||
}
|
||||
console.log()
|
||||
|
||||
if (isFirstCompile) {
|
||||
isFirstCompile = false
|
||||
|
||||
if (!isProduction) {
|
||||
const buildCommand = hasProjectYarn(api.getCwd()) ? `yarn build` : hasProjectPnpm(api.getCwd()) ? `pnpm run build` : `npm run build`
|
||||
console.log(` Note that the development build is not optimized.`)
|
||||
console.log(` To create a production build, run ${chalk.cyan(buildCommand)}.`)
|
||||
} else {
|
||||
console.log(` App is served in production mode.`)
|
||||
console.log(` Note this is for preview or E2E testing only.`)
|
||||
}
|
||||
console.log()
|
||||
|
||||
// Send final app URL
|
||||
if (args.dashboard) {
|
||||
const ipc = new IpcMessenger()
|
||||
ipc.send({
|
||||
vueServe: {
|
||||
url: localUrlForBrowser
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// resolve returned Promise
|
||||
// so other commands can do api.service.run('serve').then(...)
|
||||
resolve({
|
||||
server,
|
||||
url: localUrlForBrowser
|
||||
})
|
||||
} else if (process.env.VUE_CLI_TEST) {
|
||||
// signal for test to check HMR
|
||||
console.log('App updated')
|
||||
}
|
||||
})
|
||||
|
||||
server.start().catch(err => reject(err))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// https://stackoverflow.com/a/20012536
|
||||
function checkInContainer () {
|
||||
if ('CODESANDBOX_SSE' in process.env) {
|
||||
return true
|
||||
}
|
||||
const fs = require('fs')
|
||||
if (fs.existsSync(`/proc/1/cgroup`)) {
|
||||
const content = fs.readFileSync(`/proc/1/cgroup`, 'utf-8')
|
||||
return /:\/(lxc|docker|kubepods(\.slice)?)\//.test(content)
|
||||
}
|
||||
}
|
||||
|
||||
function genHistoryApiFallbackRewrites (baseUrl, pages = {}) {
|
||||
const path = require('path')
|
||||
const multiPageRewrites = Object
|
||||
.keys(pages)
|
||||
// sort by length in reversed order to avoid overrides
|
||||
// eg. 'page11' should appear in front of 'page1'
|
||||
.sort((a, b) => b.length - a.length)
|
||||
.map(name => ({
|
||||
from: new RegExp(`^/${name}`),
|
||||
to: path.posix.join(baseUrl, pages[name].filename || `${name}.html`)
|
||||
}))
|
||||
return [
|
||||
...multiPageRewrites,
|
||||
{ from: /./, to: path.posix.join(baseUrl, 'index.html') }
|
||||
]
|
||||
}
|
||||
|
||||
module.exports.defaultModes = {
|
||||
serve: 'development'
|
||||
}
|
Reference in New Issue
Block a user