1.安装webpack
//全局安装 npm install -g webpack //安装到你的项目目录 npm install --save-dev webpack
2.编写webpack配置文件
webpack.config.js
var webpack=require('webpack'); const path=require('path'); const htmlWebpackPlugin=require('html-webpack-plugin'); module.exports={ entry:'./main.js', output:{ path: path.resolve(__dirname + '/dist'), filename:'main.bundle.js' }, devServer:{ contentBase:'./dist' }, plugins:[ new htmlWebpackPlugin({ title:'output html', template:'index.html' }) ] }
3.执行webpack命令
4.使用 webpack-dev-server
webpack-dev-server 为你提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。让我们设置以下:
npm install --save-dev webpack-dev-server
修改配置文件,告诉开发服务器(dev server),在哪里查找文件:
webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, devtool: 'inline-source-map', + devServer: { + contentBase: './dist' + }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Development' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
以上配置告知 webpack-dev-server,在 localhost:8080 下建立服务,将 dist 目录下的文件,作为可访问文件。
让我们添加一个 script 脚本,可以直接运行开发服务器(dev server):
package.json { "name": "development", "version": "1.0.0", "description": "", "main": "webpack.config.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "watch": "webpack --progress --watch", + "start": "webpack-dev-server --open", "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "clean-webpack-plugin": "^0.1.16", "css-loader": "^0.28.4", "csv-loader": "^2.1.1", "file-loader": "^0.11.2", "html-webpack-plugin": "^2.29.0", "style-loader": "^0.18.2", "webpack": "^3.0.0", "xml-loader": "^1.2.1" } }
现在,我们可以在命令行中运行 npm start
,就会看到浏览器自动加载页面。如果现在修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。
注意:使用 webpack-dev-server命令时,项目中不会有dist目录。它是被写在内存中。直接使用webpack命令时才会有dist目录。
5.使用 webpack-dev-middleware
webpack-dev-middleware
是一个中间件容器(wrapper),它将通过 webpack 处理后的文件发布到一个服务器(server)。在内部 webpack-dev-server
它使用,然而,它可以作为一个单独的包来提供,可以进行更多的自定义设置来实现更多需求。接下来是一个 webpack-dev-middleware 配合 express server 的示例。
首先,安装 express
和 webpack-dev-middleware
:
npm install --save-dev express webpack-dev-middleware
接下来我们需要对 webpack 的配置文件做一些调整,以确保中间件(middleware)功能能够正确启用:
webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); module.exports = { entry: { app: './src/index.js', print: './src/print.js' }, devtool: 'inline-source-map', plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Output Management' }) ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist'), + publicPath: '/' } };
publicPath
也会在服务器脚本用到,以确保文件资源能够在 http://localhost:3000
下正确访问,我们稍后再设置端口号。下一步就是设置我们自定义的 express
服务:
project webpack-demo |- package.json |- webpack.config.js + |- server.js |- /dist |- /src |- index.js |- print.js |- /node_modules server.js const express = require('express'); const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); const app = express(); const config = require('./webpack.config.js'); const compiler = webpack(config); // Tell express to use the webpack-dev-middleware and use the webpack.config.js // configuration file as a base. app.use(webpackDevMiddleware(compiler, { publicPath: config.output.publicPath })); // Serve the files on port 3000. app.listen(3000, function () { console.log('Example app listening on port 3000! ');
6.启用 HMR(使用webpack-dev-server方式)
webpack.config.js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const CleanWebpackPlugin = require('clean-webpack-plugin'); + const webpack = require('webpack'); module.exports = { entry: { - app: './src/index.js', - print: './src/print.js' + app: './src/index.js' }, devtool: 'inline-source-map', devServer: { contentBase: './dist', + hot: true }, plugins: [ new CleanWebpackPlugin(['dist']), new HtmlWebpackPlugin({ title: 'Hot Module Replacement' }), + new webpack.NamedModulesPlugin(), + new webpack.HotModuleReplacementPlugin() ], output: { filename: '[name].bundle.js', path: path.resolve(__dirname, 'dist') } };
你可以通过命令来修改 webpack-dev-server 的配置:webpack-dev-server --hot-only
。
注意,我们还添加了 NamedModulesPlugin
,以便更容易查看要修补(patch)的依赖。在起步阶段,我们将通过在命令行中运行 npm start
来启动并运行 dev server。
按照上述方法进行模块热替换,更改文件后虽然执行了热替换,但是页面并没有自动刷新,具体原因不详。
通过 Node.js API
当使用 webpack dev server 和 Node.js API 时,不要将 dev server 选项放在 webpack 配置对象(webpack config object)中。而是,在创建选项时,将其作为第二个参数传递。例如:
new WebpackDevServer(compiler, options)
想要启用 HMR,还需要修改 webpack 配置对象,使其包含 HMR 入口起点。webpack-dev-server
package 中具有一个叫做 addDevServerEntrypoints
的方法,你可以通过使用这个方法来实现。这是关于如何使用的一个小例子:
dev-server.js const webpackDevServer = require('webpack-dev-server'); const webpack = require('webpack'); const config = require('./webpack.config.js'); const options = { contentBase: './dist', hot: true, host: 'localhost' }; webpackDevServer.addDevServerEntrypoints(config, options); const compiler = webpack(config); const server = new webpackDevServer(compiler, options); server.listen(5000, 'localhost', () => { console.log('dev server listening on port 5000'); });
7.使用webpack-dev-middleware和webpack-hot-middleware(可以热替换和与express结合,实现服务监听和自动刷新页面)
npm install --save-dev webpack-hot-middleware
修改配置文件:
1.配置文件添加: plugins: [ // OccurenceOrderPlugin is needed for webpack 1.x only new webpack.optimize.OccurenceOrderPlugin(), new webpack.HotModuleReplacementPlugin(), // Use NoErrorsPlugin for webpack 1.x new webpack.NoEmitOnErrorsPlugin() ] 2.服务器文件添加: var webpack = require('webpack'); var webpackConfig = require('./webpack.config'); var compiler = webpack(webpackConfig); app.use(require("webpack-dev-middleware")(compiler, { noInfo: true, publicPath: webpackConfig.output.publicPath })); app.use(require("webpack-hot-middleware")(compiler)); 3.要实现自动刷新还要添加: var ansiColors = { red: '00FF00' // note the lack of "#" }; var overlayStyles = { color: '#FF0000' // note the inclusion of "#" (these options would be the equivalent of div.style[option] = value) }; var hotMiddlewareScript = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true&ansiColors=' + encodeURIComponent(JSON.stringify(ansiColors)) + '&overlayStyles=' + encodeURIComponent(JSON.stringify(overlayStyles));
4.完整的配置文件:
var webpack=require('webpack'); const path=require('path'); const htmlWebpackPlugin=require('html-webpack-plugin'); var ansiColors = { red: '00FF00' // note the lack of "#" }; var overlayStyles = { color: '#FF0000' // note the inclusion of "#" (these options would be the equivalent of div.style[option] = value) }; var hotMiddlewareScript = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000&reload=true&ansiColors=' + encodeURIComponent(JSON.stringify(ansiColors)) + '&overlayStyles=' + encodeURIComponent(JSON.stringify(overlayStyles)); module.exports={ entry:['./public/javascripts/main.js',hotMiddlewareScript], output:{ path:path.resolve(__dirname,'dist'), filename:'main.bundle.js', publicPath:'/' }, devServer:{ contentBase:'./dist' }, plugins:[ new htmlWebpackPlugin({ title:'output html', template:'index.html' }), // OccurenceOrderPlugin is needed for webpack 1.x only new webpack.HotModuleReplacementPlugin(), // Use NoErrorsPlugin for webpack 1.x new webpack.NoEmitOnErrorsPlugin() ] }