文章开头第一句加入:本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
1. 概念
js应用程序的静态打包工具,从入口出发构建依赖图,将模块组合打包成一个或多个 bundles,它们均为静态资源,用于展示你的内容。
1.1 四个核心概念
- 入口entry
指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
- 输出output
告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。生成文件默认放置在 ./dist 文件夹中。
- 加载器loader
webpack默认只支持JavaScript 和 JSON 文件。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 [模块]
- 插件plugin
插件则可以用于执行范围更广的任务。包括:打包压缩,资源管理等。
2 常见的配置
2.1 配置文件
默认的配置文件为webpack.config.js;当为其他名称时,需要指定名称。
eg: npx webpack --config ./webapck.dev.config.js
2.2 devServer
用来实现自动化(自动编译、打包、刷新浏览器),只会在内存中编译打包,不会有任何文件输出 不用devServer时,我们 修改源代码-> npm run build 打包 -> 刷新页面 ->最新结果 而用了devServer后, 修改源代码 -> 最新结果
2.3 打包htmL/css
html-webpack-plugin 在输出目录中生成index.html;ClearWebpackPlugin每次打包前清空dist目录。 css样式文件使用css-loader和style-loader,less文件使用less-loader、css-loader和style-loader。postcss-loader css兼容,加厂商前缀。loader的读取顺序从后向前。
plugins: {
new HtmlWebpackPlugin({
template: './src/index.html' //以此为模板
}),
new ClearWebpackPlugin() //每次打包前删除dist目录
},
module:{
rules:[
{
test:/\.less$/,
use:['style-loader',
{
loader: "css-loader",
options: {
modules: true,//模块化
}
},
{ //css加厂商前缀
loader:'postcss-loader',
options:{ plugins:[require('autoprefixer')] }
},
'less-loader']
}
]
}
2.4 打包图片
url-loader和file-loader url-loader类似file-loader,但可以返回base64编码 如果图片大,用url-loader解析成的base64就大,打包出的bundle.js体积就大,加载js时间就长;可以用file-loader单独生成图片文件。 如果图片小,用file-loader就打发了一次http请求;不如用url-loader解析成base64编码。
{
test: /\.(jpg|png|gif)/,
loader: "url-loader",
options: {
// 图片大于8kb,就会被base64处理
limit: 8 * 1024,
fallback: 'file-loader', //目标文件的大小超过限制备用加载
}
}
2.5 提取css、压缩css
样式文件打包后会默认和js文件一起输出。 通过miniCssExtractPlugin 插件可将css提取出来成单独文件。
test: /\.css$/,
use: [MiniCssExtractPlugin.loader,'css-loader']
CssMinimizerPlugin或optimizeCssAssetsWebpackPlugin用来压缩css
2.6 js兼容、js压缩
js兼容,就是把es6转换成es5 主要用到babel-loader(babel-webpack),@babel/preser-env(es6->es5),polyfill(promise,map等es5没有实现的es6语法)
loader: "babel-loader",
options: {
preset: [['@babel/preset-env',{
useBuiltIns: 'usage' //按需引用polyfill
}]]
}
js压缩 uglifyPlugin 生成模式自动压缩
2.7 热更新
改东西时,不用刷新页面,代码即生效 借助webpack.HotModuleReplacementPlugin(),devServer开启hot。 js中实现热更新,只更新指定js模块
// 指定模块发生更新的时候进行HRM
if(module.hot){
module.hot.accept('./util.js',()=>{
console.log("util.js更新了")
})
}
css,vue,react热更新即生效,无需指定模块。因为style-loader,vue-loader,babael-preset分别内部实现了这块逻辑。