1

准备工作

  • 安装 Node.js, 建议安装LTS长期支持版本
  • mkdir webpack and cd webpack and npm init -y
  • npm i webpack webpack-cli --save-dev

loader是什么

所谓 loader 只是一个导出为函数的 JavaScript 模块。loader runner 会调用这个函数,然后把上一个 loader 产生的结果或者资源文件(resource file)传入进去。函数的 this 上下文将由 webpack 填充,并且 loader runner 具有一些有用方法,可以使 loader 改变为异步调用方式,或者获取 query 参数。
第一个 loader 的传入参数只有一个:资源文件(resource file)的内容。compiler 需要得到最后一个 loader 产生的处理结果。这个处理结果应该是 String 或者 Buffer(被转换为一个 string),代表了模块的 JavaScript 源码。另外还可以传递一个可选的 SourceMap 结果(格式为 JSON 对象)。
如果是单个处理结果,可以在同步模式中直接返回。如果有多个处理结果,则必须调用 this.callback()。在异步模式中,必须调用 this.async(),来指示 loader runner 等待异步结果,它会返回 this.callback() 回调函数,随后 loader 必须返回 undefined 并且调用该回调函数。

loader干了些什么

webpack loader对js代码、样式、图片等资源重新编译返回一个理想的结果,本质上说,loader是一些特殊的webpack插件,当然webpack本身有plugin的概念。默认情况下,资源文件会被转化为 UTF-8 字符串,然后传给 loader。通过设置 raw,loader 可以接收原始的 Buffer。每一个 loader 都可以用 String 或者 Buffer 的形式传递它的处理结果。Complier 将会把它们在 loader 之间相互转换。loader 总是从右到左地被调用。

接下来我们以css-loader为例看看它的输出
创建文件如下:

-- a.css
-- index.html
-- index.js
-- webpack.config.js
a.css
#app {
  background-color: #f5f5f5;
  color: blue;
}
#app p {
  color: gray;
}
index.html
<div id="app">
    <h4>hello webpack!</h4>
    <p>hello loader!</p>
</div>
<script src="./main.js"></script>
index.js
const a = require('./a.css');
console.log(a);
webpack.config.js
module.exports = {
    entry: {
        main: './index.js'
    },
    output: {
        filename: '[name].js',
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: 'css-loader'
            }
        ]
    }
}

上面的代码很常见,webpack帮助我们加载.css文件。当weback在构建的过程中会根据已有配置首先将a.css作为参数交给css-loader, css-loader将会进行一系列处理输出特定的数据。实际上a.css会作为raw resource string类型的参数,有一些loader只能接受raw作为参数,例如css-loader、handlebars-loader...
执行npx webpack
clipboard.png
可以看到,css-loader将样式代码处理成了js数组,并且我们的样式代码被处理成了字符串
修改webpack.config.js

...
module: {
    rules: [
        {
            test: /\.css$/,
            use: [ 'style-loader', 'css-loader' ]
        }
    ]
}
...

加上style-loader,再看看输出的啥:

clipboard.png

clipboard.png
如你所见,style-loader将css-loader返回的样式数组一顿操作插入到html head中去了,然后他自己返回了一个空对象

loader特性之一就是:利用参数完成某个任务,不是一定有所输出,就像一个返回值为空的函数。

显然style-loader就是符合这种特性的loader之一,它与css-loader搭配起来实现了我们需要的功能。并且他们各自独立,保持小而精的运行,方便与其他loader搭配合作,比如当我想把样式代码输出为js字符串时我就会选择to-string-loader,首先安装这个新的partner,npm i to-string-loader,然后按照顺序引用它,切记顺序很重要,

...
module: {
    rules: [
        {
            test: /\.css$/,
            use: [ 'to-string-loader', 'css-loader' ]
        }
    ]
}
...

重新构建后结果如下:

clipboard.png

关于css-loader

css-loader使用频率比较高,它有一些配置可以帮助我们实现特定需求。

...
module: {
    rules: [
        {
            test: /\.css$/,
            use: [
                'to-string-loader',
                {
                   loader: 'css-loader',
                   options: {
                       url: true,        // 是否启用url(), 类似于 url(image.png)` => `require('./image.png')
                       import: true,     // 是否启用@import()加载样式
                       modules: false,   // 是否启用CSS Modules
                       localIdentName: [hash:base64],    // Configure the generated ident
                       sourceMap: false,    // Enable/Disable Sourcemaps
                       camelCase: false,    // Export Classnames in CamelCase
                       importLoaders: 0    // Number of loaders applied before CSS loader
                   } 
                }
            ]
        }
    ]
}
...

参考链接


jczzq
33 声望1 粉丝

死宅程序员