1、 本地项目没有全局安装webpack,在项目上想要调用webpack可以使用命令
npx webpack
效果等同于 全局安装webpack之后,再执行 webpack
通常会在package.json中配置script,如
script: {
"build": "webpack"
}
在命令行输入npm run build也会生效,这是因为npm命令类似npm,会优先在当前目录里查找webpack
2、 可以使用--config 指定webpack的配置文件,默认是webpack.config.js
webpack --config webpack.dev.js
3、entry: './index.js'是对entry: { main: './index.js' }的简写
4、mode: 'development' | 'production' 用来区分打包策略,development是开发环境模式,代码不会压缩
5、module用来配置各种资源(如 css jpg等)的打包策略
module: {
rules: [{
test: /\.jpg$/,
user: 'file-loader'
}]
}
每个loader都有自己的配置下,去官网查看对应loader即可
6、file-loader负责将资源复制到output指定的文件夹下,并且将资源重命名等操作 url-loader类似file-loader,但是他还可以将文件转换为base64
7、css-loader会帮助梳理css,多个css文件会被他梳理成一个css
8、babel-loader 功能主要是建立webpack和babel之间做打通,本身不会对语法做处理
babel-core babel的核心,可以将代码转换成AST树,再将AST树转成其他形式
babel-preset-env 包含各版本如ES6 ES7的语法规则,babel根据这些规则来输出
babel-polyfill js垫片,打包后会增加打包文件的体积
业务代码打包:
入口文件引入polyfill import "@/babel/polyfill";
{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
presets:[
targets: { chrome: "67" },
["@babel/preset-env", { useBuiltIns: "usage" }]
]
}
}
库代码打包:
options: {
plugins: [
["@babel/plugin-transform-runtime",{
"corejs":2, //需要安装runtime-corejs2
"helpers":true,
"regenerator":true,
"useESModules":false
}]
]
}
babel/polyfill是全局引入的形式做垫片,这样会污染全局环境
plugin-transform-runtime则是以闭包的形式
options内容过多的话,和已将里面内容提取出来放到 .babelrc 或者 babel.config.js
更多配置查看babel官网
9、treeShaking
development: webpack设置 optimization: { usedExports: true }, 同时在package配置:
sideEffects: ["@babel/polly-fill", "*.css"] // 对没有export的文件不做shaking
实际打包结果不会被删除,但是会加上注释,只有production才会被真正删除
production: 可以删除usedExports: true
10、code spliting
同步代码 异步代码分割可以参考这里的配置:webpack.js.org/plugins/spl…
optimization: {
splitChunks: {
chunks: "all",
minSize: 1024,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10,
name (module, chunks, cacheGroupKey) {
console.log(module.identifier())
const moduleFileName = module
.identifier()
.split(/[/\\]/)
.pop()
.replace(/\..*$/, '');
const allChunksNames = chunks.map((item) => item.name).join('~');
return `${cacheGroupKey}-${allChunksNames}-${moduleFileName}`;
}
},
default: {
minChunks: 1,
priority: -20
}
}
},
}
同步代码分割 利用浏览器缓存 用来提升二次请求之后的加载时间
异步代码 配合 preFetching 可以提升首屏加载速度,preFetching:
import(/* webpackPrefetch: true */ 'lodash').then((lodash) => {
// code: lodash.join(....)
})
11、打包分析 analyse 见官网
12、css提取
使用 MiniCssExtractPlugin配合optimization使用:
optimization: {
splitChunks: {
cacheGroups: {
styles: {
name: "styles",
type: "css/mini-extract",
chunks: "all",
enforce: true,
},
},
}
}
13、webpack 环境变量
a、package.json:不传值默认为true,此时production=true
script: { "build": "webpack --env.production" }
webpack.config.js:
module.export = (env) => {
if (env && env.production) {
return merge(baseConfig, productionConfig)
} else {
return merge(baseConfig, developmentConfig)
}
}
b、也可以
script: { "build": "webpack --env production" }
webpack.config.js:
module.export = (production) => {
if (production) {
return merge(baseConfig, productionConfig)
} else {
return merge(baseConfig, developmentConfig)
}
}
c、赋值:
script: { "build": "webpack --env.production=abc" }
webpack.config.js:
module.export = (env) => {
if (env && env.production === 'abc') {
return merge(baseConfig, productionConfig)
} else {
return merge(baseConfig, developmentConfig)
}
}
14、打包library
在config文件使用externals指定不需要一起打入的包:
externals: "lodash"
externals: ["lodash", "dayjs"]
output指定输出类型和导出名:
output: {
library: "myLibrary",
libraryTarget: "umd"
}
打包完成后,修改package.json:
main: "./dist/bundle.js" // 你的打包结果
npm adduser npm publish即可发布npm包
15、webpack打包速度优化
a、尽可能使用较新版本的node npm yarn
b、尽量减少使用loader
c、尽量使用官方推荐的plguin,保证性能
d、不要过多使用 resolve.extensions resolve.mainFiles resolve.alias 处理文件扩展
e、开发环境 借助 webpack.DllPlugin webpack.DllRefrencePlugin AddAssetsHtmlWebpackPlugin 提前抽离第三方模块,减少对第三方模块重复打包
f、合理配置source-map
g、使用stats analyse做打包分析
16、自定义loader:
myLoader.js:
module.export = function (source) {
this.query // loader options
return source + '/* myLoader */'
}
webpack.config.js:
module: {
rules: [{
test: /\.js$/
use: [{
loader: path.join(__dirname, 'myLoader.js'),
options: { name: 'asd' }
}]
}]
}