Skip to content

Commit

Permalink
support context
Browse files Browse the repository at this point in the history
  • Loading branch information
vankop committed Mar 31, 2022
1 parent 3b6328c commit 5d967db
Show file tree
Hide file tree
Showing 15 changed files with 132 additions and 63 deletions.
65 changes: 35 additions & 30 deletions lib/dependencies/CommonJsImportsParserPlugin.js
Expand Up @@ -5,6 +5,7 @@

"use strict";

const { fileURLToPath } = require("url");
const CommentCompilationWarning = require("../CommentCompilationWarning");
const RuntimeGlobals = require("../RuntimeGlobals");
const UnsupportedFeatureWarning = require("../UnsupportedFeatureWarning");
Expand Down Expand Up @@ -45,6 +46,13 @@ class CommonJsImportsParserPlugin {
apply(parser) {
const options = this.options;

const getContext = () => {
if (parser.currentTagData) {
const { context } = parser.currentTagData;
return context;
}
};

//#region metadata
const tapRequireExpression = (expression, getMembers) => {
parser.hooks.typeof
Expand Down Expand Up @@ -172,7 +180,8 @@ class CommonJsImportsParserPlugin {
},
expr.range,
undefined,
parser.scope.inShorthand
parser.scope.inShorthand,
getContext()
);
dep.critical =
options.unknownContextCritical &&
Expand All @@ -190,7 +199,11 @@ class CommonJsImportsParserPlugin {
//#region Require
const processRequireItem = (expr, param) => {
if (param.isString()) {
const dep = new CommonJsRequireDependency(param.string, param.range);
const dep = new CommonJsRequireDependency(
param.string,
param.range,
getContext()
);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
parser.state.current.addDependency(dep);
Expand All @@ -207,7 +220,9 @@ class CommonJsImportsParserPlugin {
{
category: "commonjs"
},
parser
parser,
undefined,
getContext()
);
if (!dep) return;
dep.loc = expr.loc;
Expand Down Expand Up @@ -380,7 +395,11 @@ class CommonJsImportsParserPlugin {
};
const processResolveItem = (expr, param, weak) => {
if (param.isString()) {
const dep = new RequireResolveDependency(param.string, param.range);
const dep = new RequireResolveDependency(
param.string,
param.range,
getContext()
);
dep.loc = expr.loc;
dep.optional = !!parser.scope.inTry;
dep.weak = weak;
Expand All @@ -399,7 +418,8 @@ class CommonJsImportsParserPlugin {
category: "commonjs",
mode: weak ? "weak" : "sync"
},
parser
parser,
getContext()
);
if (!dep) return;
dep.loc = expr.loc;
Expand Down Expand Up @@ -489,7 +509,7 @@ class CommonJsImportsParserPlugin {
.tap("CommonJsImportsParserPlugin", createRequireHandler(false));
/**
* @param {CallExpressionNode} expr call expression
* @returns {string|boolean} context
* @returns {string} context
*/
const parseCreateRequireArguments = expr => {
const args = expr.arguments;
Expand All @@ -509,31 +529,16 @@ class CommonJsImportsParserPlugin {
parser.state.module.addWarning(err);
};
const arg = args[0];
if (
arg.type === "MemberExpression" &&
arg.object.type === "MetaProperty"
) {
if (
arg.object.meta.type === "Identifier" &&
arg.object.meta.name === "import" &&
arg.object.property.type === "Identifier" &&
arg.object.property.name === "meta" &&
arg.property.type === "Identifier" &&
arg.property.name === "url"
) {
// same module context
return false;
} else {
createParsingError(arg);
}
} else {
const evaluated = parser.evaluateExpression(arg);
if (!evaluated.isString()) {
createParsingError(arg);
return;
}
return evaluated.string;
const evaluated = parser.evaluateExpression(arg);
if (!evaluated.isString()) {
createParsingError(arg);
return;
}
const ctx = evaluated.string.startsWith("file://")
? fileURLToPath(evaluated.string)
: evaluated.string;
// argument always should be a filename
return ctx.slice(0, ctx.lastIndexOf(ctx.startsWith("/") ? "/" : "\\"));
};

parser.hooks.import.tap(
Expand Down
4 changes: 2 additions & 2 deletions lib/dependencies/CommonJsRequireContextDependency.js
Expand Up @@ -10,8 +10,8 @@ const ContextDependency = require("./ContextDependency");
const ContextDependencyTemplateAsRequireCall = require("./ContextDependencyTemplateAsRequireCall");

class CommonJsRequireContextDependency extends ContextDependency {
constructor(options, range, valueRange, inShorthand) {
super(options);
constructor(options, range, valueRange, inShorthand, context) {
super(options, context);

this.range = range;
this.valueRange = valueRange;
Expand Down
3 changes: 2 additions & 1 deletion lib/dependencies/CommonJsRequireDependency.js
Expand Up @@ -10,9 +10,10 @@ const ModuleDependency = require("./ModuleDependency");
const ModuleDependencyTemplateAsId = require("./ModuleDependencyTemplateAsId");

class CommonJsRequireDependency extends ModuleDependency {
constructor(request, range) {
constructor(request, range, context) {
super(request);
this.range = range;
this._context = context;
}

get type() {
Expand Down
17 changes: 15 additions & 2 deletions lib/dependencies/ContextDependency.js
Expand Up @@ -26,8 +26,9 @@ const regExpToString = r => (r ? r + "" : "");
class ContextDependency extends Dependency {
/**
* @param {ContextDependencyOptions} options options for the context module
* @param {string=} context request context
*/
constructor(options) {
constructor(options, context) {
super();

this.options = options;
Expand All @@ -50,6 +51,14 @@ class ContextDependency extends Dependency {
this.inShorthand = undefined;
// TODO refactor this
this.replaces = undefined;
this._requestContext = context;
}

/**
* @returns {string | undefined} a request context
*/
getContext() {
return this._requestContext;
}

get category() {
Expand All @@ -68,7 +77,9 @@ class ContextDependency extends Dependency {
*/
getResourceIdentifier() {
return (
`context${this.options.request} ${this.options.recursive} ` +
`context${this._requestContext || ""}|ctx request${
this.options.request
} ${this.options.recursive} ` +
`${regExpToString(this.options.regExp)} ${regExpToString(
this.options.include
)} ${regExpToString(this.options.exclude)} ` +
Expand Down Expand Up @@ -112,6 +123,7 @@ class ContextDependency extends Dependency {
write(this.critical);
write(this.hadGlobalOrStickyRegExp);
write(this.request);
write(this._requestContext);
write(this.range);
write(this.valueRange);
write(this.prepend);
Expand All @@ -128,6 +140,7 @@ class ContextDependency extends Dependency {
this.critical = read();
this.hadGlobalOrStickyRegExp = read();
this.request = read();
this._requestContext = read();
this.range = read();
this.valueRange = read();
this.prepend = read();
Expand Down
23 changes: 18 additions & 5 deletions lib/dependencies/ContextDependencyHelpers.js
Expand Up @@ -39,7 +39,7 @@ const splitContextFromPrefix = prefix => {

/** @typedef {Partial<Omit<ContextDependencyOptions, "resource">>} PartialContextDependencyOptions */

/** @typedef {{ new(options: ContextDependencyOptions, range: [number, number], valueRange: [number, number]): ContextDependency }} ContextDependencyConstructor */
/** @typedef {{ new(options: ContextDependencyOptions, range: [number, number], valueRange: [number, number], ...args: any[]): ContextDependency }} ContextDependencyConstructor */

/**
* @param {ContextDependencyConstructor} Dep the Dependency class
Expand All @@ -49,9 +49,19 @@ const splitContextFromPrefix = prefix => {
* @param {Pick<JavascriptParserOptions, `${"expr"|"wrapped"}Context${"Critical"|"Recursive"|"RegExp"}` | "exprContextRequest">} options options for context creation
* @param {PartialContextDependencyOptions} contextOptions options for the ContextModule
* @param {JavascriptParser} parser the parser
* @param {...any} depArgs depArgs
* @returns {ContextDependency} the created Dependency
*/
exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
exports.create = (
Dep,
range,
param,
expr,
options,
contextOptions,
parser,
...depArgs
) => {
if (param.isTemplateString()) {
let prefixRaw = param.quasis[0].string;
let postfixRaw =
Expand Down Expand Up @@ -97,7 +107,8 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
...contextOptions
},
range,
valueRange
valueRange,
...depArgs
);
dep.loc = expr.loc;
const replaces = [];
Expand Down Expand Up @@ -180,7 +191,8 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
...contextOptions
},
range,
valueRange
valueRange,
...depArgs
);
dep.loc = expr.loc;
const replaces = [];
Expand Down Expand Up @@ -218,7 +230,8 @@ exports.create = (Dep, range, param, expr, options, contextOptions, parser) => {
...contextOptions
},
range,
param.range
param.range,
...depArgs
);
dep.loc = expr.loc;
dep.critical =
Expand Down
16 changes: 0 additions & 16 deletions lib/dependencies/ContextElementDependency.js
Expand Up @@ -49,20 +49,6 @@ class ContextElementDependency extends ModuleDependency {
return "context element";
}

/**
* @returns {string | undefined} a request context
*/
getContext() {
return this._context;
}

/**
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
return `context${this._context || ""}|${super.getResourceIdentifier()}`;
}

get category() {
return this._category;
}
Expand All @@ -86,7 +72,6 @@ class ContextElementDependency extends ModuleDependency {
const { write } = context;
write(this._typePrefix);
write(this._category);
write(this._context);
write(this.referencedExports);
super.serialize(context);
}
Expand All @@ -95,7 +80,6 @@ class ContextElementDependency extends ModuleDependency {
const { read } = context;
this._typePrefix = read();
this._category = read();
this._context = read();
this.referencedExports = read();
super.deserialize(context);
}
Expand Down
12 changes: 11 additions & 1 deletion lib/dependencies/ModuleDependency.js
Expand Up @@ -26,13 +26,21 @@ class ModuleDependency extends Dependency {
// assertions must be serialized by subclasses that use it
/** @type {Record<string, any> | undefined} */
this.assertions = undefined;
this._context = undefined;
}

/**
* @returns {string | undefined} a request context
*/
getContext() {
return this._context;
}

/**
* @returns {string | null} an identifier to merge equal requests
*/
getResourceIdentifier() {
let str = `module${this.request}`;
let str = `context${this._context || ""}|module${this.request}`;
if (this.assertions !== undefined) {
str += JSON.stringify(this.assertions);
}
Expand Down Expand Up @@ -63,6 +71,7 @@ class ModuleDependency extends Dependency {
const { write } = context;
write(this.request);
write(this.userRequest);
write(this._context);
write(this.range);
super.serialize(context);
}
Expand All @@ -71,6 +80,7 @@ class ModuleDependency extends Dependency {
const { read } = context;
this.request = read();
this.userRequest = read();
this._context = read();
this.range = read();
super.deserialize(context);
}
Expand Down
4 changes: 2 additions & 2 deletions lib/dependencies/RequireResolveContextDependency.js
Expand Up @@ -10,8 +10,8 @@ const ContextDependency = require("./ContextDependency");
const ContextDependencyTemplateAsId = require("./ContextDependencyTemplateAsId");

class RequireResolveContextDependency extends ContextDependency {
constructor(options, range, valueRange) {
super(options);
constructor(options, range, valueRange, context) {
super(options, context);

this.range = range;
this.valueRange = valueRange;
Expand Down
3 changes: 2 additions & 1 deletion lib/dependencies/RequireResolveDependency.js
Expand Up @@ -15,10 +15,11 @@ const ModuleDependencyAsId = require("./ModuleDependencyTemplateAsId");
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */

class RequireResolveDependency extends ModuleDependency {
constructor(request, range) {
constructor(request, range, context) {
super(request);

this.range = range;
this._context = context;
}

get type() {
Expand Down

0 comments on commit 5d967db

Please sign in to comment.