Home  >  Article  >  Web Front-end  >  How does Webpack implement Loader? (with code)

How does Webpack implement Loader? (with code)

不言
不言forward
2019-04-03 09:11:361945browse

The content of this article is about how Webpack implements Loader? (Attached is the code), which has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

How to implement a Loader?

We have talked about loaders in the previous sections. Today we will learn more about them. The most violent way is to implement them by hand.

Okay, back to the topic, let’s review the loaders first.

Loader definition: used to convert the source code of the module. Loader allows you to preprocess files when importing or "loading" modules

Easy to use

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            // loader 是导出为一个a函数的 node 模块。该函数在 loader 转换资源的时候调用
            // 给定的函数将调用 loader API,并通过 this 上下文访问
            loader: path.resolve('loader.js'),
            options: {/* ... */}
          }
        ]
      }
    ]
  }
};

After reviewing the definition and simple use of loader, let's analyze the idea of ​​implementing loader

Single responsibility, a loader only does one thing

Chain combination, each loader in the chain will apply the conversion to the processed resources

Modularization, is exported as The node module of a function

Parameter merging, the loader can be configured through the options object

Based on the above analysis points, we started to do it

// 这个就是一个最简单loader,
// 如果我们的loader有依赖其它模块,也得以module的写法将在在顶部引入
import fs from 'fs';
export default function(source){
    return source
}

We found that return was used directly above because it is a synchronization class The loader and the returned content are unique. If you want your loader to support chain calls and return the results to the next loader for continued use, then you need to use the api provided by webpack

Here we take a brief look at this Definition of .callback, a function that can be called synchronously or asynchronously and can return multiple results. The expected parameters are

this.callback(
  err: Error | null,
  content: string | Buffer,
  sourceMap?: SourceMap,
  meta?: any
)
// loader-utils 它提供了很多有用的工具
// 最常用的一个就是获取传入 loader 的 options
import { getOptions } from 'loader-utils';
export default function(source, other) {
  const options = getOptions(this)    
  // do whatever you want
  // ...
  this.callback(null, source, other)
}

Writing a loader by hand may sound a bit difficult for those who have not studied it. In fact, after mastering the content and ideas introduced above, you can start writing a simple Loader. Let’s use it again. What is a loader with a simple code?

// 首先loader它是一个node模块,这很好理解
export const lessToCss = function(source, other) {
    // source 就是你即将要转换的文件源
    // TODO
    // 将转换好的文件源流转至一个管道
    this.callback(null, source, other)
}
Make your loader more useful

There are several useful guys in the loader api, so I will mention them here by the way

this.cacheable() From the perspective of improving execution efficiency, how to use cache is extremely important. This.cacheable in webpack can easily cache the loader.

this.async() When a loader When there are no dependencies, we should return the results asynchronously

Case analysis

The source code of less-loader is pasted below. The code is very concise. Combined with what we analyzed above, it is also very simple. Easy to understand

import processResult from './processResult';
const render = pify(less.render.bind(less));

function lessLoader(source) {
  const loaderContext = this;
  const options = getOptions(loaderContext);
  const done = loaderContext.async();
  const isSync = typeof done !== 'function';

  if (isSync) {
    throw new Error(
      'Synchronous compilation is not supported anymore. See https://github.com/webpack-contrib/less-loader/issues/84'
    );
  }
  processResult(loaderContext, render(source, options));
}

Summary

Loader is a node module

When writing loaders, you must follow a single principle. Each loader only does one kind of "escaping" work

webpack provides us with a rich loader api

webpack also provides us with a set of tool functions-loader-utils

[Related recommendations: JavaScript video tutorial]

The above is the detailed content of How does Webpack implement Loader? (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete