阅读(5098) (37)

Webpack val-loader

2023-05-22 16:31:41 更新

一个webpack加载器,它执行给定的模块,并且在构建时返回执行结果,当包中需要该模块时。通过这种方式,加载程序将模块从代码更改为结果。

另一种查看方式val-loader是,它允许用户创建自己的自定义加载器通讯,而无需编写自定义加载器。

使用两个参数调用目标模板:( options, loaderContext)

  • options添加加载器选项(例如在webpack配置中提供。请参阅下面的示例)。
  • :loaderContext加载程序上下文。

入门

首先,您需要安装val-loader

$ npm install val-loader --save-dev

然后将加载器添加到您的webpack配置中。例如:

目标文件.js

module.exports = (options, loaderContext) => {
  return { code: "module.exports = 42;" };
};

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /target-file.js$/,
        use: [
          {
            loader: `val-loader`,
          },
        ],
      },
    ],
  },
};

源码/entry.js

const answer = require("target-file");

 通过webpack您喜欢的方法运行。

选项

姓名 类型 默认 描述
executableFile {String} undefined 允许指定可执行文件的路径

可执行文件

类型:String默认:undefined

允许指定可执行文件的路径

数据.json

{
  "years": "10"
}

可执行文件.js

module.exports = function yearsInMs(options, loaderContext, content) {
  const { years } = JSON.parse(content);
  const value = years * 365 * 24 * 60 * 60 * 1000;

  return {
    cacheable: true,
    code: "module.exports = " + value,
  };
};

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /.(json)$/i,
        rules: [
          {
            loader: "val-loader",
            options: {
              executableFile: path.resolve(
                __dirname,
                "fixtures",
                "executableFile.js"
              ),
            },
          },
        ],
      },
      {
        test: /.json$/i,
        type: "asset/resource",
      },
    ],
  },
};

返回对象属性

此加载器的目标模块必须导出一个函数返回对象或Promise解析对象(例如异常步数)的对象,代码至少包含一个属性,但可以包含任意数量的附加属性。

代码

类型:String|Buffer默认:undefined 必填

代号传给 webpack 或将替换模块的下一个加载器。

资源地图

类型:Object默认:undefined

传给 webpack 或下一个加载器的源映像。

AST

类型:Array[Object]默认:undefined

将传给下一个加载程序的拖象语法树。如果下一个加载程序使用相同的AST,则有助于加速构建时间。

依赖关系

类型:Array[String]默认:[]

文件依赖项的绝对本地路径数组,webpack应监视这些路径以进行更改。

也可以使用添加依赖项loaderContext.addDependency(file: string)。

上下文依赖

类型:Array[String]默认:[]

目录依赖项的绝对本地路径数组,webpack应监视这些路径以进行更改。

也可以使用添加上下面的依赖项loaderContext.addContextDependency(directory: string)。

建立依赖关系

类型:Array[String]默认:[]

目录依赖项的绝对本地路径数组,webpack应监视这些路径以进行更改。

也可以使用添加构建依赖项loaderContext.addBuildDependency(file: string)。

可缓存的

类型:Boolean默认:false

如果是真的,指定代码可以在监视模式下重新使用,如果没有更更改的依赖项。

例子

简单的

在此示例中,加载程序配置为对文件名进行运行计算years-in-ms.js, 执行代码,并将结果作为执行结果存储在包中。此示例年作传option,对应于years目标模块导出函数中的参数

多年的 ms.js

module.exports = function yearsInMs({ years }) {
  const value = years * 365 * 24 * 60 * 60 * 1000;

  // NOTE: this return value will replace the module in the bundle
  return {
    cacheable: true,
    code: "module.exports = " + value,
  };
};

webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: require.resolve("src/years-in-ms.js"),
        use: [
          {
            loader: "val-loader",
            options: {
              years: 10,
            },
          },
        ],
      },
    ],
  },
};

在包中,要求模板然后返回:

import tenYearsMs from "years-in-ms";

console.log(tenYearsMs); // 315360000000

现代正义

示例显示了如何构建 modernizr。

入口.js

import modenizr from "./modernizr.js";

modernizr.js

const modernizr = require("modernizr");

module.exports = function (options) {
  return new Promise(function (resolve) {
    // It is impossible to throw an error because modernizr causes the process.exit(1)
    modernizr.build(options, function (output) {
      resolve({
        cacheable: true,
        code: `var modernizr; var hadGlobal = 'Modernizr' in window; var oldGlobal = window.Modernizr; ${output} modernizr = window.Modernizr; if (hadGlobal) { window.Modernizr = oldGlobal; } else { delete window.Modernizr; } export default modernizr;`,
      });
    });
  });
};

webpack.config.js

const path = require("path");
module.exports = {
  module: {
    rules: [
      {
        test: path.resolve(__dirname, "src", "modernizr.js"),
        use: [
          {
            loader: "val-loader",
            options: {
              minify: false,
              options: ["setClasses"],
              "feature-detects": [
                "test/css/flexbox",
                "test/es6/promises",
                "test/serviceworker",
              ],
            },
          },
        ],
      },
    ],
  },
};

菲力特

示例显示了如何构建 figlet。

入口.js

import { default as figlet } from "./figlet.js";

console.log(figlet);

figlet.js

const figlet = require("figlet");

function wrapOutput(output, config) {
  let figletOutput = "";

  if (config.textBefore) {
    figletOutput += encodeURI(`${config.textBefore}n`);
  }

  output.split("n").forEach((line) => {
    figletOutput += encodeURI(`${line}n`);
  });

  if (config.textAfter) {
    figletOutput += encodeURI(`${config.textAfter}n`);
  }

  return `module.exports = decodeURI("${figletOutput}");`;
}

module.exports = function (options) {
  const defaultConfig = {
    fontOptions: {
      font: "ANSI Shadow",
      horizontalLayout: "default",
      kerning: "default",
      verticalLayout: "default",
    },
    text: "FIGLET-LOADER",
    textAfter: null,
    textBefore: null,
  };

  const config = Object.assign({}, defaultConfig, options);

  return new Promise(function (resolve, reject) {
    figlet.text(config.text, config.fontOptions, (error, output) => {
      if (error) {
        return reject(error);
      }

      resolve({
        cacheable: true,
        code: "module.exports = " + wrapOutput(output, config),
      });
    });
  });
};

webpack.config.js

const path = require("path");
module.exports = {
  module: {
    rules: [
      {
        test: path.resolve(__dirname, "src", "figlet.js"),
        use: [
          {
            loader: "val-loader",
            options: {
              text: "FIGLET",
            },
          },
        ],
      },
    ],
  },
};

贡献

如果还未阅读捐献指南,请抽时间进行阅读。

执照

麻省理工学院