这是一个系列文的分享记录,本篇主要是webpack的基础之样式资源的配置,如css、less、sass。加载css,打包样式资源。loader的加载顺序,是怎么加载到head中的。
webpack 开箱即用,可以无需使用任何配置文件。然而,webpack 会假定项目的入口起点为 src/index.js
,然后会在 dist/main.js
输出结果,并且在生产环境开启压缩和优化。
webpack文档推荐:webpack.docschina.org/plugins/ter…
正式开始:
预备技能
基本nodejs知识和npm指令
注意:版本问题导致不同,本系列实战中用到的webpack版本是:"webpack": "^5.68.0"
,
"webpack-cli": "^4.9.2"
,
前置知识
我们知道直接打包样式的时候会报错,在上一篇也有验证,这个时候需要配置loader。那loader是什么呢?
webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
Warning
webpack 的其中一个强大的特性就是能通过
import
导入任何类型的模块(例如.css
文件),其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是很有必要的,因为这可以使开发人员创建出更准确的依赖关系图。
在更高层面,在 webpack 的配置中,loader 有两个属性:
-
test
属性,识别出哪些文件会被转换。 -
use
属性,定义出在进行转换时,应该使用哪个 loader。webpack.config.js
const path = require('path'); module.exports = { output: { filename: 'my-first-webpack.bundle.js', }, module: { rules: [{ test: /.txt$/, use: 'raw-loader' }], }, };
以上配置中,对一个单独的 module 对象定义了
rules
属性,里面包含两个必须属性:test
和use
。这告诉 webpack 编译器(compiler) 如下信息:“嘿,webpack 编译器,当你碰到「在
require()
/import
语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先 use(使用)raw-loader
转换一下。”Warning
重要的是要记住,在 webpack 配置中定义 rules 时,要定义在
module.rules
而不是rules
中。为了使你便于理解,如果没有按照正确方式去做,webpack 会给出警告。Warning
请记住,使用正则表达式匹配文件时,你不要为它添加引号。也就是说,
/.txt$/
与'/.txt$/'
或"/.txt$/"
不一样。前者指示 webpack 匹配任何以 .txt 结尾的文件,后者指示 webpack 匹配具有绝对路径 '.txt' 的单个文件; 这可能不符合你的意图。
loader
在上一篇基础概念中有简单介绍了一下loader的概念。
Loader:模块转换器,用于把模块原内容按照需求转换成新内容。比如:让 webpack 能够去处理那些非 JS 的文件,比如样式文件、图片文件(webpack 自身只理解JS)
loader的常用属性
- test:匹配处理文件的扩展名的正则表达式
- use:loader名称,就是你要使用模块的名称
- include/exclude:手动指定必须处理的文件夹或屏蔽不需要处理的文件夹
- query:为loaders提供额外的设置选项
loader三种写法
1、loader
loader:['style-loader','css-loader']
2、use
use:['style-loader','css-loader']
3、use+loader
use: [{
loader: 'style-loader',
options: {
insert:'top'
}
},'css-loader'
]
打包样式资源
我们在前端不可避免的要用到样式资源css,或者less、sass来让我们的页面更美观。那这些资源该如何处理打包呢?
1、创建文件
在上一篇已经创建了文件,src/index.css和src/index.less
2、下载安装包
为了webpack能够识别css文件,我们需要配置css-loader,所以需要安装css-loader包
npm install -D css-loader
3、修改配置文件webpack.config.js
const path = require('path');
module.exports = {
// webpack 配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: path.resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js'
},
// loader 配置
module: {
rules: [
{
//匹配以css结尾的文件
test: /.css$/,
//采用css-loader进行处理,让webpack能够识别
loader: 'css-loader'
}
]
},
// plugins 的配置
plugins: [
],
mode: 'development', //开发模式
// mode: 'production', //生产模式
}
4、运行
- 再执行webpack编译
我们可以看到成功了。
- 在查看built.js
css样式文件打包进去了。
- 在查看浏览器。
🤷♀️问题:哇哦, 此时样式并没有生效。页面背景没有变色。这是怎么回事呢?
原来css-loader只负责把css处理为webpack能够识别的字符串,要想样式生效,就要借助于style-loader
安装style-loader
npm install -D style-loader
修改配置文件webpack.config.js
const path = require('path');
module.exports = {
// webpack 配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: path.resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js'
},
// loader 配置
module: {
rules: [
{
//匹配以css结尾的文件
test: /.css$/,
//采用css-loader进行处理,让webpack能够识别
//单个loader使用loader属性
//loader: 'css-loader'
//多个loader处理一个文件,需要使用use
//use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
use: ['style-loader', 'css-loader']
}
]
},
// plugins 的配置
plugins: [
],
mode: 'development', //开发模式
// mode: 'production', //生产模式
}
ps:代码讲解:
- use属性的执行顺序为逆序,也就是数组尾->数组首的顺序,就是先执行'css-loader'在执行'style-loader'
- css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
- style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
运行webpack
查看浏览器:
可以看到在head里动态插入了style标签,正好就是我们index.css的内容
5、使用less
- 修改./src/index/js
//./src/index/js
import dataJson from './data.json';
import './index.css';
import './index.less';
// 引入样式文件
function add(x, y) {
return x + y;
}
console.log(add(1, 2));
console.log(dataJson, 'dataJson');
- 修改完毕,再执行webpack编译
报错!!!
- 原因是,webpack不识别
.less
文件的,此时我们还需要引入less-loader
, 因为less-loader
又依赖less
进行编译,我们呢需要安装两个依赖包
npm install less less-loader -D
- 修改webpack.config.js
const path = require('path');
module.exports = {
// webpack 配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: path.resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js'
},
// loader 配置
module: {
rules: [
{
//匹配以css结尾的文件
test: /.css$/,
//采用css-loader进行处理,让webpack能够识别
//单个loader使用loader属性
//loader: 'css-loader'
//多个loader处理一个文件,需要使用use
//use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
use: ['style-loader', 'css-loader']
},
{
//匹配以.less结尾的文件
test: /.less$/,
// less-loader 讲less文件变成成css文件 (需要下载两个依赖 less和less-loder)
// css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
// style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
// use数组执行顺序是倒叙,就是先执行'style-loader',在执行'css-loader'在执行'style-loader'
use: ['style-loader', 'css-loader', 'less-loader']
}
]
},
// plugins 的配置
plugins: [
],
mode: 'development', //开发模式
// mode: 'production', //生产模式
}
- 修改完毕,再执行webpack编译
发现打包成功,在查看浏览器,字体也变颜色了~~~
6、打包sass
通过上边的less我们知道了,需要特殊安装相应的loader,而sass也是需要安装相应的sass的loader的。
sass-loader ,因为sass-loader
又依赖sass
进行编译,我们呢需要安装两个依赖包
npm install sass-loader sass -D
- 新增sass文件
./src/index.scss
#title {
font-size: 20px;
}
- 修改./src/index.js
// ./src/index/js
import dataJson from './data.json';
import './index.css';
import './index.less';
import './index.scss';
// 引入样式文件
function add(x, y) {
return x + y;
}
console.log(add(1, 2));
console.log(dataJson, 'dataJson');
- 修改配置文件webpack.config.js
const path = require('path');
module.exports = {
// webpack 配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: path.resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js'
},
// loader 配置
module: {
rules: [
{
//匹配以css结尾的文件
test: /.css$/,
//采用css-loader进行处理,让webpack能够识别
//单个loader使用loader属性
//loader: 'css-loader'
//多个loader处理一个文件,需要使用use
//use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
use: ['style-loader', 'css-loader']
},
{
//匹配以.less结尾的文件
test: /.less$/,
// less-loader 讲less文件变成成css文件 (需要下载两个依赖 less和less-loder)
// css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
// style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
// use数组执行顺序是倒叙,就是先执行'style-loader',在执行'css-loader'在执行'style-loader'
use: ['style-loader', 'css-loader', 'less-loader']
},
{
//匹配以.scss结尾的文件
test: /.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
// plugins 的配置
plugins: [
],
mode: 'development', //开发模式
// mode: 'production', //生产模式
}
- 修改完毕,再执行webpack编译
发现打包成功,在查看浏览器,字体变大了~~~
7、其他常用样式
常用的样式资源主要是css、less、sass、styus
上边已经介绍了css、less、sass;
处理styus文件用到的loader主要是style-loader、css-loader、styus-loader (需要安装styus)
跟之前一样的步骤,我就不再这赘述了。
ps:删除原来的插件
为了使每次打包后删除原来的文件重新生成新的文件,需要用到clean-webpack-plugin插件
安装
npm install clean-webpack-plugin -D
修改配置
const path = require('path');
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// webpack 配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: path.resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js'
},
// loader 配置
module: {
rules: [
{
//匹配以css结尾的文件
test: /.css$/,
//采用css-loader进行处理,让webpack能够识别
//单个loader使用loader属性
//loader: 'css-loader'
//多个loader处理一个文件,需要使用use
//use属性的执行顺序为逆序,也就是数组尾->数组首的顺序
use: ['style-loader', 'css-loader']
},
{
//匹配以.less结尾的文件
test: /.less$/,
// less-loader 讲less文件变成成css文件 (需要下载两个依赖 less和less-loder)
// css-loader 将css文件变成commonjs模块加载到js中 里边内容是样式字符串
// style-loader 创建style标签,将js中的样式资源插入进行,添加到head中生效
// use数组执行顺序是倒叙,就是先执行'style-loader',在执行'css-loader'在执行'style-loader'
use: ['style-loader', 'css-loader', 'less-loader']
},
{
//匹配以.scss结尾的文件
test: /.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
},
// plugins 的配置
plugins: [
new CleanWebpackPlugin(),
],
mode: 'development', //开发模式
// mode: 'production', //生产模式
}
运行webpack
ps:注意遇到的坑啊:
如果错误提示:
TypeError: CleanWebpackPlugin is not a constructorn
那就是可能是你的clean-webpack-plugin版本;、
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin(['dist'])
]
};
正确的是:
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin()
]
}
哎呀,把整个build文件内部的文件都删了,index.html也删除了,其实我们工作中,index.html并不在build文件中,这个文件就是每次自己创建的,html在外部,应该每次自己打包进去,该如何操作呢?我们在一下篇中将讲解
第二种方案:推荐
我们使用
output.clean
配置项实现这个需求。
这个明显比较简单,因为不需要下载相关依赖模块,引入,使用,直接让output.clean=true
修改配置:webpack.config.js
// 输出
output: {
// 输出路径 __dirname nodejs变量 代表当前文件的目录绝对路径
path: resolve(__dirname, 'build'),
// 输出ming
filename: 'built.js',
clean:true
},
可以看到简单,推荐使用这种,减少plugin
感谢
到此,本篇介绍到此结束,之后将陆续整理 webpack 知识体系的内容分享,尽情期待,感谢您的阅读~~