打包工具的角色
所谓打包工具在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 2 3 4 5 6 7 8 9 10 11 | var HtmlwebpackPlugin = require( ‘html-webpack-plugin‘ ); module.exports = {
...
plugins: [
new HtmlwebpackPlugin({<br> filename: ‘collection.html‘ , // 入口html文件名
template: ‘./src/index.html‘ // 入口html文件模板
})
]
... }; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | module.exports = {
...
plugins: [
// 把通过npm包引用的第三方类库从入口文件中提取出来
new webpack.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
new webpack.optimize.CommonsChunkPlugin({
name: ‘manifest‘ ,
chunks: [ ‘vendor‘ ]
})
]
... }; |
js是一等公民,webpack默认不产出css文件,产出css文件需要依赖ExtractTextPlugin插件来完成。
1 2 3 4 5 6 7 8 9 10 | module.exports = {
...
plugins: [
// 把css片段从入口js文件中提取到对应入口名的css文件中
new ExtractTextPlugin({
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 |