webpack-dev-server是webpack官方提供的一个小型Express服务器。使用它可以为webpack打包生成的资源文件提供web服务。
webpack-dev-server 主要提供两个功能:
- 为静态文件提供服务
- 自动刷新和热替换(HMR)
文件结构
|--src | |--views | |--index.js | |--module_a | |--list.js | |--module_b | |--list.js |--index.html |--webpack.config.base.js |--webpack.config.dev.js
文件内容
[/src/.../module_a/list.js]
export function getName() { console.log("module_a_list");}
[/src/.../module_a/list.js]
export function getName() { console.log("module_b_list");}
[/src/.../index.js]
import * as a_list from "./module_a/list.js"import * as b_list from "./module_b/list.js"a_list.getName();b_list.getName();
[/index.html]
RUN WEBPACK_DEMO
[/webpack.config.base.js]
var webpack = require("webpack");var path = require("path");module.exports = { cache: true, debug: true, entry: { "app": "./src/views/index.js" }, output: { filename: "[name].js", path: __dirname + "/dist", publicPath: "/dist/" }, module: { loaders: [ { test: /.jsx?$/, loader: "babel", query: { presets: ["react", "es2015", "stage-0"], cacheDirectory: true }, exclude: /node_modules/ } ] }, plugins: []}
[/webpack.config.base.js]
var webpack = require("webpack");var webpackBase = require("./webpack.config.base.js");var cfg = Object.assign(webpackBase, { devtool: "cheap-module-eval-source-map"});module.exports = cfg;
webpack-dev-server
- 首先需要全局安装
webpack-dev-server
npm i webpack-dev-server -g
- package.json配置scripts:
"scripts":{ "start":"webpack-dev-server --config webpack.config.dev.js"}
- 执行
npm start
,输出如下:
命令要求webpack-dev-server执行当前目录下webpack.config.dev.js文件,发布地址默认为localhost:8080
浏览器访问
http://localhost:8080
,可以看到,项目根目录下的index.html开始运行F12打开浏览器控制台,输出js文件log
以上,一个简单的devServer配置就完成了
自动刷新
在实际开发中,我们往往有以下需求:
1、每次修改代码后,webpack可以自动重新打包 2、浏览器可以响应代码变化并自动刷新 webpack-dev-server提供了两种自动刷新模式:iframe和inlineiframe
页面被嵌套在一个iframe下,代码发生改动后,iframe会重新加载
使用此模式无需额外配置,只需访问http://localhost:8080/webpack-dev-server/index.html
即可,显然webpack-dev-server默认的模式就是iframe 浏览器访问
http://localhost:8080/webpack-dev-server/index.html
修改js代码后保存,命令行log显示module_a/list.js变化导致app.js重新生成:
同时浏览器自动刷新,控制台输出如下:
inline
此方式会将webpack-dev-server客户端加入到webpack入口文件的配置中。
配置方式有两种:CLI配置和通过Node.js Api手动配置1)CLI 方式
此方式比较简单,只需在webpack.dev.server启动的命令中加入--inline
即可
- 修改package.json中scripts配置,添加
--inline
:
"scripts":{ "start":"webpack-dev-server --inline --config webpack.config.dev.js"}
- 重新运行
npm start
,浏览器访问http://localhost:8080
即可,修改代码后保存,浏览器自动刷新
当然webpack-dev-server类似的命令还有很多,比如,我们就可以规定项目可访问的地址为http://localhost:9093
:
"scripts":{ "start":"webpack-dev-server --inline --host localhost --port 9093 --config webpack.config.dev.js"}
更多配置参考
2)Node.js Api方式
此方式需要手动将webpack-dev-server客户端配置到webpack打包的入口文件中
- 修改文件webpack.config.dev.js:
var webpack = require("webpack");var webpackBase = require("./webpack.config.base.js");var cfg = Object.assign(webpackBase, { devtool: "cheap-module-eval-source-map"});//entry Object.getOwnPropertyNames((webpackBase.entry || {})).map(function (name) { cfg.entry[name] = [] //添加webpack-dev-server客户端 .concat("webpack-dev-server/client?http://localhost:9091") .concat(webpackBase.entry[name])});module.exports = cfg;
- 根目录添加文件devServer.js,用于创建服务器实例
var path = require("path");var webpack = require("webpack");var webpackDevServer = require("webpack-dev-server");var webpackCfg = require("./webpack.config.dev.js");var compiler = webpack(webpackCfg);//init servervar app = new webpackDevServer(compiler, { //注意此处publicPath必填 publicPath: webpackCfg.output.publicPath});app.listen(9390, "localhost", function (err) { if (err) { console.log(err); }});console.log("listen at http://localhost:9390");
- 修改package.json中scripts配置,通过执行devServer.js文件启动服务器:
"scripts":{ "start":"node devServer.js"}
- 重新运行
npm start
,浏览器访问http://localhost:9390
即可,修改代码后保存,浏览器自动刷新
热替换(HMR)
当我们使用webpack-dev-server的自动刷新功能时,浏览器会整页刷新。
而热替换的区别就在于,当前端代码变动时,无需刷新整个页面,只把变化的部分替换掉。 配置的关键在于将webpack/hot/dev-server
文件加入到webpack所有入口文件中。 使用HMR同样同样有两种方式:CLI和Node.js Api CLI方式
命令行配置比较简单,只需在自动刷新的基础上,加上--hot
配置即可。
- 修改package.json中scripts配置,添加
--hot
:
"scripts":{ "start":"webpack-dev-server --inline --hot --config webpack.config.dev.js"}
- 执行
npm start
,浏览器访问http://localhost:8080
即可,当控制台出现如下信息,说明HMR配置成功
Node.js Api方式
此方式需要手动将webpack/hot/dev-server配置到所有webpack入口文件中
- 修改文件webpack.config.dev.js,添加
webpack/hot/dev-server
,添加插件HotModuleReplacementPlugin
:
var webpack = require("webpack");var webpackBase = require("./webpack.config.base.js");var cfg = Object.assign(webpackBase, { devtool: "cheap-module-eval-source-map"});//entryObject.getOwnPropertyNames((webpackBase.entry || {})).map(function (name) { cfg.entry[name] = [] //添加HMR文件 .concat("webpack/hot/dev-server") .concat("webpack-dev-server/client?http://localhost:9390") .concat(webpackBase.entry[name])});//pluginscfg.plugins = (webpackBase.plugins || []).concat( new webpack.optimize.OccurrenceOrderPlugin(), //添加HMR插件 new webpack.HotModuleReplacementPlugin(), new webpack.NoErrorsPlugin())module.exports = cfg;
- 根目录添加文件devServer.js,用于创建服务器实例,添加
hot:true
var path = require("path");var webpack = require("webpack");var webpackDevServer = require("webpack-dev-server");var webpackCfg = require("./webpack.config.dev.js");var compiler = webpack(webpackCfg);//init servervar app = new webpackDevServer(compiler, { //注意此处publicPath必填 publicPath: webpackCfg.output.publicPath, //HMR配置 hot:true});app.listen(9390, "localhost", function (err) { if (err) { console.log(err); }});console.log("listen at http://localhost:9390");
- 修改package.json中scripts配置,通过执行devServer.js文件启动服务器:
"scripts":{ "start":"node devServer.js"}
- 重新运行
npm start
,浏览器访问http://localhost:9390
即可,当控制台出现如下信息,说明HMR配置成功
可见,使用webpack-dev-server辅助开发,可以极大的方便前端调试。特别是在前后端分离的场景下,使前端可以更加灵活的构建自己的开发环境。