前端最常用的打包工具webpack(二)-引入资源
这是重新学习webpack的第二篇文章,之前我也写过一篇关于webpack的文章。问题是过去快半年了,我已经将webpack忘得差不多,回头一看那篇文章完全是一头雾水,也没有办法,那个时候我才刚刚开始写前端方面的博客,对于知识梳理、文字表达都有一些欠缺,啪啪啪一下扔出来几千字,全是重点,没有任何过渡性的语言,看个一会就没什么兴趣。
综上所述,本次决定给webpack写一个比较详细的系列文章,目的是如果我半年后又忘记了webpack的具体内容,再来翻阅文章,不会像这次一样一头雾水。
前景提要:前端最常用的打包工具webpack(一)-初识篇。
在前一篇文章中,我们已经可以打包js文件,但是在一个工程项目中,我们不仅有js文件,还有其它类型的文件,比如.css
、.scss
文件,而这些文件跟js文件不同,如果使用webpack的默认打包,则无法进行识别这些文件,从而报错。
我们在项目根目录下创建一个src
文件夹,然后在里面创建一个style.css
文件,写上如下代码
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
接着我们在main.js
中引入:
import "./src/style.css"; // 引入样式文件
function add(x, y) {
return x + y;
}
console.log(add(1, 2));
这种引入方式在使用前端框架时会经常用到,那么这个时候我们再运行一次打包指令:
webpack ./main.js -o ./build/ --mode=development
可以看到报错了,提示模块解析失败,因为默认情况下,webpack是不认识.css
这一类的文件,所以也就无法将它打包到项目中,那么如何才能将它打包呢?
接下来我们就要说到webpack的配置文件webpack.config.js
。
1. 配置文件
在项目的根目录下创建一个webpack.config.js
文件。
module.exports = {};
注意:因为webpack是使用Nodejs写的,所以需要使用CommonJS语法进行导出,而不能使用我们常用的es6 modules(export default {};
)形式进行导出。
webpack ./main.js -o ./build/ --mode=development
这一段在终端中运行的代码,如果通过webpack.config.js
配置来实现的话就需要写成下面这个样子:
const { resolve } = require("path");
module.exports = {
// 入口文件
entry: "./main.js",
// 输出文件
output: {
// 输出路径
path: resolve(__dirname, "build"),
},
// 输出模式
mode: "development",
};
然后在终端中运行:
webpack
即可以根据配置webpack.config.js
文件来打包。
说到这里你是否觉得下面这种方式比起上面终端中要敲webpack ./main.js -o ./build/ --mode=development
这一坨要简便多了?
其实webpack ./main.js -o ./build/ --mode=development
存在是有它的道理的,这个我们放在后面进行讲解为什么会存在这种形式的打包方式,并且它还是一个非常常用的打包方式。
2. 打包CSS
在终端下载两个关于处理CSS的loader:
- style-loader:创建style标签,将js中的样式资源进行插入,添加到head中生效。
- css-loader:将css文件编译成CommonJS模块加载到js中,里面内容是样式字符串。
npm install style-loader css-loader --save-dev
然后将下面的配置写入webpack.config.js
文件。
const { resolve } = require("path");
module.exports = {
// 入口文件
entry: "./main.js",
// 输出文件
output: {
// 输出路径
path: resolve(__dirname, "build"),
},
module: {
rules: [
// 详细的loader配置
{
// 用正则表达式匹配文件类型,下面就是匹配以.css结尾的文件,并且将它们使用下面的loader解析。
test: /\.css$/,
use: [
// 创建style标签,将js中的样式资源进行插入,添加到head中生效
"style-loader",
// 将css文件编程CommonJs模块加载到js中,里面内容是样式字符串
"css-loader",
],
},
],
},
// 输出模式
mode: "development",
};
可以看到上面的配置文件多了一个module
对象,并且在其下面有一个rules
数组,在这个rules
数组中就是配置loader
相关的东西。
- test:用正则表达式匹配文件类型。
- use:需要使用的loader。
use
下面的loader执行顺序是从右到左(从下到上)。这个非常重要,如果写反了可能会导致无法正确进行打包。
这个时候我们再运行webpack
打包一次,显示打包成功,然后再到打包后的文件中就可以看到最终的输出结果。
3. 打包SASS
负责将sass转换为css的两个loader是:sass-loader
、sass
。
现在大部分项目已经使用sass
替代node-sass
了,因为node-sass
之前依赖Python,并且它还有一部分文件来自于GitHub,因为国内网络环境的原因,导致经常下载node-sass
时出错,后来官方推出了编译速度更快的sass
替代node-sass
。
下载两个loader:
npm install sass-loader sass --save-dev
配置代码:
{
test: /\.(scss|sass)$/,
use: [
"style-loader",
"css-loader",
"sass-loader",
],
},
简单的说就是将.scss
或.sass
文件转换为css,然后将css编译为webpack支持的文件类型。
4. HTML
HTML文件有些许的不同,因为HTML是不用通过webpack进行编译,而是直接输出.html
文件,然后通过浏览器进行解析。
所以针对HTML文件,我们不需要使用loader,但是要使用一个插件来默认创建一个HTML文件,然后引入打包后的js文件。
- html-webpack-plugin:默认会创建一个空的HTML,自动引入打包输出的所有资源。
首先需要进行安装该插件:
npm install html-webpack-plugin --save-dev
在module
对象下面新增:
// 引入html-webpack-plugin插件
const HtmlWebpackPlugin = require("html-webpack-plugin");
// 在module对象下面新增
plugins: [new HtmlWebpackPlugin()],
这个时候再运行打包指令webpack
。
可以看到在build
目录下输出了一个index.html
文件,并且引入了main.js
。
同时我们也可以自行配置HTML文件模板样式。
在项目的根目录下创建一个public
文件夹,在下面创建一个index.html
文件。
重新配置一下webpack。
plugins: [
new HtmlWebpackPlugin({
template: resolve(__dirname, "./public/index.html"),
}),
],
可以看到,HTML文件已经应用了我们给出的模板,并且也引入了main.js
文件。
5. 处理图片资源
引入依赖:
npm install url-loader file-loader --save-dev
url-loader
依赖file-loader
,设置配置如下:
{
test: /\.(jpg|png|gif)$/,
use: [
{
// url-loader依赖file-loader。
loader: "url-loader",
options: {
// 图片大小小于8kb,就会被编译成base64打包在项目中
// 优点:减少请求数量(减轻服务器压力)。
// 缺点:图片体积会更大。
// 一般只将8~12kb的图片进行处理
limit: 8 * 1024,
},
},
],
},
根据上面的配置,小于8kb的图片就会被编译成为base64。
然而,如果在HTML中有引入图片文件,例如:
打包后引入图片的地址会原模原样的进行输出,但是打包后的目录结构发生了变化,根本就找不到这个文件夹,所以引入也是无效的,那么这种情况如何处理呢?
处理方式:引入html-loader
。
{
test: /\.html$/,
loader: "html-loader",
},
再次尝试进行打包,发现输出的文件已经产生了变化
如果觉得打包后的文件名太长,可以设置url-loader
的name
属性。
{
test: /\.(jpg|png|gif)$/,
use: [
{
// url-loader依赖file-loader。
loader: "url-loader",
options: {
limit: 8 * 1024,
// 设置名称长度,保留hash前10位,ext表示原有后缀名
name: "[hash:10].[ext]",
},
},
],
},
6. 其它资源
如果有一些不希望webpack打包的资源,我们可以将它排除掉,直接放到项目中去。
{
// 需要排除的文件类型
exclude: /\.(html|css|js|scss|sass|png|jpg|gif)/,
loader: "file-loader",
},
7. 最后
经过本次学习,我已经成功明白如何将除了js外的其它文件通过webpack进行打包,那么本篇文章就到这里,下一篇文章就介绍如何在开发环境将项目跑在webpack创建的服务器上,并且处理css和js文件的兼容性问题。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!