分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 运营维护

webpack务虚扫盲

发布时间:2023-09-06 02:01责任编辑:沈小雨关键词:webpack

打包工具的角色

所谓打包工具在web开发中主要解决的问题是:

(1)文件依赖管理。毕竟现在都是模块化开发,打包工具首先就是要梳理文件之间的依赖关系。

(2)资源加载管理。web本质就是html、js和css的文件组合,文件的加载顺序(先后时机)和文件的加载数量(合并、嵌入、拆分)也是打包工具重点要解决的问题。

(3)效率与优化管理。提高开发效率,即写最少的代码,做最好的效果展示;尽可能的使用工具,减少机械coding和优化页面效果,这个是考验打包工具是否具备魅力的点。

打包工具的结构

由上图可以推出,打包工具的结构应该是tool+plugins的结构。tool提供基础能力,即文件依赖管理和资源加载管理;在此基础上通过一系列的plugins来丰富打包工具的能力。plugins类似互联网+的概念,文件经plugins处理之后,具备了web渲染中的某种优势。

为什么使用webpack?

决定打包工具能走多远的是plugins的丰富程度,而webpack目前恰恰是最丰富的,我这里对比了一下fis与webpack在npm包上数据,看完就知道为什么要使用webpack了。

webpack的工作原理

webpack处理文件的过程可以分为两个维度:文件间的关系和文件的内容。文件间的关系处理,主要是通过文件和模块标记方法来实现;文件内容的处理主要通过loaders和plugins来处理。

1.文件内容处理

在webpack的世界里,js是一等公民,是处理的入口,其他资源都是在js中通过类似require的方式引入。webpack虽然支持命令行操作,但是一般将配置写在webpack.conf.js文件中,文件内容是一个配置对象,基本配置项是:entry、ouput、module、plugins属性。

entry与output

这里引入了一个chunk的概念,chunk表示一个文件,默认情况下webpack的输入是一个入口文件,输出也是一个文件,这个文件就是一个chunk,chunkId就是产出时给每个文件一个唯一标识id,chunkhash就是文件内容的md5值,name就是在entry中指定的key值。

1
2
3
4
5
6
7
8
9
module.exports = {
entry: {
collection:‘./src/main.js‘// collection为chunk的名字,chunk的入口文件是main.js
},
output: {
path:‘./dist/js‘,
filename:‘[name].[chunkhash].js‘// 输出到dist/js目录下,以collection+chunk内容的md5值作为输出的文件名
}
};  

输出:

module

moudle对应loader(加载器 )的配置,主要对指定类型的文件进行操作,举个例子:js类型的文件和css文件需要不同的loader来处理。最常用的加载器是eslint-loader和babel-loader。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
entry: {
collection:‘./src/main.js‘// collection为chunk的名字,chunk的入口文件是main.js
},
output: {
path:‘./dist/js‘,
filename:‘[name].[chunkhash].js‘// 输出到dist/js目录下,以collection+chunk内容的md5值作为输出的文件名
}
module: {
rules: [// rules为数组,保存每个加载器的配置
      {
        test: /\.js$/,// test属性必须配置,值为正则表达式,用于匹配文件
        loader:‘babel-loader?fakeoption=true!eslint-loader‘,// loader属性必须配置,值为字符串,对于匹配的文件使用babel-loader和eslint-loader处理,处理顺序从右向左,先eslint-loader,后babel-loader,loader之间用!隔开,loader与options用?隔开
        exclude: /node_module/,// 对于匹配的文件进行过滤,排除node_module目录下的文件
        include:‘./src‘// 指定匹配文件的范围
      }
    ] 
}
};   

其中,loader的options也可以单独使用options属性来配置

1
2
3
4
5
6
7
8
9
rules: [
{
test: /\.js$/,
loader:‘babel-loader‘,
options: {
fakeoption:true
}
}
]  

另外通常babel-loader的配置项可以写在根目录下的.babelrc文件中

1
2
3
4
5
{
"presets": ["stage-2"],
"plugins": ["transform-runtime"]
}

plugins

