WebPack能够看作是模块打包机:它作的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。在3.0出现后,Webpack还肩负起了优化项目的责任。css
这段话有三个重点:前端
现在的不少网页其实能够看作是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了不少好的实践方法react
a:模块化,让咱们能够把复杂的程序细化为小的文件;webpack
b:相似于TypeScript这种在JavaScript基础上拓展的开发语言:使咱们可以实现目前版本的JavaScript不能直接使用的特性,而且以后还能转换为JavaScript文件使浏览器能够识别;web
c:scss,less等CSS预处理器json
tree shaking 是一个术语,一般用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于浏览器
(import和export)
package.json
文件中,添加一个 "sideEffects" 入口。UglifyJSPlugin, babel-minify-webpack-plugin, webpack-closure-compiler);
或者将mode设成production。将文件标记为无反作用(side-effect-free)缓存
这种方式是经过 package.json 的 "sideEffects"
属性来实现的.服务器
{ "name": "your-project", "sideEffects": [ "./src/some-side-effectful-file.js", "*.css" ] }
压缩输出:从 webpack 4 开始,能够经过 "mode"
配置选项设置为 "production",轻松实现压缩输出。
babel
webpack.config.js
const path = require('path'); module.exports = { entry: './src/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'dist') }, mode: "production" };
devtool: 开发环境下使用inline-source-map,生产环境使用source-map.
Code spliting(代码分离)
1.手动添加入口起点
2.移除重复的依赖模块:(webpack4取消了CommonsChunkPlugin),转而使用下面的方法。
optimization与entry/plugins同级
optimization: { // 优化 splitChunks: { // 分离 cacheGroups: { commons: { name: 'common', // 共享模块的名称 chunks: 'initial', // minChunks: 2 // 公享模块最少复用过几回 } } } }
3.动态导入 import()
async function getComponent () { const _ = await import(/* webpackChunkName: "lodash" */ 'lodash'); var element = document.createElement('div'); element.innerHTML = _.join(['hello', 'webpack'], ' '); return element; }
缓存:确保 webpack 编译生成的文件可以被客户端缓存,而在文件内容变化后,可以请求到新的文件。
1.使用 [chunkhash]
生成文件名
output: { filename: '[name].[chunkhash].js', path: path.resolve(__dirname, 'dist') },
2. 代码分离:optimization.splitChunks在每次修改后的构建结果中,将 webpack 的样板(boilerplate)和 manifest 提取出来。
此外,将第三方库(library)(例如 lodash
或 react
)提取到单独的 vendor
chunk 文件中。
entry: { app: './src/script/index.js', vendor: ['lodash'] }, optimization: { // 优化 splitChunks: { // 分离 cacheGroups: { vendor: { name: 'vendor', priority: 10, chunks: 'initial', // // enforce: true }, commons: { name: 'manifest', // 共享模块的名称 chunks: 'initial', // minChunks: 1 // 公享模块最少复用过几回 } } } }
注意问题:
1.混合使用ES2015,AMD CommonJS
你能够自由混合使用三种模块类型(甚至在同一个文件中)。在这个状况中 webpack 的行为和 babel一致。
// ES2015 模块调用 CommonJS import fs from "fs"; // module.exports 映射到 default import { readFileSync } from "fs"; // 从返回对象(returned object+)中读取命名的导出方法(named exports) typeof fs.readFileSync === "function"; typeof readFileSync === "function";
须要让 Babel 不解析这些模块符号,从而让 webpack 可使用它们。能够经过设置以下配置到 .babelrc
{ "presets": [ ["@babel/preset-env", {"modules": false}], ] }
2.只在production环境下才会用到的工具(在development时应避免)
UglifyJsPlugin
ExtractTextPlugin
[hash]
/[chunkhash]
AggressiveSplittingPlugin
AggressiveMergingPlugin
ModuleConcatenationPlugin