# 开发环境

模式切换成development,自动优化。

module.exports = {
  mode: "development",
};
1
2
3

# 自动构建

每次文件更新时,自己手动执行命令打包,效率会很低。可以使用webpack自带的观察模式。如果文件更新,自动打包。打包完成后页面是不会刷新的,需要手动刷新才能看到最新效果,可以查看服务器搭建来解决自动刷新问题(也可以解决自动构建问题)。

# 启动
webpack --watch
1
2

提示

推荐使用webpack-dev-serverwebpack-dev-middleware,因为会自动监听、打包、刷新,还可以使用热更新功能。

# source map

很多文件都打包成一个文件,错误时难以追踪。例如bundle.js包含a.jsb.jsc.js三个文件的内容,如果其中c.js的第 x 行代码发生错误,实际上在控制台中会显示bundle.js第 xxx 行错误。添加以下代码可解决,此外还提供其他选项 (opens new window)

module.exports = {
  devtool: "inline-source-map",
};
1
2
3

# 服务器搭建

如果每次手动刷新页面查看最新效果,或者每次都将打包后的产物放到服务器上查看效果,这都会很麻烦,且大大降低开发效率。我们可以使用webpack-dev-server或者可以使用webpack-dev-middleware更加定制化。

提示

webpack-dev-server内部其实也是使用webpack-dev-middleware该插件。

# webpack-dev-server

# 安装
npm install --save-dev webpack-dev-server
1
2
// webpack.config.js
module.exports = {
  // 将 dist 目录作为服务器根目录
  devServer: {
    contentBase: "./dist",
    // 默认
    // publicPath: "/", // http://location:xxxx/ 访问
    publicPath: "/assets/", // http://location:xxxx/assets/ 访问
  },
};
1
2
3
4
5
6
7
8
9
10
# webpack5 webpack-cli v4
webpack serve --config ./webpack.config.js
# webpack4
webpack-dev-server --config ./webpack.config.js
1
2
3
4

注意

启用命令时,不会输出编译产物,因为是写进内存里的。另外 webpack5 需要使用webpack serve,可参考issue 2029 (opens new window)issue 2759 (opens new window)

# webpack-dev-middleware

# 安装
npm install --save-dev express webpack-dev-middleware
1
2
// webpack.config.js
module.exports = {
  output: {
    // ...
    publicPath: "/",
  },
};
1
2
3
4
5
6
7
// 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);

// 延迟加载,可以模拟网络慢的情景
app.use(function(req, res, next) {
  setTimeout(() => next(), 2000);
});

// 告知 express 使用 webpack-dev-middleware,
// 以及将 webpack.config.js 配置文件作为基础配置。
app.use(
  WebpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

// 将文件 serve 到 port 8080。
app.listen(8080, function() {
  console.log("端口监听:8080!\n");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 启动
node server.js
1
2

# 热更新

你需要告诉 webpack 哪些文件更新后,页面是需要强制刷新的,而哪些是可以热更新,并且传递热更新函数。

假设函数NewImage原本是创建200px的图片,现在改为300px的图片,我们不想让页面刷新才显示效果。可以使用如下代码:

// 是否支持热更新
if (module.hot) {
  // 允许module.js热更新、传入热更新回调
  module.hot.accept("./module.js", () => {
    // 获取所有图片
    const imgs = document.getElementsByTagName("img");
    // 重新执行 NewImage 函数,替换原本的图片
    Array.prototype.forEach.call(imgs, (img) => {
      const src = img.getAttribute("src");
      const newImg = NewImage(src);
      img.parentNode.replaceChild(newImg, img);
    });
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# webpack-dev-server







 



 



const webpack = require("webpack");

module.exports = {
  // ...
  devServer: {
    // ...
    hot: true,
  },
  plugins: [
    // ...
    new webpack.HotModuleReplacementPlugin(), // webpack v4
  ],
};
1
2
3
4
5
6
7
8
9
10
11
12
13

注意

webpack v5 不需使用HotModuleReplacementPlugin

# webpack-dev-middleware

npm install --save-dev webpack-hot-middleware
1




 



















 






// server.js
const express = require("express");
const webpack = require("webpack");
const WebpackDevMiddleware = require("webpack-dev-middleware");
const WebpackHotMiddleware = require("webpack-hot-middleware");

const app = express();
const config = require("./webpack.config.js");
const compiler = webpack(config);

// 延迟加载,可以模拟网络慢的情景
app.use(function(req, res, next) {
  setTimeout(() => next(), 2000);
});

// 告知 express 使用 webpack-dev-middleware,
// 以及将 webpack.config.js 配置文件作为基础配置。
app.use(
  WebpackDevMiddleware(compiler, {
    publicPath: config.output.publicPath,
  })
);

// 热更新
app.use(WebpackHotMiddleware(compiler));

// 将文件 serve 到 port 8080。
app.listen(8080, function() {
  console.log("端口监听:8080!\n");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30