Add matchResource feature (for loaders)
Match rules with custom resource name Also use this name as rule.issuer or splitChunks test Show nicely in stats
This commit is contained in:
parent
3415a98330
commit
530e1fb172
|
@ -43,9 +43,18 @@ const contextify = (context, request) => {
|
|||
.split("!")
|
||||
.map(r => {
|
||||
const splitPath = r.split("?");
|
||||
splitPath[0] = path.relative(context, splitPath[0]);
|
||||
if (path.sep === "\\") splitPath[0] = splitPath[0].replace(/\\/g, "/");
|
||||
if (splitPath[0].indexOf("../") !== 0) splitPath[0] = "./" + splitPath[0];
|
||||
if (/^[a-zA-Z]:\\/.test(splitPath[0])) {
|
||||
splitPath[0] = path.win32.relative(context, splitPath[0]);
|
||||
if (!/^[a-zA-Z]:\\/.test(splitPath[0])) {
|
||||
splitPath[0] = splitPath[0].replace(/\\/g, "/");
|
||||
}
|
||||
}
|
||||
if (/^\//.test(splitPath[0])) {
|
||||
splitPath[0] = path.posix.relative(context, splitPath[0]);
|
||||
}
|
||||
if (!/^(\.\.\/|\/|[a-zA-Z]:\\)/.test(splitPath[0])) {
|
||||
splitPath[0] = "./" + splitPath[0];
|
||||
}
|
||||
return splitPath.join("?");
|
||||
})
|
||||
.join("!");
|
||||
|
@ -76,6 +85,7 @@ class NormalModule extends Module {
|
|||
rawRequest,
|
||||
loaders,
|
||||
resource,
|
||||
matchResource,
|
||||
parser,
|
||||
generator,
|
||||
resolveOptions
|
||||
|
@ -90,6 +100,7 @@ class NormalModule extends Module {
|
|||
this.parser = parser;
|
||||
this.generator = generator;
|
||||
this.resource = resource;
|
||||
this.matchResource = matchResource;
|
||||
this.loaders = loaders;
|
||||
if (resolveOptions !== undefined) this.resolveOptions = resolveOptions;
|
||||
|
||||
|
@ -123,16 +134,21 @@ class NormalModule extends Module {
|
|||
}
|
||||
|
||||
nameForCondition() {
|
||||
const idx = this.resource.indexOf("?");
|
||||
if (idx >= 0) return this.resource.substr(0, idx);
|
||||
return this.resource;
|
||||
const resource = this.matchResource || this.resource;
|
||||
const idx = resource.indexOf("?");
|
||||
if (idx >= 0) return resource.substr(0, idx);
|
||||
return resource;
|
||||
}
|
||||
|
||||
updateCacheModule(module) {
|
||||
this.type = module.type;
|
||||
this.request = module.request;
|
||||
this.userRequest = module.userRequest;
|
||||
this.rawRequest = module.rawRequest;
|
||||
this.parser = module.parser;
|
||||
this.generator = module.generator;
|
||||
this.resource = module.resource;
|
||||
this.matchResource = module.matchResource;
|
||||
this.loaders = module.loaders;
|
||||
this.resolveOptions = module.resolveOptions;
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
"use strict";
|
||||
|
||||
const path = require("path");
|
||||
const asyncLib = require("neo-async");
|
||||
const {
|
||||
Tapable,
|
||||
|
@ -20,6 +21,8 @@ const cachedMerge = require("./util/cachedMerge");
|
|||
|
||||
const EMPTY_RESOLVE_OPTIONS = {};
|
||||
|
||||
const MATCH_RESOURCE_REGEX = /^([^!]+)!=!/;
|
||||
|
||||
const loaderToIdent = data => {
|
||||
if (!data.options) {
|
||||
return data.loader;
|
||||
|
@ -158,19 +161,33 @@ class NormalModuleFactory extends Tapable {
|
|||
const context = data.context;
|
||||
const request = data.request;
|
||||
|
||||
const noPreAutoLoaders = request.startsWith("-!");
|
||||
const noAutoLoaders = noPreAutoLoaders || request.startsWith("!");
|
||||
const noPrePostAutoLoaders = request.startsWith("!!");
|
||||
let elements = request
|
||||
const loaderResolver = this.getResolver("loader");
|
||||
const normalResolver = this.getResolver("normal", data.resolveOptions);
|
||||
|
||||
let matchResource = undefined;
|
||||
let requestWithoutMatchResource = request;
|
||||
const matchResourceMatch = MATCH_RESOURCE_REGEX.exec(request);
|
||||
if (matchResourceMatch) {
|
||||
matchResource = matchResourceMatch[1];
|
||||
if (/^\.\.?\//.test(matchResource)) {
|
||||
matchResource = path.join(context, matchResource);
|
||||
}
|
||||
requestWithoutMatchResource = request.substr(
|
||||
matchResourceMatch[0].length
|
||||
);
|
||||
}
|
||||
|
||||
const noPreAutoLoaders = requestWithoutMatchResource.startsWith("-!");
|
||||
const noAutoLoaders =
|
||||
noPreAutoLoaders || requestWithoutMatchResource.startsWith("!");
|
||||
const noPrePostAutoLoaders = requestWithoutMatchResource.startsWith("!!");
|
||||
let elements = requestWithoutMatchResource
|
||||
.replace(/^-?!+/, "")
|
||||
.replace(/!!+/g, "!")
|
||||
.split("!");
|
||||
let resource = elements.pop();
|
||||
elements = elements.map(identToLoaderRequest);
|
||||
|
||||
const loaderResolver = this.getResolver("loader");
|
||||
const normalResolver = this.getResolver("normal", data.resolveOptions);
|
||||
|
||||
asyncLib.parallel(
|
||||
[
|
||||
callback =>
|
||||
|
@ -234,12 +251,15 @@ class NormalModuleFactory extends Tapable {
|
|||
);
|
||||
}
|
||||
|
||||
const userRequest = loaders
|
||||
.map(loaderToIdent)
|
||||
.concat([resource])
|
||||
.join("!");
|
||||
const userRequest =
|
||||
(matchResource !== undefined ? `${matchResource}!=!` : "") +
|
||||
loaders
|
||||
.map(loaderToIdent)
|
||||
.concat([resource])
|
||||
.join("!");
|
||||
|
||||
let resourcePath = resource;
|
||||
let resourcePath =
|
||||
matchResource !== undefined ? matchResource : resource;
|
||||
let resourceQuery = "";
|
||||
const queryIndex = resourcePath.indexOf("?");
|
||||
if (queryIndex >= 0) {
|
||||
|
@ -249,6 +269,10 @@ class NormalModuleFactory extends Tapable {
|
|||
|
||||
const result = this.ruleSet.exec({
|
||||
resource: resourcePath,
|
||||
realResource:
|
||||
matchResource !== undefined
|
||||
? resource.replace(/\?.*/, "")
|
||||
: resourcePath,
|
||||
resourceQuery,
|
||||
issuer: contextInfo.issuer,
|
||||
compiler: contextInfo.compiler
|
||||
|
@ -326,6 +350,7 @@ class NormalModuleFactory extends Tapable {
|
|||
rawRequest: request,
|
||||
loaders,
|
||||
resource,
|
||||
matchResource,
|
||||
resourceResolveData,
|
||||
settings,
|
||||
type,
|
||||
|
|
|
@ -10,6 +10,7 @@ const PATH_CHARS_REGEXP = /[-[\]{}()*+?.,\\^$|#\s]/g;
|
|||
const SEPARATOR_REGEXP = /[/\\]$/;
|
||||
const FRONT_OR_BACK_BANG_REGEXP = /^!|!$/g;
|
||||
const INDEX_JS_REGEXP = /\/index.js(!|\?|\(query\))/g;
|
||||
const MATCH_RESOURCE_REGEXP = /!=!/;
|
||||
|
||||
const normalizeBackSlashDirection = request => {
|
||||
return request.replace(NORMALIZE_SLASH_DIRECTION_REGEXP, "/");
|
||||
|
@ -73,6 +74,7 @@ class RequestShortener {
|
|||
}
|
||||
result = result.replace(INDEX_JS_REGEXP, "$1");
|
||||
result = result.replace(FRONT_OR_BACK_BANG_REGEXP, "");
|
||||
result = result.replace(MATCH_RESOURCE_REGEXP, " = ");
|
||||
this.cache.set(request, result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -203,6 +203,14 @@ module.exports = class RuleSet {
|
|||
}
|
||||
}
|
||||
|
||||
if (rule.realResource) {
|
||||
try {
|
||||
newRule.realResource = RuleSet.normalizeCondition(rule.realResource);
|
||||
} catch (error) {
|
||||
throw new Error(RuleSet.buildErrorMessage(rule.realResource, error));
|
||||
}
|
||||
}
|
||||
|
||||
if (rule.resourceQuery) {
|
||||
try {
|
||||
newRule.resourceQuery = RuleSet.normalizeCondition(rule.resourceQuery);
|
||||
|
@ -477,10 +485,13 @@ module.exports = class RuleSet {
|
|||
_run(data, rule, result) {
|
||||
// test conditions
|
||||
if (rule.resource && !data.resource) return false;
|
||||
if (rule.realResource && !data.realResource) return false;
|
||||
if (rule.resourceQuery && !data.resourceQuery) return false;
|
||||
if (rule.compiler && !data.compiler) return false;
|
||||
if (rule.issuer && !data.issuer) return false;
|
||||
if (rule.resource && !rule.resource(data.resource)) return false;
|
||||
if (rule.realResource && !rule.realResource(data.realResource))
|
||||
return false;
|
||||
if (data.issuer && rule.issuer && !rule.issuer(data.issuer)) return false;
|
||||
if (
|
||||
data.resourceQuery &&
|
||||
|
@ -497,6 +508,7 @@ module.exports = class RuleSet {
|
|||
const keys = Object.keys(rule).filter(key => {
|
||||
return ![
|
||||
"resource",
|
||||
"realResource",
|
||||
"resourceQuery",
|
||||
"compiler",
|
||||
"issuer",
|
||||
|
|
|
@ -16,11 +16,11 @@ describe("NormalModule", () => {
|
|||
let resource;
|
||||
let parser;
|
||||
beforeEach(() => {
|
||||
request = "some/request";
|
||||
userRequest = "some/userRequest";
|
||||
request = "/some/request";
|
||||
userRequest = "/some/userRequest";
|
||||
rawRequest = "some/rawRequest";
|
||||
loaders = [];
|
||||
resource = "some/resource";
|
||||
resource = "/some/resource";
|
||||
parser = {
|
||||
parse() {}
|
||||
};
|
||||
|
@ -66,14 +66,14 @@ describe("NormalModule", () => {
|
|||
it("contextifies the userRequest of the module", () => {
|
||||
expect(
|
||||
normalModule.libIdent({
|
||||
context: "some/context"
|
||||
context: "/some/context"
|
||||
})
|
||||
).toBe("../userRequest");
|
||||
});
|
||||
describe("given a userRequest containing loaders", () => {
|
||||
beforeEach(() => {
|
||||
userRequest =
|
||||
"some/userRequest!some/other/userRequest!some/thing/is/off/here";
|
||||
"/some/userRequest!/some/other/userRequest!/some/thing/is/off/here";
|
||||
normalModule = new NormalModule({
|
||||
type: "javascript/auto",
|
||||
request,
|
||||
|
@ -87,7 +87,7 @@ describe("NormalModule", () => {
|
|||
it("contextifies every path in the userRequest", () => {
|
||||
expect(
|
||||
normalModule.libIdent({
|
||||
context: "some/context"
|
||||
context: "/some/context"
|
||||
})
|
||||
).toBe("../userRequest!../other/userRequest!../thing/is/off/here");
|
||||
});
|
||||
|
@ -95,7 +95,7 @@ describe("NormalModule", () => {
|
|||
describe("given a userRequest containing query parameters", () => {
|
||||
it("ignores paths in query parameters", () => {
|
||||
userRequest =
|
||||
"some/context/loader?query=foo\\bar&otherPath=testpath/other";
|
||||
"F:\\some\\context\\loader?query=foo\\bar&otherPath=testpath/other";
|
||||
normalModule = new NormalModule({
|
||||
type: "javascript/auto",
|
||||
request,
|
||||
|
@ -107,7 +107,7 @@ describe("NormalModule", () => {
|
|||
});
|
||||
expect(
|
||||
normalModule.libIdent({
|
||||
context: "some/context"
|
||||
context: "F:\\some\\context"
|
||||
})
|
||||
).toBe("./loader?query=foo\\bar&otherPath=testpath/other");
|
||||
});
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
it("should be able to create two modules from loader", function() {
|
||||
return import("./wrapper-loader!./src/wasm.dat").then(function(wasm) {
|
||||
expect(wasm.getString()).toEqual("Hello World");
|
||||
});
|
||||
});
|
||||
|
||||
it("should be able to create two modules from loader with remaining request", function() {
|
||||
return import("./wrapper-loader2!./src/wasm.dat?2").then(function(wasm) {
|
||||
expect(wasm.getString()).toEqual("Hello World");
|
||||
});
|
||||
});
|
|
@ -0,0 +1,8 @@
|
|||
(module
|
||||
(memory (export "memory") 1)
|
||||
(data (i32.const 16) "Hello World\00")
|
||||
(func (export "getString") (result i32)
|
||||
(i32.const 16)
|
||||
)
|
||||
)
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
var supportsWebAssembly = require("../../../helpers/supportsWebAssembly");
|
||||
|
||||
module.exports = function(config) {
|
||||
return supportsWebAssembly();
|
||||
};
|
|
@ -0,0 +1,17 @@
|
|||
const stringifyRequest = require("loader-utils").stringifyRequest;
|
||||
|
||||
module.exports.pitch = function(remainingRequest) {
|
||||
return `
|
||||
import { getString as _getString, memory } from ${stringifyRequest(this,
|
||||
`${this.resourcePath}.wat!=!${remainingRequest}`
|
||||
)};
|
||||
|
||||
export function getString() {
|
||||
const strBuf = new Uint8Array(memory.buffer, _getString());
|
||||
const idx = strBuf.indexOf(0);
|
||||
const strBuf2 = strBuf.slice(0, idx);
|
||||
const str = Buffer.from(strBuf2).toString("utf-8");
|
||||
return str;
|
||||
};
|
||||
`;
|
||||
};
|
|
@ -0,0 +1,18 @@
|
|||
const stringifyRequest = require("loader-utils").stringifyRequest;
|
||||
|
||||
module.exports.pitch = function(remainingRequest) {
|
||||
return `
|
||||
import { getString as _getString, memory } from ${stringifyRequest(
|
||||
this,
|
||||
`${this.resourcePath}.wasm!=!wast-loader!${remainingRequest}`
|
||||
)};
|
||||
|
||||
export function getString() {
|
||||
const strBuf = new Uint8Array(memory.buffer, _getString());
|
||||
const idx = strBuf.indexOf(0);
|
||||
const strBuf2 = strBuf.slice(0, idx);
|
||||
const str = Buffer.from(strBuf2).toString("utf-8");
|
||||
return str;
|
||||
};
|
||||
`;
|
||||
};
|
Loading…
Reference in New Issue