webpack 学习笔记2(进阶)
1. webpack的 watch模式
执行 npx webpack --mode=development --watch 命令的话,就是执行一次编译多次。只要你修改了相关的文件,保存后就会重新触发编译。这个比较适合多次反复调试的情况。
2. 使用Webpack-dev-server监听代码修改的同时,自动刷新网页。
npm install webpack-dev-server -D #@4.15.1
XXXX
plugins:[
XXX
],
devServer:{
static: dist //dist文件夹里的文件发生变化,就会刷新浏览器
}
运行的时候,使用如下指令:npx webpack-dev-server --mode=development
默认的网址为localhost:8080
然后代码变动,保存后,如果对应的页面有变动,会自动刷新。
3.资源模块(asset module)
在webpack5中,一般不在使用file-loader/url-loader/raw-loader,而是使用asset/resource、asset/inline、asset/source、asset去处理,不需要任何插件。
asset/resource发送一个单独的文件并导出 URL。之前通过使用file-loader实现。asset/inline导出一个资源的 data URI。之前通过使用url-loader实现。asset/source导出资源的源代码。之前通过使用raw-loader实现。asset在导出一个 data URI 和发送一个单独的文件之间自动选择。之前通过使用url-loader,并且配置资源体积限制实现。
【type : 'asset/resource'】为例。在配置文件中,直接在module的rules中配置:
module: {
rules: [
XXX
{
test: /\.(png|svg|jpg|ico|gif|bmp|pdf|jpe?g)$/,
type: 'asset/resource',
generator: {//指定输出到img文件夹。也可以在output中使用配置assetModuleFilename项的方式。
filename: 'img/[name]-[hash][ext][query]'
}
},
]
},
plugins:[
XXXXf
在js代码中
import cil_notes_img from './img/cil-notes.svg';
<img height='100%' src={cil_notes_img} />
为了方便,其实使用asset配置,让webpack自动选择独立文件或者内联的方式更加
【type : 'asset'】为例。在配置文件中,直接在module的rules中配置:
{
test: /\.(png|svg|jpg|ico|gif|bmp|pdf|jpe?g)$/,
type: 'asset',//自行选择独立文件or内联
generator: {//指定输出到img文件夹。也可以在output中使用配置assetModuleFilename项的方式。
filename: 'img/[name]-[hash][ext][query]'
},
parser: {
dataUrlCondition: {
maxSize: 8 * 1024 // 8kb以下内联;8k以上独立文件。
}
}
},
在css中使用图片正常使用就行,如下:
.app-header{
background-image: url(./img/cil-notes.svg);//没有什么特殊处理
margin-top: 24px;
#4 loader是什么
可以通过loader来引入其他类型的文件。loader可以让webpack去处理其他类型的文件,并且将他们转化为有效的模块,来供应用程序使用
#5 代码分离,将公共代码提取出来
一般有3中方法
(1)入口依赖
(2)SplitChunksPlugin实现分离【常用,简单配置】
(3)动态导入。【需要的时候再从服务器下载导入】
(4)还有一种预加载方式。【网络空闲的时候,从服务器下载导入】
具体可以参考:https://www.webpackjs.com/guides/code-splitting/;https://www.webpackjs.com/plugins/split-chunks-plugin#root
其中第二种方法比较常用且简单,只需要在optimization中如下配置
output: { filXXMD5 paXX件夹 clXX文件 }, optimization: { splitChunks: {//用webpack内置的功能提取公共代码。默认参数仅打包node_mudule里的公共代码,如有特殊情况(例如打包我们自己的公共代码),可以自行参看文档配置(下面有一例)。 chunks: 'all', }, //splitChunks: {//这里的例子是将node_module和data中用到的公共代码提取出来。 // cacheGroups: { // vendor: { // test: /([\\/]node_modules[\\/]|[\\/]data[\\/])/, // name: 'vendors',//如果指定了name,生成一个大的公共包;如果不指定name,根据默认配置规则打碎。 // chunks: 'all', // }, // }, //}, }, module: { rules: [ {XXX
生成很多公共js,非公共的js会很小。
#6 懒加载
上一条的第三种方法动态导入可以实现懒加载。https://www.webpackjs.com/guides/lazy-loading/
所谓懒加载就是网页执行的时候,如果没有使用到某一个js文件,则不会去服务器下载改js文件。如果点击一个按钮,触发一个行为,而该行为需要用到一个js文件,此时会再去服务器下载此js文件。
# output.publicPath的配置
此选项指定在浏览器中所引用的公开 URL,在资源托管的情况下会用到,例如cdn
module.exports = {
//...
output: {
path: path.resolve(__dirname, 'public/assets'),
publicPath: 'https://cdn.example.com/assets/',
},
};
此时html引用js模块的时候,形如:
XXXX<script defer="defer" src="https://cdn.example.com/assets/155.b525f922d19f1617f8f3.js"></script> <script defer="defer" src="https://cdn.example.com/assets/526.b52887bdb1d3497c31ed.js"></script> <script defer="defer" src="https://cdn.example.com/assets/844.2554505742109c463eb5.js"></script> <script defer="defer" src="https://cdn.example.com/assets/richang_add.bd6fafd79d3c096a13d3.js"></script></body> </html>
# 生产环境和开放环境的拆分
npx webpack --env production/development
env参数如何获取呢,这就需要对webapck.config.js的结构做调整,具体如下
原exports代码为:
module.exports = {
entry: {
"login":"./data/login.js"},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'build2'),
clean: true//自动删除之前的文件
}
};
现在改为:
module.exports = (env)=>{
console.log(env);
return {
entry: {
"login":"./data/login.js"},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'build2'),
clean: true//自动删除之前的文件
}
};
}
这样可以通过env里的参数来动态判断环境。配置devltool和mode如下:
output: {
filename: '[name].[chunkhash].js',//模块名字+MD5
path: path.resolve(__dirname, dist),//生成到目标文件夹
},
optimization: {
},
mode: env.production ? "production" : "development",//根据env参数进行配置
devtool: env.production ? false:'inline-source-map',//增加一个map文件,便于定位异常or错误位置。生产环境不需要配置此项。
module: {
rules: [
#node-env
我们经常在别人代码里node-env,他的功能跟上一条的env类似,也可以通过它传入一些变量。
//你可以使用 --node-env 选项来设置 process.env.NODE_ENV: npx webpack --node-env production # process.env.NODE_ENV = 'production'
config.js里这样使用:
mode: process.env.NODE_ENV,
#webpack中hash,chunkhash,contenthash有什么区别
在webpack中有三种hash可以配置,hash,chunkhash,contenthash 。为了正确使用这三种配置,首先我们需要搞清楚他们的区别是什么,以及适用的不同场景。
hash :表示所有文件哈希值相同,如果任意文件内容发生变化,则再次打包后,所有哈希值均改变且相同。即当任意module发生改变时,所有bundle的hash都改变且相同。
当有多个chunk,形成多个bundle时,如果只有一个chunk和bundle内容发生改变,会导致其他所有的bundle的哈希值都发生改变,因为大家共用一个hash,这个时候chunkhash的作用就体现出来了。
chunkhash :根据不同的入口文(Entry)进行依赖文件解析,构建对应的chunk,生成对应的哈希值。
contenthash :在打包时,我们会在js文件中导入CSS文件,因为他们是同一个入口文件,我们只改了JS代码,但是它的CSS在抽离生成CSS文件时hash也会跟着变,这个时候就需要contenthash来解决。
总结:hash所有文件的哈希值都相同;chunkhash根据不同的入口文件进行依赖文件解析,构建对应的chunk,生成对应的哈希值;contenthash计算与文件内容本身有关,主要用于CSS抽离CSS文件。
所以js稳健用chunkhash,css文件用contenthash
形如:
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
mode: "production",
entry: {
index: "./src/index.js",
chunk1: "./src/chunk1.js",
},
output: {
filename: "[name].[chunkhash].js",
},
module: {
rules: [
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, "css-loader"],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css", // chunkhash => contenthash
}),
],
};
以上描述完全拷贝自:https://zhuanlan.zhihu.com/p/416294253
#自定义的config.js文件
不适用默认的webpack.config.js配置文件,而是使用自定义名字的文件,例如webpack.config.dev.js
使用命令:npx webpack -c webpack.config.dev.js //-c是--config的简写

浙公网安备 33010602011771号