NOTE: Refer to this for latest guide.
This article assuming you created your project using webpack template.
vue init webpack <PROJECT_NAME>
Open package.json
and observe the scripts
section. You realize there is dev
to spin up a development server with hot reload and build
for production release. There isn't an option for development release with hot reloading (watch mode).
Note: if you are not using webpack, you can use vue build index.js --watch
to enable watch mode.
...
"scripts": {
"dev": "node build/dev-server.js",
"start": "node build/dev-server.js",
"build": "node build/build.js",
"unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run",
"e2e": "node test/e2e/runner.js",
"test": "npm run unit && npm run e2e",
"lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs"
},
...
Edit package.json
to add watch
.
```text
...
"scripts": {
...
"watch": "node build/watch-build-dev.js"
},
...
Copy build/build.js
to build/watch-build-dev.js
, and edit as per following (changes are commented with EDIT
).
require('./check-versions')()// EDIT: process.env.NODE_ENV = 'production'process.env.NODE_ENV = 'development'var ora = require('ora')var rm = require('rimraf')var path = require('path')var chalk = require('chalk')var webpack = require('webpack')var config = require('../config')// EDIT: var webpackConfig = require('./webpack.prod.conf')var webpackConfig = require('./webpack.watch.conf')// EDIT: ora('building for production...')var spinner = ora('building for development...')spinner.start()rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err webpack(webpackConfig, function (err, stats) { spinner.stop() if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n') // EDIT: remove the following to avoid watch quit upon error /* if (stats.hasErrors()) { console.log(chalk.red(' Build failed with errors.\n')) process.exit(1) } */ console.log(chalk.cyan(' Build complete.\n')) // EDIT: remove /* console.log(chalk.yellow( ' Tip: built files are meant to be served over an HTTP server.\n' + ' Opening index.html over file:// won\'t work.\n' )) */ })})
Copy build/webpack.dev.conf.js
to build/webpack.watch.conf.js
, and edit as per following (changes are commented with EDIT
).
Update 2017-11-26: for vue-cli-template-webpack
1.2.4, copy build/webpack.prod.conf.js
to build/webpack.watch.conf.js
, and edit as per following (changes are commented with EDIT
)
'use strict'const path = require('path')const utils = require('./utils')const webpack = require('webpack')const config = require('../config')const merge = require('webpack-merge')const baseWebpackConfig = require('./webpack.base.conf')const CopyWebpackPlugin = require('copy-webpack-plugin')const HtmlWebpackPlugin = require('html-webpack-plugin')const ExtractTextPlugin = require('extract-text-webpack-plugin')const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')// EDIT: change to development// const env = require('../config/prod.env')const env = require('../config/dev.env')const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false, output: { path: config.build.assetsRoot, // EDIT: remove hash // filename: utils.assetsPath('js/[name].[chunkhash].js'), // chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') filename: utils.assetsPath('js/[name].js'), chunkFilename: utils.assetsPath('js/[id].js') }, plugins: [ // http://vuejs.github.io/vue-loader/en/workflow/production.html new webpack.DefinePlugin({ 'process.env': env }), // UglifyJs do not support ES6+, you can also use babel-minify for better treeshaking: https://github.com/babel/minify // EDIT: disable js minify /* new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false }, sourceMap: config.build.productionSourceMap, parallel: true }), */ // extract css into its own file new ExtractTextPlugin({ // EDIT: remove hash // filename: utils.assetsPath('css/[name].[contenthash].css'), filename: utils.assetsPath('css/[name].css'), // set the following option to `true` if you want to extract CSS from // codesplit chunks into this main css file as well. // This will result in *all* of your app's CSS being loaded upfront. // EDIT: if not then splitting vendor.css will cause javascript error // allChunks: false, allChunks: true, }), // Compress extracted CSS. We are using this plugin so that possible // duplicated CSS from different components can be deduped. // EDIT: disable CSS minify /* new OptimizeCSSPlugin({ cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), */ // generate dist index.html with correct asset hash for caching. // you can customize output by editing /index.html // see https://github.com/ampedandwired/html-webpack-plugin new HtmlWebpackPlugin({ filename: config.build.index, template: 'index.html', inject: true, // EDIT: disable minify /* minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true // more options: // https://github.com/kangax/html-minifier#options-quick-reference }, */ minify: false, // necessary to consistently work with multiple chunks via CommonsChunkPlugin chunksSortMode: 'dependency' }), // keep module.id stable when vender modules does not change new webpack.HashedModuleIdsPlugin(), // enable scope hoisting // EDIT: // new webpack.optimize.ModuleConcatenationPlugin(), // split vendor js into its own file new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', minChunks: function (module) { // any required modules inside node_modules are extracted to vendor // EDIT return ( module.resource && /\.(js|css|sass|scss|less)$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), // extract webpack runtime and module manifest to its own file in order to // prevent vendor hash from being updated whenever app bundle is updated new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), // This instance extracts shared chunks from code splitted chunks and bundles them // in a separate chunk, similar to the vendor chunk // see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), // copy custom static assets new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ], // EDIT: enable watch watch: true, // EDIT: enable watch for modules // https://github.com/vuejs-templates/webpack/issues/378 watchOptions: { aggregateTimeout: 300, poll: 1000 }})if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) )}if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin())}module.exports = webpackConfig
Run npm run watch
to enable development build in watch mode.
Note: if you include global scope CSS, remember to import
them at main.js
.
npm run watch# output> [email protected] watch /code/vue/hello> node build/watch-build-dev.js⠙ building for development... DONE Compiled successfully in 2923ms 5:32:25 PMHash: fcfe8096ae777ea47bf7Version: webpack 2.7.0Time: 2923ms Asset Size Chunks Chunk Names app.js 780 kB 0 [emitted] [big] appstatic/css/app.css 93 bytes 0 [emitted] app index.html 845 bytes [emitted] Build complete.
Output shall be created at dist
folder. You can use symbolic link (ln -s /code/vue/hello/dist/app.js
) to link to these files from you external server (e.g. nginx) development directory. You can use something like livereload on the external server development directory to reload if changes are detected.