0%

webpack(三)开发环境配置

仅用于开发环境不要在生产环境中使用!

source-map –映射关系

当 webpack 打包源代码时,可能会很难追踪到错误和警告在源代码中的原始位置。例如,如果将三个源文件(a.js, b.jsc.js)打包到一个 bundle(bundle.js)中,而其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js。这并通常没有太多帮助,因为你可能需要准确地知道错误来自于哪个源文件。

为了更容易地追踪错误和警告,JavaScript 提供了 source map 功能,将编译后的代码映射回原始源代码。如果一个错误来自于 b.js,source map 就会明确的告诉你。

原理

面试常常会问原理,需要掌握。

配置

mode:'development'时,source map默认是打开,

也可以devtool : 'source-map',此时会生成一个.map文件,存放代码打包前后的映射关系。如果用inline-cheap-source-map时,就不会生成.map文件,直接写在打包后的js文件中用base64写入。

  • source-map 产生source map文件。

  • inline:不会生成map文件,直接将.map作为DataURI嵌入打包后的js文件中(包含inline关键字的配置项也会产生.map文件,但是这个map文件是经过base64编码作为DataURI嵌入)

  • cheap:只显示第几行,不显示第几行的第几列。

  • module:显示loader、第三方模块的source map。

eval:用eval函数直接把代码注入。没有.map 也没有base64写入。速度相对较快。是使用eval将webpack中每个模块包裹,然后在模块末尾添加模块来源//# souceURL, 依靠souceURL找到原始代码的位置。(eval模式有点特殊, 它和其他模式不一样的地方是它依靠sourceURL来定位原始代码, 而其他所有选项都使用.map文件的方式来定位)

最佳实践

1
2
3
4
5
6
7
8
[webpack.config.js]
...
mode : 'production' ,
devtool : 'eval-cheap-module-source-map'
...

mode : 'production' ,
devtool : 'cheap-module-source-map' 或者注释掉,不做映射
  1. https://segmentfault.com/a/1190000008315937
  2. https://www.html5rocks.com/en/tutorials/developertools/sourcemaps/
  3. http://www.ruanyifeng.com/blog/2013/01/javascript_source_map.html
  4. https://www.youtube.com/watch?v=NkVes0UMe9Y

Dev Server

每次要编译代码时,手动运行 npm run bundle 就会变得很麻烦。我们需要:

  1. 修改源代码后自动打包。
  2. 打包后自动打开浏览器。
  3. 刷新浏览器。

webpack 中有几个不同的选项,可以帮助你在代码发生变化后自动编译代码:

  1. webpack’s Watch Mode 观察模式
  2. webpack-dev-server
  3. webpack-dev-middleware

多数场景中需要使用 webpack-dev-server

配置

1
2
3
4
5
6
7
8
[package.json]
{
'scripts' : {
'watch' : 'webpack --watch' ,
'start' : 'webpack-dev-server',
'server' : 'node server.js'
}
}

观察模式

源代码改变就自动重新打包。但不能重新打开浏览器。静态页面也无法发出ajax请求等服务器操作。

在命令行中运行 npm run watch,就会看到 webpack 编译代码,然而却不会退出命令行。这是因为 script 脚本还在观察文件。

devServer

webpack-dev-server 提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。

需要安装webpack-dev-server,并修改配置文件告诉服务器在哪里查找文件。

以下配置告知 webpack-dev-server,在 localhost:8080 (默认值)下建立服务,将 dist 目录下的文件,作为可访问文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
npm install -D webpack-dev-server
[webpack.config.js]
...
//修改配置文件告诉服务器在哪里查找文件。
devSever : {
contentBase : './dist',
open : true //自动打开浏览器
port : 8080 //端口
proxy : {
'/api' : 'http://xxx' //跨域代理配置,将请求转发
}
}
...


[输出]
> webpack-dev-server

i 「wds」: Project is running at http://localhost:8080/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from ./dist
i 「wdm」: Hash: 146d630f7310e8e6347c

middleware

可以自己实现一个server并配置使用它,但要实现与devServer样的功能需要很多配置。了解即可,不需要自己手动配置。

webpack-dev-middleware 是一个容器(wrapper),它可以把 webpack 处理后的文件传递给一个服务器(server)。 webpack-dev-server 在内部使用了它,同时,它也可以作为一个单独的包来使用,以便进行更多自定义设置来实现更多的需求。

https://www.webpackjs.com/guides/development/#%E4%BD%BF%E7%94%A8-webpack-dev-middleware

Hot Module Replacement HMR 模块热更新

模块热替换(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面时丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 调整样式更加快速 - 几乎相当于在浏览器调试器中更改样式。

配置样式文件的热更新

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[webpack.config.js]
const webpack = require("webpack"); //模块热更新插件在webpack包里
...
devServer: {
contentBase: "./dist",
open: true,
+ hot: true, //打开模块热更新
+ hotOnly: true,//热更新失败也不刷新页面
},
plugins: [
new HtmlWebpackPlugin({
template: "src/index.html",
}),
new CleanWebpackPlugin(),
+ new webpack.HotModuleReplacementPlugin(),
+ new webpack.NamedModulesPlugin(), //以便更容易查看要修补(patch)的依赖。
],

配置之后,修改样式文件即可热更新。

自己配置的js文件直接使用配置不会生效,原因是需要配置module.hot.accept()

1
2
3
4
module.hot.accept(
dependencies, // 可以是一个字符串或字符串数组,可以是修改的
callback // 用于在模块更新后触发的函数
)

样式文件的css-loader、vue的vue-loader会帮你做这部分工作,所以只要打开热更新,不需要其他的配置即可生效。