文章目录
在上一篇中带大家通过一个小
demo
,简单的体验了一下使用webpack
打包的流程。这一篇中将继续深入讲解webpack
的具体概念和用法。
一. webpack工作机制
我自知没有官方大大总结的细致,就先附上官方中文文档地址🐶:
其实我后续的讲解也是遵循官方文档的,治学严谨 ~ 哈哈。先来看官方大大对webpack
的定义:
本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。 当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。
依赖关系图就类似于上图。我们之前的例子中只写了一个模块math.js
,其实webpack
真正强大的地方在于它对于模块的定义非常宽泛。比如我们实际项目中会存在的:
- JS(ES5)模板文件;
- CSS样式文件;
- PNG,JPG,GIF等格式的图片文件;
或者更高级的比如:
- JS(ES6)文件;
- CSS的预处理文件,比如:Sass / Less / Stylus;
- TypeScript文件;
- .jsx、.vue等后缀的文件;
- …
这些文件格式在webpack
中都被视作模块,并且webpack
会自动帮我们分析和处理它们之间的依赖关系,并根据我们指定的某个模块(即接下来的入口 entry
),来作为构建其内部依赖图的开始。之后每个依赖项随即被处理,最后打包输出到称之为 bundles
的文件中。
了解过
webpack
的工作机制后,我们就可以来系统的上手体验啦 ~ 先来跟我创建配置文件webpack.config.js
,之后再逐一了解各项配置。
二. 创建配置文件 —— webpack.config.js
类似于npm
的有关配置都会放在package.json
文件中,webpack
也有自己对应的配置文件 —— webpack.config.js
。 当我们需要配置某些信息的时候,就需要我们自己在项目根目录下手动创建该文件。
例子还是沿用上一篇中的,强烈建议先去看上一篇,效果更佳 ~ 当然,后续的讲解我也会回忆上一篇中对应的操作,接着看本篇也无妨。
【 webpack系列(二)】一个基于CommonJS模块化方案的小demo —— 带你简单体验 webpack 打包流程
新建完webpack.config.js
文件,我们现在的项目目录结构为:
现在我们在webpack.config.js
文件中先添加好如下的代码格式,便于后续配置信息的添加:
module.exports = {
// 配置信息
}
这个格式是不是很眼熟 ? 没错,他就是CommonJS
模块化方案中的模块导出格式。由此也印证了webpack
本身也是遵循CommonJS
这个规范的。
webpack
本身是高度可配置的,配置项都是基于以下四个核心概念:
- 入口(entry)
- 出口(output)
- 加载器(loader)
- 插件(plugins)
三. 入口(entry) + 出口(output)
入口(entry)和出口(output)往往是相对应的,具体的属性作用和可配置项如下:
- 入口
entry
属性:
来指定内部依赖图的起点,默认值为./src
; - 出口
output
属性:- path —— 告诉
webpack
在哪里输出它所创建的bundles
,默认值为./dist
; - filename —— 如何命名这些文件;
- path —— 告诉
先回忆一哈我们上次打包时用到的命令:
// webpack entry output
webpack ./src/main.js ./dist/main.js
这里我们其实就是在命令中指定了entry
和output
属性。之后我们的实际项目中要打包的模块如果每次都这样指定出入口,那就太麻烦啦!我们可以把出入口的配置写在webpack.config.js
文件里。
module.exports = {
entry:__dirname + '/src/main.js',
output:{
path:__dirname + '/dist',
filename:'bundle.js'
}
}
我们之前的例子就可以这样配置(__dirname
指代当前文件),这里我配置的文件名称是bundle.js
,这个不影响,之后我们在执行打包命令的时候,就只用敲webpack
关键字即可。最后达到的效果如图:
webpack
四. 加载器(loader)
4.1 loader 概述
我们要清楚的是webpack强大的文件转换能力其实是loader具有的,webpack本身只能理解JavaScript
。 在 webpack 的配置中 loader 有两个属性:
- test —— 需要被转换的文件类型(使用正则表达式检索文件后缀)
- use —— 需要用到的loader列表(数组)
module.exports = {
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
},
};
所以loader本身也有细分,转换不同类型的模块文件需要安装不同的loader工具。 比如:
- css-loader —— 加载css文件
- style-loader —— 把加载出来的css文件嵌入到文档中
- file-loader
- url-loader
- …
4.2 css文件处理
4.2.1 传统css文件引入
接下来就以css-loader
为例,来看看具体loader怎么配置和使用:
我们传统的做法是在一个单独的CSS
文件中写样式代码,然后link
导入。这里我们就简单一点,在src
文件夹内新建一个normal.css
文件:
写上一段样式代码:
html,body {
margin: 0;
padding: 0;
background-color: skyblue;
}
之后在index.html
文件中引入:
<link rel="stylesheet" href="./src/normal.css">
来看看效果 ~ 这一抹天空蓝真让人心旷神怡 🐶~
4.2.2 切换模块化开发方案
使用webpack打包项目的前提是项目采用模块化开发方案。做法也很简单:
- 注释掉
index.js
文件里之前的link
引入标签; - 在
main.js
文件中require
导入normal.css
模块;
require('./normal.css');
为什么要在main.js
文件中导入normal.css
模块呢?是因为我们上边配置入口entry
属性时,把main.js
设置成了根依赖文件,其他的模块都应该跟它有直接或间接的依赖关系。
4.2.3 css-loader + style-loader
这一步是局部安装loader(仅限本次项目中使用),要想正确应用CSS文件需要安装两个loader:
- css-loader —— 只负责加载css文件
- style-loader —— 把加载出来的css文件嵌入到文档中
npm install --save-dev css-loader
npm install --save-dev style-loader
执行完毕你会发现之前执行打包操作时自动添加的node_modules
文件夹中多了两个文件夹css-loader
和style-loader
,之后我们安装的其他loader也会在这里。
仅仅是安装好还是不可以使用的,我们还需要去webpack.config.js
文件里配置:
module: {
rules: [
{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
],
}
之后再重新执行打包命令,在浏览器中就可以再次看到那一抹天蓝色啦 ~
❀ 拓展一下❀
webpack读取loader的时候,是按照从右到左的顺序读取。
按照正常逻辑来说,肯定是先执行css-loader,等它把css文件读取出来,才能让style-loader把css文件嵌入到文档中。但是书写的时候要注意,从右到左依次列出顺序执行的loader工具。
4.3 图片文件处理
接下来我们再来看webpack中对图片文件的处理。我们的小项目也越来越成型了,哈哈。那就先整理一下项目目录结构吧,看起来稍专业一些:
别忘了修改之前main.js
中的模块导入路径和webpack.config.js
中的出入口路径。这里我在images
文件夹里放了两张图片:一张大于8k,一张小于8k:
(图片请自理)
然后把小的那一张设置成我们刚才的背景图片:
html,body {
margin: 0;
padding: 0;
background-color: skyblue;
background-image: url('../images/l-vAnCrown.png');
}
然后重新打包,注意这里会出错:
4.3.1 url-loader
因为我们是通过url
的方式导入的图片,处理url
资源需要安装url-loader
,所以我们就去安装并配置:
(其实有关loader的详细安装和配置,建议你们去官网直接搜索文档)
当然你们也可以看我表演哈 🐶 ~
npm install --save-dev url-loader
从官网文档中截取如下url-loader
的具体配置,插入到配置文件的rules
数组中即可:
{
test: /\.(png|jpg|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 8192,
},
},
],
}
分析一哈这段代码,我们能看懂的有:
- 文件类型的正则表达式里检索的是
png / jpg / gif
三种图片格式; - 对图片大小有限制,最大不超过8192k;
(所以图片才特意找了两张,一大一小,都测试一下 ~ )
现在我们再重新打包项目,切到浏览器看看:
(哇偶,这也太可了 ~ 哈哈 )
4.3.2 图片base64格式
这时候你打开浏览器的控制台,会看到我们样式这里的图片url会被解析成base64格式,并不是我们的图片路径。
图片的 base64 编码就是可以将一张图片数据编码成一串字符串,使用该字符串代替图像地址。 是项目中图片分辨率较小的icons的主要实现方式。不建议大于300KB的图片做base64格式转换。
我们自己也可以利用一些图片base64的转换工具,先把图片转换成base64格式,然后写在css样式中。这里就以刚才准备的另一张较大的图片为例:
(转换工具直接百度即可)
操作也很简单,在左边上传你要转换的图片,右边就会出现转换好的编码,直接复制即可食用。
我们直接在index.html的body标签中写一个img标签,把上边代码全选复制粘到url中,这个代码好长好长的,所以说base64格式最好还是用来转换一些小图片。
❀ 拓展一下❀
我们老师写的一篇Vue框架中使用base64做图片上传的博客,感兴趣的小伙伴可以去刷刷访问量哈:
vue中使用base64编码上传文件或者图片,以及base64编码的图片在img标签中使用
4.3.3 file-loader
刚才的base64格式只是个小插曲。我们继续来看刚才的图片问题:之前用的是那张小图(小于8192k)做的背景,如果换成大的那张呢 ? 肯定会报错,代码中有限制:
这里报错信息中提示我们找不到file-loader,这个就是用来处理大于8192k的文件资源的。现在来安装一下这个loader:
npm install --save-dev file-loader
再来打包一下,会发现file-loader把这张图片打包到了dist文件中:
这样就会造成图片引入的路径出问题,现在的页面上并不能正确显示这张图片。解决这个问题,我们需要去安装一个插件 —— HtmlWebpackPlugin,后续章节有详细介绍。点我直达 👈
五. 插件(plugins)
5.1 认识plugins
plugin是插件的意思,这个概念在很多软件或框架中都存在,通常是用于对某个软件或框架的现有功能进行扩展。
webpack中的插件,就是对webpack现有功能的各种扩展,比如打包优化,文件压缩等等。
loader和plugin区别:
- loader主要用于转换某些类型的模块,它是一个转换器;
- plugin是插件,它是对webpack本身的扩展,是一个扩展器;
plugins的使用其实和loader很类似,也是先通过npm安装(某些webpack已经内置的插件不需要安装),之后在webpack.config.js中添加配置。
5.2 内置插件 —— BannerPlugin
先来看一个内置插件:为打包的文件添加版权声明 —— BannerPlugin。
内置插件无需安装,直接定义在webpack本身,所以这部分插件使用前需要先声明webpack常量。具体配置如下:
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.BannerPlugin('最终版权归zevin所有')
]
};
webpack中想要使用一个插件,你只需要 require()
它,然后在 plugins
数组中通过new
关键字新建该插件实例来使用。多次创建实例,即可多次使用插件。
上述配置完成后,重新打包去看bundle.js
:
5.3 npm安装插件 —— HtmlWebpackPlugin
对应的继续来看一个需要npm安装的插件 —— HtmlWebpackPlugin。使用之前先来明确一个问题:目前,我们的index.html
文件是存放在项目的根目录下的:
-
我们知道,在真实发布项目时,发布的是
dist
文件夹中的内容,但是dist
文件夹中如果没有index.html
文件,那么打包的js等文件也就没有意义了。 -
所以,我们需要将
index.html
文件打包到dist
文件夹中,这个时候就可以使用HtmlWebpackPlugin
插件。
5.3.1 HtmlWebpackPlugin插件作用
- 自动生成一个
index.html
文件(可以指定模板来生成); - 将打包的js文件,自动通过
script
标签插入到body
中;
5.3.2 HtmlWebpackPlugin的安装与配置
安装命令如下:
npm install html-webpack-plugin --save-dev
添加如下配置:
const HtmlWebpackPlugin = require('html-webpack-plugin');
plugins: [
new HtmlWebpackPlugin({
template:'index.html'
})
]
这里的template
表示根据什么模板来生成index.html
,就用我们之前的那个index.html
作为模板即可。
之后重新打包,在dist
文件夹下就会出现一个插件生成的index.html
文件,把这个文件用浏览器打开:
你会发现之前遗留的那个问题:使用file-loader
打包出来的那张图片,因为引入路径的问题不能正确显示。现在也恢复正常啦~🐶
到这里就算是对webpack
有了一个简单的全面了解,赶紧去看Vue框架吧… 这周耗在webpack
基础上的时间太长了。。。