feat: getOptions util for loader

This commit is contained in:
evilebottnawi 2019-11-21 16:36:31 +03:00 committed by Tobias Koppers
parent 0f96cb2586
commit 4e808cb613
15 changed files with 234 additions and 0 deletions

View File

@ -5,7 +5,10 @@
"use strict";
const parseJson = require("json-parse-better-errors");
const { getContext, runLoaders } = require("loader-runner");
const querystring = require("querystring");
const validateOptions = require("schema-utils");
const { SyncHook } = require("tapable");
const {
CachedSource,
@ -350,6 +353,50 @@ class NormalModule extends Module {
};
const loaderContext = {
version: 2,
getOptions: (loaderName, schema) => {
const loader = loaderContext.loaders[loaderContext.loaderIndex];
let options = {};
if (loader.options && typeof loader.options === "object") {
({ options } = loader);
} else if (loader.query) {
let { query } = loader;
if (query.substr(0, 1) !== "?") {
throw new WebpackError(
"A valid query string should begin with '?'"
);
}
query = query.substr(1);
// Allow to use `?foo=bar` in `options`
if (query.substr(0, 1) === "?") {
query = query.substr(1);
}
if (query.substr(0, 1) === "{" && query.substr(-1) === "}") {
try {
options = parseJson(query);
} catch (e) {
throw new WebpackError(`Cannot parse query string: ${e.message}`);
}
} else {
options = querystring.parse(query);
}
}
if (!schema) {
return options;
}
validateOptions(schema, options, {
name: loaderName || "Unknown Loader",
baseDataPath: "options"
});
return options;
},
emitWarning: warning => {
if (!(warning instanceof Error)) {
warning = new NonErrorEmittedError(warning);

View File

View File

View File

View File

View File

View File

View File

View File

View File

View File

@ -0,0 +1,45 @@
it("should get options", function() {
expect(require("./a")).toStrictEqual({
arg: true,
arg1: null,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
});
expect(require("./b")).toStrictEqual({
arg: true,
arg1: null,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
});
expect(require("./c")).toStrictEqual({
arg: true,
arg1: null,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
});
expect(require("./d")).toStrictEqual({
arg4: "text"
});
expect(require("./e")).toStrictEqual({});
expect(require("./f")).toStrictEqual({
delicious: "",
name: "cheesecake",
slices: "8",
warm: "false"
});
expect(require("./g")).toStrictEqual({
"=": "="
});
expect(require("./h")).toStrictEqual({
"foo": "bar"
});
expect(require("./i")).toStrictEqual({
"foo": "bar"
});
});

View File

@ -0,0 +1,12 @@
const schema = require('./loader-1.options');
module.exports = function() {
const options = this.getOptions('Loader Name', schema);
const json = JSON.stringify(options)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
return `module.exports = ${json}`;
};

View File

@ -0,0 +1,43 @@
{
"additionalProperties": false,
"properties": {
"arg": {
"type": "boolean"
},
"arg1": {
"type": "null"
},
"arg2": {},
"arg3": {
"type": "number"
},
"arg4": {
"type": "string"
},
"arg5": {
"type": "array",
"items": {
"type": "number"
}
},
"arg6": {
"type": "object",
"properties": {
"foo": {
"type": "string"
},
"bar": {
"type": "object",
"properties": {
"baz": {
"type": "string"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
},
"type": "object"
}

View File

@ -0,0 +1,9 @@
module.exports = function() {
const options = this.getOptions();
const json = JSON.stringify(options)
.replace(/\u2028/g, '\\u2028')
.replace(/\u2029/g, '\\u2029');
return `module.exports = ${json}`;
};

View File

@ -0,0 +1,78 @@
module.exports = {
mode: "none",
module: {
rules: [
{
test: /a\.js$/,
loader: "./loader",
options: {
arg: true,
arg1: null,
arg2: undefined,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
}
},
{
test: /b\.js$/,
loader: "./loader-1",
options: {
arg: true,
arg1: null,
arg2: undefined,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
}
},
{
test: /c\.js$/,
loader: "./loader-1",
options: JSON.stringify({
arg: true,
arg1: null,
arg2: undefined,
arg3: 1234567890,
arg4: "string",
arg5: [1, 2, 3],
arg6: { foo: "value", bar: { baz: "other-value" } }
})
},
{
test: /d\.js$/,
loader: "./loader-1",
options: "arg4=text"
},
{
test: /d\.js$/,
loader: "./loader",
options: "?"
},
{
test: /f\.js$/,
loader: "./loader",
options: "name=cheesecake&slices=8&delicious&warm=false"
},
{
test: /g\.js$/,
loader: "./loader",
options: "%3d=%3D"
},
{
test: /h\.js$/,
loader: "./loader",
options: "?foo=bar"
},
{
test: /i\.js$/,
loader: "./loader",
options: `?${JSON.stringify({
foo: "bar"
})}`
}
]
}
};