webpack:loader编写

参考:

loader入门

格式

Webpack中loader是一个CommonJs风格的函数,接收输入的源码,通过同步或异步的方式替换源码后进行输出。

module.exports = function(source, sourceMap, meta) {
  
}

source是输入的内容
sourceMap是可选的
meta是模块的元数据,也是可选的

该导出函数必须使用function,不能使用箭头函数,因为loader编写过程中会经常使用到this访问选项和其他方法。

loader的配置文件

babel-loader在使用时可以加载.babelrc配置文件来配置plugins和presets,减少了webpack.config.js的代码量,便于维护。

流程

1,执行npm初始化,并安装webpack

npm init -y
npm install webpack webpack-cli

2,构建项目目录

|----loader # loader目录
        |----replace-loader.js # 替换字符串的Loader
|----src   # 应用源码
        |----index.js # 首页
|----package.json
|----webpack.config.js

3,编写loader代码

module.exports = function(source) {
  return source.replace(/World/g, 'Loader');
};

4,配置webpack :webpack.config.js

const path = require('path');

module.exports = {
  entry: './src/index',
  target: 'node', // 我们编译为Node.js环境下的JS,等下直接使用Node.js执行编译完成的文件
  output:{
    path: path.resolve(__dirname, 'build'),
    filename: '[name].js'
  },
  module:{
    rules:[
      {
        test:/.js$/,
        use: 'replace-loader'
      }
    ]
  },
  resolveLoader: {
      modules: ['./node_modules', './loader'] // 配置loader的查找目录
  }
};

5,配置package脚本和执行

//编写package.json
{
  "scripts":{
    "build":"webpack"
  }
}

//构建打包
npm run build

//构建完成后,执行
build/main.js

loader的选项

在Loader编写时,Webpack中官方推荐通过loader-utils来读取配置选项,我们需要先安装。

npm install loader-utils

给上文创建的loader传递选项:replace-loader.js

const loaderUtils = require('loader-utils');

module.exports = function(source) {
    const options = loaderUtils.getOptions(this);
    return source.replace(/World/g, options.text);
};

编辑webpack.config.js,给replace-loader传递选项

module.exports = {
  module:{
    rules:[
      {
        test:/.js$/,
        use:[
          {
            loader:'replace-loader',
            options:{
              text: 'Webpack4',
              plugins:[],
              presets:[]
            }
          }
        ]
      }
    ]
  },
  resolveLoader:{
    modules: ['./node_modules', './loader']
  }
};    

异步loader

在Loader中,如果存在异步调用,那么就无法直接通过return返回构建后的结果了,此时需要使用到Webpack提供的回调函数将数据进行回调。

Webpack4给Loader提供了this.async()函数,调用之后返回一个callback,callback的参数如下:

function callback(
  err: Error|null,
  content: string|Buffer,
  sourceMap?:SourceMap,
  meta?: any
)

相应代码

module.exports = function(source) {
    const callback = this.async();
    const output = source.replace(/World/g, 'Webpack4');
    callback(null, output);
}

raw式loader

module.exports = function(source) {
  assert(source instanceof Buffer);
  return someSyncOperation(source);
};
module.exports.raw = true; // 设置当前Loader为raw loader, webpack会将原始的Buffer对象传入

综合例子:i18n-loader

目录结构

|----loader
        |----i18n-loader.js # loader
|----i18n
        |----zh.json # 中文语言包
|----src
        |----index.js # 入口文件
|----webpack.config.js

相关配置文件

//i18n/zh.json
{
"hello": "你好", "today": "今天" }
//src/index.js
console.log('{{Hello}}, {{Today}} is a good day.');

loader/i18n-loader.js

const loaderUtils = require('loader-utils');
const path = require('path');

module.exports = function (source) {
    const options = loaderUtils.getOptions(this);
    const locale = options ? options.locale : null;

    // 读取语言配置文件
    let json = null;
    if (locale) {
        const filename = path.resolve(__dirname, '..', 'i18n', `${locale}.json`);
        json = require(filename);
    }

    // 读取语言标记 {{}}
    const matches = source.match(/{{w+}}/g); 
    for (const match of matches) {
        const name = match.match(/{{(w+)}}/)[1].toLowerCase();
        if (json !== null && json[name] !== undefined) {
            source = source.replace(match, json[name]);
        } else {
            source = source.replace(match, name);
        }
    }
    return source;
}

构建

npm run build

build/main.js输出为

你好, 今天 is a good day.
原文地址:https://www.cnblogs.com/tkzc2013/p/14536913.html