Skip to content

Commit

Permalink
Merge pull request #16996 from webpack/feat/destructuring-for-plugins
Browse files Browse the repository at this point in the history
support destructuring assignment in import.meta
  • Loading branch information
TheLarkInn committed Apr 15, 2023
2 parents 0076983 + 80b88c5 commit ee2fe97
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 27 deletions.
82 changes: 56 additions & 26 deletions lib/dependencies/ImportMetaPlugin.js
Expand Up @@ -75,6 +75,17 @@ class ImportMetaPlugin {
}

/// import.meta direct ///
const webpackVersion = parseInt(
require("../../package.json").version,
10
);
const importMetaUrl = () =>
JSON.stringify(getUrl(parser.state.module));
const importMetaWebpackVersion = () => JSON.stringify(webpackVersion);
const importMetaUnknownProperty = members =>
`${Template.toNormalComment(
"unsupported import.meta." + members.join(".")
)} undefined${propertyAccess(members, 1)}`;
parser.hooks.typeof
.for("import.meta")
.tap(
Expand All @@ -84,20 +95,48 @@ class ImportMetaPlugin {
parser.hooks.expression
.for("import.meta")
.tap(PLUGIN_NAME, metaProperty => {
const CriticalDependencyWarning = getCriticalDependencyWarning();
parser.state.module.addWarning(
new ModuleDependencyWarning(
parser.state.module,
new CriticalDependencyWarning(
"Accessing import.meta directly is unsupported (only property access is supported)"
),
metaProperty.loc
)
);
const dep = new ConstDependency(
`${parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""}({})`,
metaProperty.range
);
const referencedPropertiesInDestructuring =
parser.destructuringAssignmentPropertiesFor(metaProperty);
if (!referencedPropertiesInDestructuring) {
const CriticalDependencyWarning =
getCriticalDependencyWarning();
parser.state.module.addWarning(
new ModuleDependencyWarning(
parser.state.module,
new CriticalDependencyWarning(
"Accessing import.meta directly is unsupported (only property access or destructuring is supported)"
),
metaProperty.loc
)
);
const dep = new ConstDependency(
`${
parser.isAsiPosition(metaProperty.range[0]) ? ";" : ""
}({})`,
metaProperty.range
);
dep.loc = metaProperty.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
}

let str = "";
for (const prop of referencedPropertiesInDestructuring) {
switch (prop) {
case "url":
str += `url: ${importMetaUrl()},`;
break;
case "webpack":
str += `webpack: ${importMetaWebpackVersion()},`;
break;
default:
str += `[${JSON.stringify(
prop
)}]: ${importMetaUnknownProperty([prop])},`;
break;
}
}
const dep = new ConstDependency(`({${str}})`, metaProperty.range);
dep.loc = metaProperty.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
Expand All @@ -120,10 +159,7 @@ class ImportMetaPlugin {
parser.hooks.expression
.for("import.meta.url")
.tap(PLUGIN_NAME, expr => {
const dep = new ConstDependency(
JSON.stringify(getUrl(parser.state.module)),
expr.range
);
const dep = new ConstDependency(importMetaUrl(), expr.range);
dep.loc = expr.loc;
parser.state.module.addPresentationalDependency(dep);
return true;
Expand All @@ -140,10 +176,6 @@ class ImportMetaPlugin {
});

/// import.meta.webpack ///
const webpackVersion = parseInt(
require("../../package.json").version,
10
);
parser.hooks.typeof
.for("import.meta.webpack")
.tap(
Expand All @@ -154,7 +186,7 @@ class ImportMetaPlugin {
.for("import.meta.webpack")
.tap(
PLUGIN_NAME,
toConstantDependency(parser, JSON.stringify(webpackVersion))
toConstantDependency(parser, importMetaWebpackVersion())
);
parser.hooks.evaluateTypeof
.for("import.meta.webpack")
Expand All @@ -168,9 +200,7 @@ class ImportMetaPlugin {
.for("import.meta")
.tap(PLUGIN_NAME, (expr, members) => {
const dep = new ConstDependency(
`${Template.toNormalComment(
"unsupported import.meta." + members.join(".")
)} undefined${propertyAccess(members, 1)}`,
importMetaUnknownProperty(members),
expr.range
);
dep.loc = expr.loc;
Expand Down
13 changes: 12 additions & 1 deletion test/cases/esm/import-meta/index.js
Expand Up @@ -42,5 +42,16 @@ it("should return undefined for unknown property", () => {
expect(import.meta.other).toBe(undefined);
if (typeof import.meta.other !== "undefined") require("fail");
expect(() => import.meta.other.other.other).toThrowError();
// if (typeof import.meta.other.other.other !== "undefined") require("fail");
});

it("should add warning on direct import.meta usage", () => {
expect(Object.keys(import.meta)).toHaveLength(0);
});

it("should support destructuring assignment", () => {
let version, url2, c;
({ webpack: version } = { url: url2 } = { c } = import.meta);
expect(version).toBeTypeOf("number");
expect(url2).toBe(url);
expect(c).toBe(undefined);
});
5 changes: 5 additions & 0 deletions test/cases/esm/import-meta/warnings.js
@@ -0,0 +1,5 @@
module.exports = [
[
/Accessing import.meta directly is unsupported \(only property access or destructuring is supported\)/
]
];

0 comments on commit ee2fe97

Please sign in to comment.