常用配置项——Mode
默认值是 production(什么都不设置的情况下);可选值有:'none' | 'development' | 'production'。
- development:会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 development,为模块和 chunk 启用有效的名。
- production:会将 DefinePlugin 中 process.env.NODE_ENV 的值设置为 production,为模块和 chunk 启用确定性的混淆名称。
- none:不使用任何默认优化选项
常用配置项——Source Map
一、如何在 Webpack 中启用 Source Map
在 webpack.config.js 中,通过配置 devtool 选项来控制是否生成 source map 以及生成的类型:
module.exports = {// ...devtool: 'source-map', // 或其他值
};
二、常见的 devtool 选项及其区别
💡 实践建议:
- 开发/测试环境:常用
eval-cheap-module-source-map(速度快 + 能定位到原始模块)- 生产环境:
- 如果需要错误监控(如 Sentry),可使用
hidden-source-map或nosources-source-map
- 通过
sentry-cli将.map文件上传到 Sentry- 用户报错时,Sentry 利用 source map 自动还原原始错误位置
- 一般不直接暴露完整
source-map,以防源码泄露
三、Source Map 的工作原理简述
- Webpack 在打包时根据
devtool配置生成.map文件(如main.js.map) - 在输出的 bundle 文件(转换后的文件)末尾添加一行魔法注释:
//# sourceMappingURL=main.js.map
- 浏览器 DevTools 自动加载该
.map文件,并将压缩代码映射回原始源码 - 开发者可以在 DevTools 中像调试原始代码一样设置断点、查看变量等
常用配置项——Babel、Browserslist、Polyfill
见之前的文章:《身为大厂前端的你,不能不知道 Babel + Polyfill!》
常用配置项——devServer
你有没有想过一个问题,我们干前端的,为什么要在构建工作内嵌一个服务器(devServer)。
原因其实有这么两个:
- 文件变化时完成自动构建
- 启动一个服务查看页面展示(最最之前我们学 html 的时候也是通过 live server 启动的一个内置服务器查看页面)
webpack-dev-server 在编译之后不会写入到任何输出文件,而是将 bundle 文件保留在内存中。
常见配置:
devServer: {host: '0.0.0.0', // 允许外部访问(如手机调试)port: 3000,open: true, // 启动后自动打开默认浏览器hot: true, // 启用 HMR(模块热更新)static: { // 指定静态资源目录(如 public 文件夹)directory: path.join(__dirname, 'public'), // 静态资源根目录publicPath: '/', // 访问路径前缀watch: true, // 监听变化并刷新},compress: true, // 是否为静态文件开启 gzip压缩,默认为falseproxy: { // 一般用于开发环境反向代理避免CORS'/api': {target: 'http://localhost:8080',changeOrigin: true, // 改变请求头中的 hostpathRewrite: {'^/api': '', // 重写路径,去掉 /api 前缀},},},historyApiFallback: true, // 解决SPA页面在路由跳转之后,进行页面刷新时,返回404的错误
}
- 默认
localhost(仅本机访问),这里我们在实际开发中可能会遇到一个问题,就是后端同学无法通过我们项目的 ip 地址访问,这是因为你和他的主机处于同一网段- 设为
'0.0.0.0'可局域网访问(常用于真机调试)
hot: true:支持 HMR,若失败则 fallback 到页面刷新hotOnly: true:仅 HMR,编译失败不刷新页面(hot: true 编译失败会重新刷新整个页面)
常用配置——哈希
在我们给打包的文件进行命名的时候,会使用 placeholder 占位符,这里详细说说占位符的这几个属性:
hash 本身是通过 MD4 的散列函数处理后,生成一个 128 位的 hash 值(32 个十六进制)
- hash 值的生成和整个项目有关系:
- 比如我们现在有两个入口 index.js 和 main.js;
- 它们分别会输出到不同的 bundle 文件中,并且在文件名称中我们有使用 hash;
- 这个时候,如果修改了 index.js 文件中的内容,那么 hash 会发生变化,两个文件的名称都会发生变化;
- chunkhash 可以有效的解决上面的问题,它会根据不同的入口进行借来解析来生成 hash 值:
- 比如我们修改了 index.js,那么 main.js 的 chunkhash 是不会发生改变的;
- contenthash 表示生成的文件 hash 名称,只和内容有关系:
- 比如我们的 index.js,引入了一个 style.css,style.css 有被抽取到一个独立的 css 文件中;
- 这个 css 文件在命名时,如果我们使用的是 chunkhash,那么当 index.js 文件的内容发生变化时,css 文件的命名也会发生变化;
- 这个时候我们可以使用 contenthash,不影响 css 文件名