什么是loader?
webapck的本质是一个模块打包工具, 所以webpack默认只能处理JS文件,不能处理其他文件,
因为其他文件中没有模块的概念, 但是在企业开发中我们除了需要对JS进行打包以外,
还有可能需要对图片/CSS等进行打包, 所以为了能够让webpack能够对其它的文件类型进行打包,
在打包之前就必须将其它类型文件转换为webpack能够识别处理的模块,
用于将其它类型文件转换为webpack能够识别处理模块的工具我们就称之为loader
如何使用loader
一般loader的使用方式分为三种:
1:在配置文件webpack.config.js中配置
module.exports = {
// 单个 loader 的配置
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
}
]
}
// 多个 loader 的配置
module: {
rules: [
{
// 增加对 SCSS 文件的支持
test: /\.scss/,
// SCSS 文件的处理顺序为先 sass-loader 再 css-loader 再 style-loader
use: [
'style-loader',
{
loader:'css-loader',
// 给 css-loader 传入配置项
options:{
minimize:true,
}
},
'sass-loader'],
},
]
}
}
2:通过命令行参数方式
webpack --module-bind 'txt=raw-loader'
3:通过内联使用
import txt from 'raw-loader!./file.txt';
webpack常用的loader
- 样式:style-loader、css-loader、less-loader、sass-loader等
- 文件:raw-loader、file-loader 、url-loader等
- 编译:babel-loader、coffee-loader 、ts-loader等
- 校验测试:mocha-loader、jshint-loader 、eslint-loader等
file-loader
1. 安装file-loader
npm install --save-dev file-loader
2. 在webpack.config.js中配置file-loader
webpack.config.js
module.exports = {
// module: 告诉webpack如何处理webpack不能够识别的文件
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {}
}
]
}
]
}
}
3. 其他配置(options)
默认情况下fileloader生成的图片名就是文件内容的 MD5 哈希值
如何想打包后不修改图片的名称, 那么可以新增配置name: "[name].[ext]"
其它命名规则详见: placeholders默认情况下fileloader会将生成的图片放到dist根目录下面
如果想打包之后放到指定目录下面, 那么可以新增配置outputPath: "images/"
如果需要将图片托管到其它服务器, 那么只需在打包之前配置 publicPath: "托管服务器地址"即可
例如:
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: "[name].[ext]",
outputPath: "images/",
publicPath: "http://www.baidu.com/images/"
}
}
]
}
]
}
url-loader
中文文档
url-loader 功能类似于 file-loader,
但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL
1. 安装urlloader
npm install --save-dev url-loader
2. 配置urlloader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'url-loader',
options: {
// limit: 指定图片限制的大小
limit: 1024*100,
// 指定打包后的文件名称
name: "[name].[ext]",
// 指定打包后文件存放目录
outputPath: "images/"
}
}
]
}
]
}
}
【注意】
如果被打包的图片超过了限制的大小, 就会将图片保存为一个文件
如果被打包的图片没有超过限制的大小, 就会将图片转换成base64的字符串
对于比较小的图片, 我们将图片转换成base64的字符串之后, 可以提升网页的性能(因为减少了请求的次数)
对于比较大的图片, 哪怕我们将图片转换成了base64的字符串之后, 也不会提升网页的性能, 还有可能降低网页的性能(因为图片如果比较大, 那么转换之后的字符串也会比较多, 那么网页的体积就会变大, 那么访问的速度就会变慢)
优势:
图片比较小的时候直接转换成base64字符串图片, 减少请求次数
图片比较大的时候由于生成的base64字符串图片也比较大, 就保持原有的图片
html-withimg-loader
我们通过file-loader或者url-loader已经可以将JS或者CSS中用到的图片打包到指定目录中了
但是file-loader或者url-loader并不能将HTML中用到的图片打包到指定目录中
所以此时我们就需要再借助一个名称叫做"html-withimg-loader"的加载器来实现HTML中图片的打包
参考文档
1. 安装html-withimg-loader
npm install html-withimg-loader --save
2. 配置html-withimg-loader
webpack.config.js
{
test: /\.(htm|html)$/i,
loader: 'html-withimg-loader'
}
image-webpack-loader 和 img-loader(压缩图片)
在开发中为了提升网页的访问速度, 我们除了会压缩HTML/CSS/JS以外,还会对网页上的图片进行压缩, 压缩可以减少网页体积。
image-webpack-loader 和 img-loader都可以压缩打包之后的图片, 这里我们选择image-webpack-loader 演示
参考文档: image-webpack-loader 、img-loader
1. 安装image-webpack-loader
npm install image-webpack-loader --save-dev
2. 配置image-webpack-loader
webpack.config.js
rules: [{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
{
loader: 'image-webpack-loader',
options: {
mozjpeg: {
progressive: true,
quality: 65
},
// optipng.enabled: false will disable optipng
optipng: {
enabled: false,
},
pngquant: {
quality: [0.65, 0.90],
speed: 4
},
gifsicle: {
interlaced: false,
},
// the webp option will enable WEBP
webp: {
quality: 75
}
}
},
],
}]
postcss-sprites和webpack-spritesmith(合并图片)
过去为了减少网页请求的次数, 我们需要"UI设计师"给我们提供精灵图, 并且在使用时还需要手动的去设置每张图片的位置。但是有了webpack之后我们只需要让"UI设计师"给我们提供切割好的图片,我们可以自己合成精灵图, 并且还不用手动去设置图片的位置
postcss-sprites和webpack-spritesmith都可以合并图片, 这里只介绍postcss-sprites
参考文档: postcss-sprites、webpack-spritesmith
1. 安装postcss-sprites
npm install --save-dev postcss
npm install --save-dev postcss-sprites
2. 配置postcss-sprites
postcss.config.js
module.exports = {
plugins: {
"postcss-sprites": {
// 告诉webpack合并之后的图片保存到什么地方
spritePath: "./bundle/images",
// 告诉webpack合并图片的时候如何分组
groupBy: function (image) {
let path = image.url.substr(0, image.url.lastIndexOf('/'));
let name = path.substr(path.lastIndexOf("/") + 1);
return Promise.resolve(name);
},
// 告诉webpack哪些图片需要合并, 哪些图片不需要合并
filterBy: function (image) {
let path = image.url;
// 如果不是以png结尾的图片就不合并
// 这里的过滤规则可以自定义
if (!/\.png$/.test(path)){
return Promise.reject();
}
// 如果是以png结尾的图片就合并
return Promise.resolve();
}
}
}
};
iconfot-loader(打包字体图标)
如何打包字体图标
字体图标中也用到了url用到了文件, 所以我们需要通过file-loader来处理字体图标文件
webpack.config.js
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use:[{
loader: "file-loader",
options: {
name: "[name].[ext]",
outputPath: "font/",
}
}]
}
css-loader
和图片一样webpack默认能不能处理CSS文件, 所以也需要借助loader将CSS文件转换为webpack能够处理的类型
1. 安装css-oader
npm install --save-dev css-loader
2. 安装style-loader
npm install style-loader --save-dev
3. 配置css-loader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ]
}
]
}
}
css-loader和style-loader作用
css-loader: 解析css文件中的@import依赖关系
style-loader: 将webpack处理之后的内容插入到HTML的HEAD代码中
css-loader模块化
默认情况下通过import "./xxx.css"导入的样式是全局样式, 也就是只要被导入, 在其它文件中也可以使用。如果想要导入的CSS文件只在导入的文件中有效, 那么就需要开启CSS模块化
目的:局部组件引入局部css样式,实现css模块化开发; 减免全局污染
操作
-
启用css modules
webpack.config.js
{
loader: "css-loader",
options: {
modules: true // 开启CSS模块化
}
}
-
使用css modules
导入的地方通过 import xxx from "./xxx.css"导入
在使用的地方通过 xxx.className方式使用即可, "xxx"是一个对象
例如:
import cssModule from "./index.css";
oImg.setAttribute("class", cssModule.size);
less-loader
将Less文件转换为webpack能够处理的类型
1. 安装less-loader
npm install --save-dev less-loader less
2. 配置less-loader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.less$/,
use: [ 'style-loader', 'css-loader' , 'less-loader']
}
]
}
}
sass-loader
将SASS/SCSS文件转换为webpack能够处理的类型
1. 安装sass-loader
npm install sass-loader node-sass webpack --save-dev
如果安装的时候报错, 可以尝试执行nrm use cnpm
将npm源改为cnpm
2. 配置sass-loader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(sass|scss)$/,
use: [ 'style-loader', 'css-loader' , 'sass-loader']
}
]
}
}
postcss-loader
1. 什么是PostCSS?
官网
PostCSS 是目前流行的一个对 CSS 进行处理的工具。
PostCSS和sass/less不同, 它不是CSS预处理器, 它是一款使用插件去转换CSS的工具,它负责进一步处理 CSS 文件,比如自动补全浏览器前缀,自动把px代为转换成rem 等。
PostCSS有许多非常好用的插件, PostCSS 依托其强大的插件体系为 CSS 处理增加了无穷的可能性。
2. autoprefixer(自动补全浏览器前缀)
- 安装postcss-loader
npm i -D postcss-loader
- 安装autoprefixer插件
npm i -D autoprefixer
-
配置postcss-loader
在css-loader or less-loader or sass-loader之后添加postcss-loader
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader', 'postcss-loader']
]
}
]
}
}
-
创建并配置postcss-loader配置文件
postcss.config.js
module.exports = {
plugins: {
"autoprefixer": {
"overrideBrowserslist": [
"ie >= 8", // 兼容IE7以上浏览器
"Firefox >= 3.5", // 兼容火狐版本号大于3.5浏览器
"chrome >= 35", // 兼容谷歌版本号大于35浏览器,
"opera >= 11.5", // 兼容欧朋版本号大于11.5浏览器,
]
}
}
};
3. postcss-pxtorem(自动把px代为转换成rem)
- 安装postcss-loader
npm i -D postcss-loader
- 安装postcss-pxtorem
npm install postcss-pxtorem -D
-
在配置文件中配置postcss-pxtorem
postcss.config.js
module.exports = {
plugins: {
"postcss-pxtorem": {
rootValue: 100, // 根元素字体大小
// propList: ["*"] // 可以从px更改到rem的属性
propList: ["height"]
}
}
};
postcss-pxtorem常用参数配置:
- rootValue (Number) root 元素的字体大小。
- unitPrecision (Number) 允许REM单位增长到的十进制数。
- propList ( array ) 可以从px更改到rem的属性。
值需要精确匹配。
使用通配符 * 启用所有属性。 示例:[ ' * ' ]
在单词的开头或者结尾使用 。 ( [ ' position ' ] 将匹配 background-position-y )
使用 与属性不匹配。! 示例:[' letter-spacing ']!
将"非"前缀与其他前缀合并。 示例:['', 'font*']!- selectorBlackList ( array ) 要忽略和离开的选择器。
如果值为字符串,它将检查选择器是否包含字符串。
['body'] 将匹配 .body-class
如果值为 regexp,它将检查选择器是否匹配正则表达式。
[/^body$/] 将匹配 body,但不匹配 .body- replace (Boolean) 替代包含rems的规则,而不是添加回退。
- mediaQuery (Boolean) 允许在媒体查询中转换 px。
- minPixelValue (Number) 设置要替换的最小像素值。
eslint
ESLint 是一个插件化的 javascript 代码检测工具,它可以用于检查常见的 JavaScript 代码错误,也可以进行"代码规范"检查,在开发中项目负责人会定制一套 ESLint 规则,然后应用到所编写的项目上,从而实现辅助编码规范的执行,有效控制项目代码的质量。在编译打包时如果语法有错或者有不符合规范的语法就会报错, 并且会提示相关错误信息
参考文档: eslint-loader、eslint中文文档
- 安装对应环境和loader
npm install eslint --save-dev
npm install eslint-loader --save-dev
-
配置文件
webpack.config.js
module.exports = {
// ...
module: {
rules: [
// 检查编码规范的规则
{
test: /\.js$/,
// 让当前的loader在其他loader之前执行
enforce: pre,
// 过滤 node_modules 文件夹
exclude: /node_modules/,
// 只检查src目录
include: path.resolve(__dirname, "src"),
loader: 'eslint-loader',
options: {
// 检查代码时发现不符合规范的代码会自动修复
fix: true
},
},
],
},
// ...
};
-
生成eslint配置文件
配置编码规范
创建一个.eslint.js
的文件
.eslint.js
module.exports = {
/*
不重要,永远写true
* */
root: true,
parserOptions: {
// parser: 'babel-eslint',
/*
默认设置为 3,5(默认), 你可以使用 6、7、8、9 或 10 来指定你想要使用的 ECMAScript 版本
* */
"ecmaVersion": 10,
/*
设置为 "script" (默认) 或 "module"(如果你的代码是 ECMAScript 模块)。
* */
"sourceType": "module",
/*
ecmaFeatures - 这是个对象,表示你想使用的额外的语言特性:
globalReturn - 允许在全局作用域下使用 return 语句
impliedStrict - 启用全局 strict mode (如果 ecmaVersion 是 5 或更高)
jsx - 启用 JSX
* */
"ecmaFeatures": {}
},
// 指定代码运行的宿主环境
env: {
browser: true, // 浏览器
node: true, // node
/*
支持 ES6 语法并不意味着同时支持新的 ES6 全局变量或类型(比如 Set 等新类型)。
对于 ES6 语法,使用 { "parserOptions": { "ecmaVersion": 6 } }
* */
es6: true,
},
extends: [
/*
引入standard代码规范
* */
// https://github.com/standard/standard/blob/master/docs/README-zhcn.md
'standard'
],
/*
扩展或覆盖规则
* */
rules: {
// 强制语句结束添加,分号
semi: ["error", "always"],
// 强制缩进2个空格
indent: ["error", 4],
// 方法名和刮号之间不加空格
'space-before-function-paren': ['error', 'never'],
"no-unexpected-multiline": "off"
}
};
如果要使用standard代码规范, 还必须安装它
npm install standard --save-dev
- 如何自动修复不符合规范的代码
- webpack.config.js配置文件的规则中新增
fix: true
options: {
// 检查代码时发现不符合规范的代码会自动修复
fix: true
},
弊端: 只能在打包的时候自动修复
-
借助webstorm
可以在编写代码的时候修复不符合规范的代码
在webstorm的sitting中搜索eslint, 选中手动配置
选中自己编写的规则
发现自己在编写代码的时候出现了红线提示, 可以右键鼠标选择最后一个, 就会自动修改不符合规则的代码
loader特点:
1. 单一原则, 一个loader只做一件事情
2. 多个loader会按照从右至左, 从下至上的顺序执行
例如: 从右至左
[ 'style-loader', 'css-loader' ]
先执行css-loader解析css文件关系拿到所有内容,
再执行style-loader将内容插入到HTML的HEAD代码中
例如: 从下至上
[{
loader: "style-loader"
},{
loader: "css-loader"
}]
先执行css-loader解析css文件关系拿到所有内容,
再执行style-loader将内容插入到HTML的HEAD代码中
如果一个源文件需要经历多步转换才能正常使用,就通过多个 Loader 去转换。
在调用多个 Loader 去转换一个文件时,每个 Loader 会链式的顺序执行,
第一个 Loader 将会拿到需处理的原内容,上一个 Loader 处理后的结果会传给下一个接着处理,最后的 Loader 将处理后的最终结果返回给 Webpack。
所以,在你开发一个 Loader 时,请保持其职责的单一性,你只需关心输入和输出。