Skip to content

Commit

Permalink
Merge pull request #15246 from pavelsavara/import_meta_url
Browse files Browse the repository at this point in the history
Disable compile time evaluation of import.meta.url
  • Loading branch information
sokra committed Jan 28, 2022
2 parents 1e73ca7 + 232403c commit 46e8639
Show file tree
Hide file tree
Showing 15 changed files with 132 additions and 4 deletions.
4 changes: 4 additions & 0 deletions declarations/WebpackOptions.d.ts
Expand Up @@ -2949,6 +2949,10 @@ export interface JavascriptParserOptions {
* Specifies the behavior of invalid export names in "import ... from ...".
*/
importExportsPresence?: "error" | "warn" | "auto" | false;
/**
* Enable/disable evaluating import.meta.
*/
importMeta?: boolean;
/**
* Include polyfills or mocks for various node stuff.
*/
Expand Down
1 change: 1 addition & 0 deletions lib/config/defaults.js
Expand Up @@ -469,6 +469,7 @@ const applyJavascriptParserOptionsDefaults = (
D(parserOptions, "wrappedContextRecursive", true);
D(parserOptions, "wrappedContextCritical", false);
D(parserOptions, "strictThisContextOnImports", false);
D(parserOptions, "importMeta", true);
if (futureDefaults) D(parserOptions, "exportsPresence", "error");
};

Expand Down
25 changes: 22 additions & 3 deletions lib/dependencies/ImportMetaPlugin.js
Expand Up @@ -20,6 +20,7 @@ const propertyAccess = require("../util/propertyAccess");
const ConstDependency = require("./ConstDependency");

/** @typedef {import("estree").MemberExpression} MemberExpression */
/** @typedef {import("../../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../NormalModule")} NormalModule */
/** @typedef {import("../javascript/JavascriptParser")} Parser */
Expand All @@ -44,11 +45,29 @@ class ImportMetaPlugin {
return pathToFileURL(module.resource).toString();
};
/**
* @param {Parser} parser parser
* @param {Object} parserOptions parserOptions
* @param {Parser} parser parser parser
* @param {JavascriptParserOptions} parserOptions parserOptions
* @returns {void}
*/
const parserHandler = (parser, parserOptions) => {
const parserHandler = (parser, { importMeta }) => {
if (importMeta === false) {
const { importMetaName } = compilation.outputOptions;
if (importMetaName === "import.meta") return;

parser.hooks.expression
.for("import.meta")
.tap("ImportMetaPlugin", metaProperty => {
const dep = new ConstDependency(
importMetaName,
metaProperty.range
);
dep.loc = metaProperty.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
});
return;
}

/// import.meta direct ///
parser.hooks.typeof
.for("import.meta")
Expand Down
2 changes: 1 addition & 1 deletion schemas/WebpackOptions.check.js

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions schemas/WebpackOptions.json
Expand Up @@ -1608,6 +1608,10 @@
"description": "Specifies the behavior of invalid export names in \"import ... from ...\".",
"enum": ["error", "warn", "auto", false]
},
"importMeta": {
"description": "Enable/disable evaluating import.meta.",
"type": "boolean"
},
"node": {
"$ref": "#/definitions/Node"
},
Expand Down
1 change: 1 addition & 0 deletions test/Defaults.unittest.js
Expand Up @@ -218,6 +218,7 @@ describe("Defaults", () => {
"exprContextRecursive": true,
"exprContextRegExp": false,
"exprContextRequest": ".",
"importMeta": true,
"strictExportPresence": undefined,
"strictThisContextOnImports": false,
"unknownContextCritical": true,
Expand Down
52 changes: 52 additions & 0 deletions test/__snapshots__/Cli.basictest.js.snap
Expand Up @@ -1612,6 +1612,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-auto-import-meta": Object {
"configs": Array [
Object {
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"path": "module.parser.javascript/auto.importMeta",
"type": "boolean",
},
],
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-auto-node": Object {
"configs": Array [
Object {
Expand Down Expand Up @@ -2163,6 +2176,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-dynamic-import-meta": Object {
"configs": Array [
Object {
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"path": "module.parser.javascript/dynamic.importMeta",
"type": "boolean",
},
],
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-dynamic-node": Object {
"configs": Array [
Object {
Expand Down Expand Up @@ -2675,6 +2701,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-esm-import-meta": Object {
"configs": Array [
Object {
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"path": "module.parser.javascript/esm.importMeta",
"type": "boolean",
},
],
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-esm-node": Object {
"configs": Array [
Object {
Expand Down Expand Up @@ -3132,6 +3171,19 @@ Object {
"multiple": false,
"simpleType": "string",
},
"module-parser-javascript-import-meta": Object {
"configs": Array [
Object {
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"path": "module.parser.javascript.importMeta",
"type": "boolean",
},
],
"description": "Enable/disable evaluating import.meta.",
"multiple": false,
"simpleType": "boolean",
},
"module-parser-javascript-node": Object {
"configs": Array [
Object {
Expand Down
6 changes: 6 additions & 0 deletions test/configCases/module/externals/index.js
@@ -1,7 +1,13 @@
import imported from "./imported.mjs";
import value from "./module";
import { metaUrl } from "./meta";
const localMetaUrl = import.meta.url;

it("should allow to use externals in concatenated modules", () => {
expect(imported).toBe(42);
expect(value).toBe(40);
});

it("all bundled files should have same url, when parser.javascript.importMeta === false", () => {
expect(localMetaUrl).toBe(metaUrl)
});
1 change: 1 addition & 0 deletions test/configCases/module/externals/meta.js
@@ -0,0 +1 @@
export const metaUrl = import.meta.url;
7 changes: 7 additions & 0 deletions test/configCases/module/externals/webpack.config.js
@@ -1,5 +1,12 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
module: {
parser: {
javascript: {
importMeta: false
}
}
},
entry: {
main: "./index.js",
imported: {
Expand Down
1 change: 1 addition & 0 deletions test/configCases/output/import-meta-name/a.js
@@ -0,0 +1 @@
export const url = import.meta.url;
9 changes: 9 additions & 0 deletions test/configCases/output/import-meta-name/index.js
@@ -0,0 +1,9 @@
import { url } from "./a";

it("should evaluate import.meta to pseudoImport.meta", () => {
expect(url).toBe("http://test.co/path/index.js");
});

it("should evaluate import.meta in runtime", () => {
expect(url).toBe(import.meta.url);
});
5 changes: 5 additions & 0 deletions test/configCases/output/import-meta-name/test.config.js
@@ -0,0 +1,5 @@
module.exports = {
moduleScope(scope) {
scope.pseudoImport = { meta: { url: "http://test.co/path/index.js" } };
}
};
13 changes: 13 additions & 0 deletions test/configCases/output/import-meta-name/webpack.config.js
@@ -0,0 +1,13 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
output: {
importMetaName: "pseudoImport.meta"
},
module: {
parser: {
javascript: {
importMeta: false
}
}
}
};
5 changes: 5 additions & 0 deletions types.d.ts
Expand Up @@ -5472,6 +5472,11 @@ declare interface JavascriptParserOptions {
*/
importExportsPresence?: false | "auto" | "error" | "warn";

/**
* Enable/disable evaluating import.meta.
*/
importMeta?: boolean;

/**
* Include polyfills or mocks for various node stuff.
*/
Expand Down

0 comments on commit 46e8639

Please sign in to comment.