publicPath + serve production mode

This commit is contained in:
Evan You
2018-01-01 16:57:00 -05:00
parent 153785d066
commit d048b939ab
10 changed files with 184 additions and 241 deletions
+2 -3
View File
@@ -2,15 +2,14 @@ module.exports = (generatorAPI, options) => {
generatorAPI.render('./template')
generatorAPI.extendPackage({
scripts: {
'dev': 'vue-cli-service dev' + (
'serve': 'vue-cli-service serve' + (
// only auto open browser on MacOS where applescript
// can avoid dupilcate window opens
process.platform === 'darwin'
? ' --open'
: ''
),
'build': 'vue-cli-service build',
'start': 'vue-cli-service serve'
'build': 'vue-cli-service build'
},
dependencies: {
'vue': '^2.5.13'
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

@@ -3,6 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="shortcut icon" href="<%%= webpackConfig.output.publicPath %%>favicon.ico">
<title><%= options.projectName %></title>
</head>
<body>
+24 -6
View File
@@ -78,9 +78,8 @@ module.exports = class Service {
resolvePlugins () {
const builtInPlugins = [
'./commands/dev',
'./commands/build',
'./commands/serve',
'./commands/build',
'./commands/inspect',
'./commands/help',
// config plugins are order sensitive
@@ -135,7 +134,7 @@ module.exports = class Service {
loadProjectConfig () {
// vue.config.js
let fileConfig, pkgConfig
let fileConfig, pkgConfig, resolved
const configPath = path.resolve(this.context, 'vue.config.js')
if (fs.existsSync(configPath)) {
fileConfig = require(configPath)
@@ -165,12 +164,31 @@ module.exports = class Service {
)
}
info(`Using project config in ${chalk.bold('vue.config.js')}.`)
return fileConfig
resolved = fileConfig
} else if (pkgConfig) {
info(`Using project config from "vue" field in ${chalk.bold(`package.json`)}.`)
return pkgConfig
resolved = pkgConfig
} else {
return {}
resolved = {}
}
// normlaize some options
ensureSlash(resolved, 'base')
removeSlash(resolved, 'outputDir')
removeSlash(resolved, 'staticDir')
}
}
function ensureSlash (config, key) {
if (typeof config[key] === 'string') {
config[key] = config[key]
.replace(/^([^/])/, '/$1')
.replace(/([^/])$/, '$1/')
}
}
function removeSlash (config, key) {
if (typeof config[key] === 'string') {
config[key] = config[key].replace(/^\/|\/$/g, '')
}
}
@@ -22,7 +22,6 @@ module.exports = (api, options) => {
const {
done,
info,
hasYarn,
logWithSpinner,
stopSpinner
} = require('@vue/cli-shared-utils')
@@ -60,13 +59,12 @@ module.exports = (api, options) => {
if (!args.silent) {
done(`Build complete. The ${chalk.cyan(options.outputDir)} directory is ready to be deployed.\n`)
const previewCommand = chalk.cyan(`${hasYarn ? 'yarn' : 'npm'} start`)
info(`You can preview the production app by running ${previewCommand}.\n`)
if (options.base === '/') {
info(`The app is built assuming that it will be deployed at the root of a domain.`)
info(`If you intend to deploy it under a subpath, update the ${chalk.green('base')} option`)
info(`in your project config (${chalk.cyan(`vue.config.js`)} or ${chalk.green('"vue"')} field in ${chalk.cyan(`package.json`)}).\n`)
}
// TODO info(`You can view more deployment tips at ???`)
}
resolve()
@@ -1,152 +0,0 @@
const {
info,
error,
hasYarn,
clearConsole
} = require('@vue/cli-shared-utils')
const defaults = {
mode: 'development',
host: '0.0.0.0',
port: 8080,
https: false
}
module.exports = (api, options) => {
api.registerCommand('dev', {
description: 'start development server',
usage: 'vue-cli-service dev [options]',
options: {
'--open': `open browser on server start`,
'--mode': `specify env mode (default: ${defaults.mode})`,
'--host': `specify host (default: ${defaults.host})`,
'--port': `specify port (default: ${defaults.port})`,
'--https': `use https (default: ${defaults.https})`
}
}, args => {
clearConsole()
info('Starting development server...')
api.setMode(args.mode || defaults.mode)
const chalk = require('chalk')
const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
const portfinder = require('portfinder')
const openBrowser = require('../util/openBrowser')
const prepareURLs = require('../util/prepareURLs')
const prepareProxy = require('../util/prepareProxy')
const overlayMiddleware = require('@vue/cli-overlay/middleware')
const projectDevServerOptions = options.devServer || {}
const useHttps = args.https || projectDevServerOptions.https || defaults.https
const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults.port
portfinder.getPort((err, port) => {
if (err) {
return error(err)
}
const webpackConfig = api.resolveWebpackConfig()
const urls = prepareURLs(
useHttps ? 'https' : 'http',
host,
port
)
// inject dev/hot client
addDevClientToEntry(webpackConfig, [
// dev server client
`webpack-dev-server/client/?${urls.localUrlForBrowser}`,
// hmr client
projectDevServerOptions.hotOnly
? 'webpack/hot/dev-server'
: 'webpack/hot/only-dev-server'
// TODO custom overlay client
// `@vue/cli-overlay/dist/client`
])
const compiler = webpack(webpackConfig)
// log instructions & open browser on first compilation complete
let isFirstCompile = true
compiler.plugin('done', stats => {
if (stats.hasErrors()) {
return
}
console.log([
` App running at:`,
` - Local: ${chalk.cyan(urls.localUrlForTerminal)}`,
` - Network: ${chalk.cyan(urls.lanUrlForTerminal)}`
].join('\n'))
console.log()
if (isFirstCompile) {
isFirstCompile = false
const buildCommand = hasYarn ? `yarn build` : `npm run build`
console.log([
` Note that the development build is not optimized.`,
` To create a production build, run ${chalk.cyan(buildCommand)}.`
].join('\n'))
console.log()
if (args.open || projectDevServerOptions.open) {
openBrowser(urls.localUrlForBrowser)
}
}
})
const proxySettings = prepareProxy(
projectDevServerOptions.proxy,
api.resolve('public')
)
const server = new WebpackDevServer(compiler, Object.assign({
clientLogLevel: 'none',
historyApiFallback: {
disableDotRule: true
},
contentBase: api.resolve('public'),
watchContentBase: true,
hot: true,
quiet: true,
compress: true,
publicPath: webpackConfig.output.publicPath,
overlay: { warnings: false, errors: true } // TODO disable this
}, projectDevServerOptions, {
https: useHttps,
proxy: proxySettings,
before (app) {
// overlay
app.use(overlayMiddleware())
// allow other plugins to register middlewares, e.g. PWA
api.service.devServerConfigFns.forEach(fn => fn(app))
// apply in project middlewares
projectDevServerOptions.before && projectDevServerOptions.before(app)
}
}))
server.listen(port, host, err => {
if (err) {
return error(err)
}
})
})
})
}
function addDevClientToEntry (config, devClient) {
const { entry } = config
if (typeof entry === 'object' && !Array.isArray(entry)) {
Object.keys(entry).forEach((key) => {
entry[key] = devClient.concat(entry[key])
})
} else if (typeof entry === 'function') {
config.entry = entry(devClient)
} else {
config.entry = devClient.concat(entry)
}
}
+154 -54
View File
@@ -1,66 +1,166 @@
const chalk = require('chalk')
const {
info,
error,
hasYarn,
clearConsole
} = require('@vue/cli-shared-utils')
const defaults = {
mode: 'development',
host: '0.0.0.0',
port: 8080,
https: false
}
module.exports = (api, options) => {
api.registerCommand('serve', {
description: `start static server in ${chalk.cyan(options.outputDir)}`,
usage: 'vue-cli-service serve [options]',
description: 'start development server',
usage: 'vue-cli-service dev [options]',
options: {
'--mode': 'specify env mode for build (default: production)',
'--https': 'use HTTPS? (default: false)'
},
details: `For additional options, see ${
chalk.cyan(`https://github.com/zeit/serve/blob/master/lib/options.js`)
}`
}, args => {
const mode = args.mode || 'production'
api.setMode(mode)
const fs = require('fs')
const serve = require('serve')
const chalk = require('chalk')
const portfinder = require('portfinder')
const prepareURLs = require('../util/prepareURLs')
const { info, hasYarn } = require('@vue/cli-shared-utils')
let buildPromise
const outputDir = api.resolve(options.outputDir)
if (!fs.existsSync(outputDir)) {
info(
`Build directory does not exist. ` +
`Running ${chalk.cyan(hasYarn ? 'yarn build' : 'npm run build')} first.`
)
buildPromise = api.service.run('build', {
mode,
silent: true
})
} else {
buildPromise = Promise.resolve()
'--open': `open browser on server start`,
'--mode': `specify env mode (default: ${defaults.mode})`,
'--host': `specify host (default: ${defaults.host})`,
'--port': `specify port (default: ${defaults.port})`,
'--https': `use https (default: ${defaults.https})`
}
}, args => {
clearConsole()
info('Starting development server...')
buildPromise.then(() => {
portfinder.basePort = args.port || 3000
return portfinder.getPortPromise()
}).then(port => {
const serveOptions = Object.assign({}, args, {
port,
ssl: args.https,
silent: true,
single: true,
treeless: true
api.setMode(args.mode || defaults.mode)
// 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 isProduction = process.env.NODE_ENV === 'production'
const chalk = require('chalk')
const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
const portfinder = require('portfinder')
const openBrowser = require('../util/openBrowser')
const prepareURLs = require('../util/prepareURLs')
const prepareProxy = require('../util/prepareProxy')
const overlayMiddleware = require('@vue/cli-overlay/middleware')
const projectDevServerOptions = options.devServer || {}
const useHttps = args.https || projectDevServerOptions.https || defaults.https
const host = args.host || process.env.HOST || projectDevServerOptions.host || defaults.host
portfinder.basePort = args.port || process.env.PORT || projectDevServerOptions.port || defaults.port
portfinder.getPort((err, port) => {
if (err) {
return error(err)
}
const webpackConfig = api.resolveWebpackConfig()
const urls = prepareURLs(
useHttps ? 'https' : 'http',
host,
port
)
if (!isProduction) {
// inject dev/hot client
addDevClientToEntry(webpackConfig, [
// dev server client
`webpack-dev-server/client/?${urls.localUrlForBrowser}`,
// hmr client
projectDevServerOptions.hotOnly
? 'webpack/hot/dev-server'
: 'webpack/hot/only-dev-server'
// TODO custom overlay client
// `@vue/cli-overlay/dist/client`
])
}
const compiler = webpack(webpackConfig)
// log instructions & open browser on first compilation complete
let isFirstCompile = true
compiler.plugin('done', stats => {
if (stats.hasErrors()) {
return
}
console.log()
console.log([
` App running at:`,
` - Local: ${chalk.cyan(urls.localUrlForTerminal)}`,
` - Network: ${chalk.cyan(urls.lanUrlForTerminal)}`
].join('\n'))
console.log()
if (isFirstCompile) {
isFirstCompile = false
if (!isProduction) {
const buildCommand = hasYarn ? `yarn 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.`)
// TODO console.log(` See URL for more deployment tips.`)
}
console.log()
if (args.open || projectDevServerOptions.open) {
openBrowser(urls.localUrlForBrowser)
}
}
})
delete serveOptions.mode
delete serveOptions.https
serve(outputDir, serveOptions)
const proxySettings = prepareProxy(
projectDevServerOptions.proxy,
api.resolve('public')
)
const urls = prepareURLs(args.https ? 'https' : 'http', '::', port)
console.log()
console.log([
` Serving static app in ${chalk.yellow(mode)} mode at:\n`,
` - Local: ${chalk.cyan(urls.localUrlForTerminal)}`,
` - Network: ${chalk.cyan(urls.lanUrlForTerminal)}`
].join('\n'))
console.log()
const server = new WebpackDevServer(compiler, Object.assign({
clientLogLevel: 'none',
historyApiFallback: {
disableDotRule: true
},
contentBase: api.resolve('public'),
watchContentBase: !isProduction,
hot: !isProduction,
quiet: true,
compress: true,
publicPath: '/',
overlay: isProduction // TODO disable this
? false
: { warnings: false, errors: true }
}, projectDevServerOptions, {
https: useHttps,
proxy: proxySettings,
before (app) {
// overlay
app.use(overlayMiddleware())
// allow other plugins to register middlewares, e.g. PWA
api.service.devServerConfigFns.forEach(fn => fn(app))
// apply in project middlewares
projectDevServerOptions.before && projectDevServerOptions.before(app)
}
}))
server.listen(port, host, err => {
if (err) {
return error(err)
}
})
})
})
}
function addDevClientToEntry (config, devClient) {
const { entry } = config
if (typeof entry === 'object' && !Array.isArray(entry)) {
Object.keys(entry).forEach((key) => {
entry[key] = devClient.concat(entry[key])
})
} else if (typeof entry === 'function') {
config.entry = entry(devClient)
} else {
config.entry = devClient.concat(entry)
}
}
@@ -98,7 +98,6 @@ module.exports = (api, options) => {
child_process: 'empty'
})
// TODO handle publicPath in template
webpackConfig
.plugin('html')
.use(require('html-webpack-plugin'), [{
@@ -3,6 +3,8 @@ module.exports = api => {
if (process.env.NODE_ENV === 'development') {
webpackConfig
.devtool('cheap-module-eval-source-map')
.output
.publicPath('/')
webpackConfig
.plugin('hmr')
-22
View File
@@ -3364,13 +3364,6 @@ eslint-plugin-vue-libs@^2.1.0:
dependencies:
eslint-plugin-html "^4.0.1"
eslint-plugin-vue@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-vue/-/eslint-plugin-vue-4.0.0.tgz#b93f2b21c32d4b88794962a56ce662621b268acd"
dependencies:
require-all "^2.2.0"
vue-eslint-parser "^2.0.1"
eslint-restricted-globals@^0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7"
@@ -7499,10 +7492,6 @@ request@^2.67.0, request@^2.83.0:
tunnel-agent "^0.6.0"
uuid "^3.1.0"
require-all@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/require-all/-/require-all-2.2.0.tgz#b4420c233ac0282d0ff49b277fb880a8b5de0894"
require-directory@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
@@ -8755,17 +8744,6 @@ vue-cli@^2.9.2:
user-home "^2.0.0"
validate-npm-package-name "^3.0.0"
vue-eslint-parser@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-2.0.1.tgz#30135771c4fad00fdbac4542a2d59f3b1d776834"
dependencies:
debug "^3.1.0"
eslint-scope "^3.7.1"
eslint-visitor-keys "^1.0.0"
espree "^3.5.2"
esquery "^1.0.0"
lodash "^4.17.4"
vue-hot-reload-api@^2.2.0:
version "2.2.4"
resolved "https://registry.yarnpkg.com/vue-hot-reload-api/-/vue-hot-reload-api-2.2.4.tgz#683bd1d026c0d3b3c937d5875679e9a87ec6cd8f"