[Webpack]浅写个loader

506 阅读2分钟

loader是什么?

Webpack原本只能解析js文件,loader拓展了webpack的解析能力,使css,html等都能被webpack所解析。
loader的本质是一个具有返回值的函数

举个栗子

Webpack初始化

npm init -y  //初始化
npm i webpack webpack-cli //安装webpack及脚手架

根目录下创建webpack.config.js,用来配置webpack
package.json中加入命令dev 使用我们自己的配置进行打包。

...
 "scripts": {
    "dev": "webpack --config webpack.config.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
...

image.png

//index.js
import './style.css'
function add(a, b) {
    console.log(a + b);
    return a + b
}
add(6, 6) 
//webpack.config.js
const path = require('path')
module.exports = {
    mode:'development',
    entry:{
        main:'./src/index.js'
    },
    output:{
        path:path.resolve(__dirname,'dist'),
        filename:'main.js'
    }
}

image.png 当我们的js文件中引入了css文件,对js文件打包会报错,显示无法解析css模块。

安装css-loader

此时为了让webpack拥有解析css的能力,我们就需要安装css-loader。

npm i css-loader

在webpack.config.js中使用css-loader

module.exports = {
...
    module: {
        rules: [
            {
                test: /\.css$/, //去匹配css后缀的文件,此处是一个正则表达式,\是转义字符,$表示已某某结尾,翻译过来就是以.css结尾。
                use: ['css-loader']
            },
        ]
    },
...
}

再次打包,成功√

image.png

image.png

如何写一个loader?

loader的设计准则

1.单一职责
2.链式组合(一个loader操作完的文件可以被另一个loader继续操作)
3.模块化
4.无状态

小demo

webpack.config.js
...
    module:{
        rules:[
            {
                test:/\.html$/,
                use:[
                   'html-loader', 
                    {
                        loader:path.resolve('./html-minify-loader.js'),//我们自己写的loader
                        options:{
                            comments:false // 注释不打包
                        }
                    }
                ]
            }
 ...

loader的本质是函数,loader函数的参数是匹配到的文件内容。 options是额外传给这个函数的内容,需要用this.getOptions获取,在webpack4中需要使用loader-utils获取
此处以一个简单的小demo进行示范,将html-minify-loader.js这个自己写的loader来压缩html,然后交给html-loader解析成js

安装html-loader

npm i html-loader //先安装将html解析成js的loader.

image.png

//index.js
var html = require('./example.html')
console.log(html);
//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    好热啊~~~
</body>
</html>
//html-minify-loader.js
module.exports = function(source){
    var options =this.getOptions()     //拿到配置的options参数
    console.log('options:',options);
    console.log('source',source);      //source此处为html代码
    return source
}

我们先打npm run dev 打包看一下打印结果。

image.png

image.png

在自己的loader中压缩html

我们对自己写的loader加个压缩html中的换行和空格的功能,此处就偷个懒用别人写好的压缩轮子。

npm i minimize //该工具用来压缩html中的空格和换行。
//html-minify-loader.js
var Minimize = require('minimize')
module.exports = function(source){
    var options =this.getOptions() 
    var minimize = new Minimize(options) //将额外参数{comments:false}传入工具中
    return minimize.parse(source)
}

再打包看看,空格没了! image.png