1、loader的作用

loader又叫模块转换器。换言之就是将输入到模块到内容按照自己到特性转换输出去(有点像Vue的过滤)。同时,所有的loader的功能都是单一的,他们只会关心自己的输入与输出。同理,loader有链式调用转换的功能(有点像promise then,想要了解这一块的同学,可以看我的另一篇文章 手撕代码之Promise的实现(附源码)

2、多个loader使用规则

  • 从右向前
  • 从下向上

从右向前

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: ["style-loader","css-loader","less-loader"],
  },
};

说明:在执行该规则的时候,我们先执行了less-loader,将less文件转换成css。接着将转换为的规则交给前面的css-loadercss-loader 会对css中的@import 和 url() 进行处理,并将处理后的文件交给style-loader
然后style-loader把 CSS 插入到 DOM 中。

从下向上

module.exports = {
  module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          {
            loader: "style-loader",
          },
          {
            loader: "css-loader",
          },
          {
            loader: "less-loader",
            options: {
              lessOptions: {
                strictMath: true,
              },
            },
          },
        ],
      },
    ],
  },
};

按照刚刚的套路从下到上,分别执行 less-loader,css-loader,style-loader 。很容易的理解loader执行顺序,和每一个loader的作用。

强调:刚刚讲到的是loader的执行顺序是从右到左,从下到上。而loader的加载顺序还是我们所理解的从左到右,从上到下。但是如果在加载到时候遇到pitch-loader有返回,就不会继续向后加载了,而是会立即执行当前加载到的loader的前一个loader,然后按照执行顺序执行回去。

这一块还有很多东西,我会在之后的loader文章中详细说到,现在仅仅记住这个结论即可。

3、实现自己的babel-loader

开头我们就说了,loader的本质是将输入到模块到内容按照自己到特性转换输出去。而这和vue的过滤很像。所以,我们其实就可以将loader 定义为是 一个函数。

function loader(source){
	// coding
}
module.exports = loader;

知己知彼,方能百战不殆。接下来,我们就来了解我们今天写的这个loader

npm install @babel/core label-loader @babel/preset-env -D

这是我们在将es6+语法 转换为 ES5 语法的时候的操作。

  • @babel/preset-env 将我们的高版本语法转化为低版本语法

  • label-loader 该软件包允许使用Babel和webpack转换JavaScript文件。

  • @babel/core babel核心包

label-loader 具体作用,换一句能听懂的话讲,就是为@babel/preset-env 和 @babel/core 搭建起了桥梁,并将@babel/preset-env 高级语法转化为的输出数据,转换为@babel/core 能看懂的输入数据。

1、拿到babel预设(输入参数)

 module: {
       rules: [
           {
               test: /\.js$/,
               use: {
                   loader: 'babel-loader',
                   options: {
                       presets: [
                           '@babel/preset-env'
                       ]
                   }
               }
           }
       ]
   }

这一块代码在 webpack.config.js 目录中倒是很常见。
optionss 就是 loader的配置参数,我们需要拿到这些,并且预设显示,需要用到 @babel/preset-env。那么很容易得到代码…

let babel = require('@babel/core')
// 协助拿到传入的参数
let loaderUtils = require('loader-utils')
function loader(source) {
    // 拿到输入的参数
    let options = loaderUtils.getOptions(this);
    return source
} 

module.exports = loader

2、转换高级语法,并获取到高级语法转换结果,并将结果return 出去

let babel = require('@babel/core')
// 协助拿到传入的参数
let loaderUtils = require('loader-utils')
function loader(source) {
    // 拿到输入的参数
    let options = loaderUtils.getOptions(this);
    // 返回结果的过程是异步,需要调用该api
    let cb = this.async()
    babel.transform(source, {
        ...options,
        // 生成sourcemap文件 调试源码
        sourceMap: true
    },function (err,result) {
    	// 如果babel转换后提供了ast抽象语法树,webpack会直接
       //使用你这个loader提供的语法树而不再需要自己把code再转成语法树了
        // 异步过程
        cb(err,result.code,result.map)
    })
} 

module.exports = loader

是不是感觉很简单,没错这就是看起来很牛逼,很难懂的webpack中的loader。同时你也理解了weback中的laoder的核心。

如果你感觉这篇文章对你有帮助,可以点个赞,买个关注吗?
我最近在写校招面试的文章,欢迎关注我的公众号提问。

关注我【聪明可爱小轩轩】,让你学习前端更容易。

在这里插入图片描述

Logo

前往低代码交流专区

更多推荐