plugins用于扩展webpack的功能,相比着loader更加灵活,不用指定文件类型。常用的plugins有三个,html-webpack-plugin、commonChunkPlugin和ExtractTextPlugin。

(1)html-webpack-plugin:生成入口html文件,由于webpack输出的js文件需要插入到html文件,以构成web入口;该插件默认有一个html文件模板,但是一般情况下需要为其指定一个html文件作为模板,webpack打包输出的js文件会插入到body结束标签之前。
1
2
3
4
5
6
7
8
9
10
11
varHtmlwebpackPlugin = require(‘html-webpack-plugin‘);
module.exports = {
...
plugins: [
newHtmlwebpackPlugin({<br>       filename:‘collection.html‘,// 入口html文件名
template:‘./src/index.html‘// 入口html文件模板
})
]
...
};
最终输出的入口文件如下图,生成的入口文件是在模板文件的基础上插入了打包后的js引用标签。
(2)commonChunkPlugin:主要提取公共业务代码与第三方类库代码
在介绍entry的时候,提到了chunk的概念,chunk指的就是一个代码块,即一个js文件。默认的情况下webpack只产生entry中指定的代码块,chunk的个数和entry中的key值个数相等,即单入口的情况下,默认只产出一个chunk。但是我们通常希望将入口之间的通用代码和第三方类库的代码提取出来,单独作为一个js文件来引用,第三方的文件一般很少变动,可以利用缓存机制把相关内容缓存起来,通用代码则可以避免重复加载。
commonChunkPlugin的处理级别是chunk级别,通过指定chunks(输入的文件)+minChunks(提取过滤器:一般是被引用的次数)+name(输出的文件名)来完成操作。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
module.exports = {
...
plugins: [
// 把通过npm包引用的第三方类库从入口文件中提取出来
newwebpack.optimize.CommonsChunkPlugin({
name:‘vendor‘,
minChunks:function(module, count) {
// 指定范围是js文件来自node_modules
return(module.resource && /\.js$/.test(module.resource) &&module.resource.indexOf(path.join(__dirname,‘../node_modules‘)) === 0);
}
}),
// 把webpack的module管理相关基础代码从vendor中提取到manifest
newwebpack.optimize.CommonsChunkPlugin({
name:‘manifest‘,
chunks: [‘vendor‘]
})
]
...
};
(3)ExtractTextPlugin:提取css片段到单独css文件

js是一等公民,webpack默认不产出css文件,产出css文件需要依赖ExtractTextPlugin插件来完成。

1
2
3
4
5
6
7
8
9
10
module.exports = {
...
plugins: [
// 把css片段从入口js文件中提取到对应入口名的css文件中
newExtractTextPlugin({
filename:‘./dist/static/css/[name].[contenthash].css‘
}),
]
...
};

  

2.文件间的关系处理

理清这个过程得倒推,先看一下经webpack处理后的js文件,下面的例子中主要涉及3个产出文件,manifest是webpack的module管理代码,vendor是第三方类库文件,collection是入口文件,加载的顺序是manifest-》vendor-》collection。

查看三个文件的内容可知:

vendor和collection的内容都是一个函数,类似jsonp请求回来的返回值。下面分别是vendor和collection中的代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
webpackJsonp([0],[// chunkid为0
/* 0 */
/***/(function(module, exports, __webpack_require__) {
...
/***/}),
/* 1 */
/***/(function(module, exports) {
...
/* 2 */
...
/* 9 */
/***/(function(module, exports, __webpack_require__) {
...
/***/}),
/* 10 */,// 此处moduleid=10的模块为空
/* 11 */
/***/(function(module, exports) {
...
/***/}),
...
]);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
webpackJsonp([1],[// chunkid为1
/* 0 */,// moduleid为0-9的模块均为空
/* 1 */,
/* 2 */,
/* 3 */,
/* 4 */,
/* 5 */,
/* 6 */,
/* 7 */,
/* 8 */,
/* 9 */,
/* 10 */
/***/(function(module, __webpack_exports__, __webpack_require__) {
...
};
/***/

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved