与えられたモジュールを実行し、バンドル内でモジュールが必要とされるビルド時に実行結果を返す webpack ローダーです。このようにして、ローダーはモジュールをコードから結果に変更します。
val-loader の別の見方としては、ユーザーがカスタムローダーを作成することなく、独自のカスタムローダーロジックを作成する方法を提供することです。
ターゲットモジュールは、2 つの引数 (options, loaderContext) を使用して呼び出されます。
options: ローダーオプションです (たとえば、webpack 設定で提供されます。以下の例を参照してください)。loaderContext: ローダーコンテキスト。まず、val-loader をインストールする必要があります
npm install val-loader --save-dev
yarn add -D val-loader
pnpm add -D val-loader
次に、ローダーを webpack 設定に追加します。たとえば
target-file.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`,
},
],
},
],
},
};src/entry.js
const answer = require("target-file");そして、お好みの方法で webpack を実行します。
executableFileタイプ
type executableFile = string;デフォルト: undefined
実行可能ファイルへのパスを指定できます
data.json
{
"years": "10"
}executable-file.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",
},
],
},
};このローダーの対象となるモジュールは、オブジェクトを返す Function、またはオブジェクトを解決する Promise (例: 非同期関数) をエクスポートする必要があり、少なくとも code プロパティを含める必要がありますが、任意の数の追加プロパティを含めることができます。
codeタイプ
type code = string | Buffer;デフォルト: undefined 必須
webpack またはモジュールを置き換える次のローダーに渡されるコード。
sourceMapタイプ
type sourceMap = object;デフォルト: undefined
webpack または次のローダーに渡されるソースマップ。
astタイプ
type ast = Array<object>;デフォルト: undefined
次のローダーに渡される 抽象構文木。次のローダーが同じ AST を使用する場合、ビルド時間を短縮するのに役立ちます。
dependenciesタイプ
type dependencies = Array<string>;デフォルト: []
webpack が変更を監視する必要があるファイル依存関係への絶対的なネイティブパスの配列。
依存関係は、loaderContext.addDependency(file: string) を使用して追加することもできます。
contextDependenciesタイプ
type contextDependencies = Array<string>;デフォルト: []
webpack が変更を監視する必要があるディレクトリ依存関係への絶対的なネイティブパスの配列。
コンテキスト依存関係は、loaderContext.addContextDependency(directory: string) を使用して追加することもできます。
buildDependenciesタイプ
type buildDependencies = Array<string>;デフォルト: []
webpack が変更を監視する必要があるディレクトリ依存関係への絶対的なネイティブパスの配列。
ビルド依存関係は、loaderContext.addBuildDependency(file: string)を使用しても追加できます。
cacheableタイプ
type cacheable = boolean;デフォルト: false
trueの場合、dependenciesのいずれも変更されていない場合、コードをウォッチモードで再利用できることを指定します。
この例では、ローダーはyears-in-ms.jsというファイル名に対して操作を実行し、コードを実行し、実行結果をバンドルに格納するように構成されています。この例では、yearsをoptionとして渡しています。これは、ターゲットモジュールのエクスポートされた関数内のyearsパラメーターに対応します。
years-in-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,
},
},
],
},
],
},
};バンドル内で、モジュールをrequireすると、次のものが返されます。
import tenYearsMs from "years-in-ms";
console.log(tenYearsMs); // 315360000000この例は、modernizrをビルドする方法を示しています。
entry.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をビルドする方法を示しています。
entry.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",
},
},
],
},
],
},
};まだお読みでない場合は、貢献ガイドラインをお読みください。