| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374 | 
							- const {
 
-   info,
 
-   error,
 
-   hasProjectYarn,
 
-   hasProjectPnpm,
 
-   openBrowser,
 
-   IpcMessenger
 
- } = require('@vue/cli-shared-utils')
 
- const defaults = {
 
-   host: '0.0.0.0',
 
-   port: 8080,
 
-   https: false
 
- }
 
- module.exports = (api, 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 url = require('url')
 
-     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') {
 
-         webpackConfig
 
-           .devtool('cheap-module-eval-source-map')
 
-         webpackConfig
 
-           .plugin('hmr')
 
-             .use(require('webpack/lib/HotModuleReplacementPlugin'))
 
-         // 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.progress !== false) {
 
-           webpackConfig
 
-             .plugin('progress')
 
-             .use(require('webpack/lib/ProgressPlugin'))
 
-         }
 
-       }
 
-     })
 
-     // 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 = 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 useHttps = args.https || projectDevServerOptions.https || 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 urls = prepareURLs(
 
-       protocol,
 
-       host,
 
-       port,
 
-       isAbsoluteUrl(options.publicPath) ? '/' : options.publicPath
 
-     )
 
-     const localUrlForBrowser = publicUrl || urls.localUrlForBrowser
 
-     const proxySettings = prepareProxy(
 
-       projectDevServerOptions.proxy,
 
-       api.resolve('public')
 
-     )
 
-     // inject dev & hot-reload middleware entries
 
-     if (!isProduction) {
 
-       const sockPath = projectDevServerOptions.sockPath || '/sockjs-node'
 
-       const sockjsUrl = publicUrl
 
-         // explicitly configured via devServer.public
 
-         ? `?${publicUrl}&sockPath=${sockPath}`
 
-         : isInContainer
 
-           // can't infer public network url if inside a container...
 
-           // use client-side inference (note this would break with non-root publicPath)
 
-           ? ``
 
-           // otherwise infer the url
 
-           : `?` + url.format({
 
-             protocol,
 
-             port,
 
-             hostname: urls.lanUrlForConfig || 'localhost'
 
-           }) + `&sockPath=${sockPath}`
 
-       const devClients = [
 
-         // dev server client
 
-         require.resolve(`webpack-dev-server/client`) + sockjsUrl,
 
-         // hmr client
 
-         require.resolve(projectDevServerOptions.hotOnly
 
-           ? 'webpack/hot/only-dev-server'
 
-           : 'webpack/hot/dev-server')
 
-         // TODO custom overlay client
 
-         // `@vue/cli-overlay/dist/client`
 
-       ]
 
-       if (process.env.APPVEYOR) {
 
-         devClients.push(`webpack/hot/poll?500`)
 
-       }
 
-       // inject dev/hot client
 
-       addDevClientToEntry(webpackConfig, devClients)
 
-     }
 
-     // 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(compiler, Object.assign({
 
-       logLevel: 'silent',
 
-       clientLogLevel: 'silent',
 
-       historyApiFallback: {
 
-         disableDotRule: true,
 
-         rewrites: genHistoryApiFallbackRewrites(options.publicPath, options.pages)
 
-       },
 
-       contentBase: api.resolve('public'),
 
-       watchContentBase: !isProduction,
 
-       hot: !isProduction,
 
-       injectClient: false,
 
-       compress: isProduction,
 
-       publicPath: options.publicPath,
 
-       overlay: isProduction // TODO disable this
 
-         ? false
 
-         : { warnings: false, errors: true }
 
-     }, projectDevServerOptions, {
 
-       https: useHttps,
 
-       proxy: proxySettings,
 
-       // eslint-disable-next-line no-shadow
 
-       before (app, server) {
 
-         // launch editor support.
 
-         // this works with vue-devtools & @vue/cli-overlay
 
-         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
 
-         api.service.devServerConfigFns.forEach(fn => fn(app, server))
 
-         // apply in project middlewares
 
-         projectDevServerOptions.before && projectDevServerOptions.before(app, server)
 
-       },
 
-       // avoid opening browser
 
-       open: false
 
-     }))
 
-     ;['SIGINT', 'SIGTERM'].forEach(signal => {
 
-       process.on(signal, () => {
 
-         server.close(() => {
 
-           process.exit(0)
 
-         })
 
-       })
 
-     })
 
-     if (args.stdin) {
 
-       process.stdin.on('end', () => {
 
-         server.close(() => {
 
-           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.close(() => {
 
-             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()
 
-           if (args.open || projectDevServerOptions.open) {
 
-             const pageUri = (projectDevServerOptions.openPage && typeof projectDevServerOptions.openPage === 'string')
 
-               ? projectDevServerOptions.openPage
 
-               : ''
 
-             openBrowser(localUrlForBrowser + pageUri)
 
-           }
 
-           // 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.listen(port, host, err => {
 
-         if (err) {
 
-           reject(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)
 
-   }
 
- }
 
- // https://stackoverflow.com/a/20012536
 
- function checkInContainer () {
 
-   const fs = require('fs')
 
-   if (fs.existsSync(`/proc/1/cgroup`)) {
 
-     const content = fs.readFileSync(`/proc/1/cgroup`, 'utf-8')
 
-     return /:\/(lxc|docker|kubepods)\//.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'
 
- }
 
 
  |