Skip to content

Commit

Permalink
Merge pull request #17281 from webpack/feat-environment-to-loader-con…
Browse files Browse the repository at this point in the history
…text

feat: support `environment` in loader context
  • Loading branch information
TheLarkInn committed May 31, 2023
2 parents e0cd928 + 9c7693b commit 6d8d96b
Show file tree
Hide file tree
Showing 16 changed files with 201 additions and 9 deletions.
7 changes: 7 additions & 0 deletions declarations/LoaderContext.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
ImportModuleOptions
} from "../lib/dependencies/LoaderPlugin";
import type { Resolver } from "enhanced-resolve";
import type { Environment } from "./WebpackOptions";

type ResolveCallback = Parameters<Resolver["resolve"]>[4];
type Schema = Parameters<typeof validate>[0];
Expand Down Expand Up @@ -219,6 +220,12 @@ export interface LoaderRunnerLoaderContext<OptionsType> {
* Example: "web"
*/
target: string;

/**
* Tell what kind of ES-features may be used in the generated runtime-code.
* Example: { arrowFunction: true }
*/
environment: Environment;
}

type AdditionalData = {
Expand Down
8 changes: 8 additions & 0 deletions declarations/WebpackOptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2246,10 +2246,18 @@ export interface Environment {
* The environment supports an async import() function to import EcmaScript modules.
*/
dynamicImport?: boolean;
/**
* The environment supports an async import() is available when creating a worker.
*/
dynamicImportInWorker?: boolean;
/**
* The environment supports 'for of' iteration ('for (const x of array) { ... }').
*/
forOf?: boolean;
/**
* The environment supports 'globalThis'.
*/
globalThis?: boolean;
/**
* The environment supports EcmaScript Module syntax to import EcmaScript modules (import ... from '...').
*/
Expand Down
42 changes: 34 additions & 8 deletions lib/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ const applyWebpackOptionsDefaults = options => {

applyLoaderDefaults(
/** @type {NonNullable<WebpackOptions["loader"]>} */ (options.loader),
{ targetProperties }
{ targetProperties, environment: options.output.environment }
);

F(options, "externalsType", () => {
Expand Down Expand Up @@ -1036,6 +1036,22 @@ const applyOutputDefaults = (
* @returns {boolean | undefined} true, when v is truthy or undefined, or c is truthy
*/
const conditionallyOptimistic = (v, c) => (v === undefined && c) || v;

F(
environment,
"globalThis",
() => /** @type {boolean | undefined} */ (tp && tp.globalThis)
);
F(
environment,
"bigIntLiteral",
() => /** @type {boolean | undefined} */ (tp && tp.bigIntLiteral)
);
F(
environment,
"const",
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
);
F(
environment,
"arrowFunction",
Expand All @@ -1044,8 +1060,8 @@ const applyOutputDefaults = (
);
F(
environment,
"const",
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.const))
"forOf",
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
);
F(
environment,
Expand All @@ -1055,20 +1071,28 @@ const applyOutputDefaults = (
);
F(
environment,
"forOf",
() => tp && optimistic(/** @type {boolean | undefined} */ (tp.forOf))
"optionalChaining",
() =>
tp && optimistic(/** @type {boolean | undefined} */ (tp.optionalChaining))
);
F(
environment,
"bigIntLiteral",
() => /** @type {boolean | undefined} */ (tp && tp.bigIntLiteral)
"templateLiteral",
() =>
tp && optimistic(/** @type {boolean | undefined} */ (tp.templateLiteral))
);
F(environment, "dynamicImport", () =>
conditionallyOptimistic(
/** @type {boolean | undefined} */ (tp && tp.dynamicImport),
output.module
)
);
F(environment, "dynamicImportInWorker", () =>
conditionallyOptimistic(
/** @type {boolean | undefined} */ (tp && tp.dynamicImportInWorker),
output.module
)
);
F(environment, "module", () =>
conditionallyOptimistic(
/** @type {boolean | undefined} */ (tp && tp.module),
Expand Down Expand Up @@ -1215,9 +1239,10 @@ const applyExternalsPresetsDefaults = (
* @param {Loader} loader options
* @param {Object} options options
* @param {TargetProperties | false} options.targetProperties target properties
* @param {Environment} options.environment environment
* @returns {void}
*/
const applyLoaderDefaults = (loader, { targetProperties }) => {
const applyLoaderDefaults = (loader, { targetProperties, environment }) => {
F(loader, "target", () => {
if (targetProperties) {
if (targetProperties.electron) {
Expand All @@ -1231,6 +1256,7 @@ const applyLoaderDefaults = (loader, { targetProperties }) => {
if (targetProperties.web) return "web";
}
});
D(loader, "environment", environment);
};

/**
Expand Down
2 changes: 1 addition & 1 deletion schemas/WebpackOptions.check.js

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions schemas/WebpackOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -744,10 +744,18 @@
"description": "The environment supports an async import() function to import EcmaScript modules.",
"type": "boolean"
},
"dynamicImportInWorker": {
"description": "The environment supports an async import() is available when creating a worker.",
"type": "boolean"
},
"forOf": {
"description": "The environment supports 'for of' iteration ('for (const x of array) { ... }').",
"type": "boolean"
},
"globalThis": {
"description": "The environment supports 'globalThis'.",
"type": "boolean"
},
"module": {
"description": "The environment supports EcmaScript Module syntax to import EcmaScript modules (import ... from '...').",
"type": "boolean"
Expand Down
58 changes: 58 additions & 0 deletions test/Defaults.unittest.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,19 @@ describe("snapshots", () => {
"ignoreWarnings": undefined,
"infrastructureLogging": Object {},
"loader": Object {
"environment": Object {
"arrowFunction": true,
"bigIntLiteral": undefined,
"const": true,
"destructuring": true,
"dynamicImport": undefined,
"dynamicImportInWorker": undefined,
"forOf": true,
"globalThis": undefined,
"module": undefined,
"optionalChaining": true,
"templateLiteral": true,
},
"target": "web",
},
"mode": "none",
Expand Down Expand Up @@ -331,8 +344,12 @@ describe("snapshots", () => {
"const": true,
"destructuring": true,
"dynamicImport": undefined,
"dynamicImportInWorker": undefined,
"forOf": true,
"globalThis": undefined,
"module": undefined,
"optionalChaining": true,
"templateLiteral": true,
},
"filename": "[name].js",
"globalObject": "self",
Expand Down Expand Up @@ -885,11 +902,21 @@ describe("snapshots", () => {
- "externalsType": "var",
+ "externalsType": "module",
@@ ... @@
- "dynamicImport": undefined,
- "dynamicImportInWorker": undefined,
+ "dynamicImport": true,
+ "dynamicImportInWorker": true,
@@ ... @@
- "module": undefined,
+ "module": true,
@@ ... @@
- "chunkFilename": "[name].js",
+ "chunkFilename": "[name].mjs",
@@ ... @@
- "dynamicImport": undefined,
- "dynamicImportInWorker": undefined,
+ "dynamicImport": true,
+ "dynamicImportInWorker": true,
@@ ... @@
- "module": undefined,
+ "module": true,
Expand Down Expand Up @@ -1991,6 +2018,29 @@ describe("snapshots", () => {
- "context": "<cwd>",
+ "context": "<cwd>/test/fixtures/browserslist",
@@ ... @@
- "arrowFunction": true,
- "bigIntLiteral": undefined,
- "const": true,
- "destructuring": true,
- "dynamicImport": undefined,
- "dynamicImportInWorker": undefined,
- "forOf": true,
- "globalThis": undefined,
- "module": undefined,
- "optionalChaining": true,
- "templateLiteral": true,
+ "arrowFunction": false,
+ "bigIntLiteral": false,
+ "const": false,
+ "destructuring": false,
+ "dynamicImport": false,
+ "dynamicImportInWorker": false,
+ "forOf": false,
+ "globalThis": false,
+ "module": false,
+ "optionalChaining": false,
+ "templateLiteral": false,
@@ ... @@
- "chunkLoadingGlobal": "webpackChunkwebpack",
+ "chunkLoadingGlobal": "webpackChunkbrowserslist_test",
@@ ... @@
Expand All @@ -2002,15 +2052,23 @@ describe("snapshots", () => {
- "const": true,
- "destructuring": true,
- "dynamicImport": undefined,
- "dynamicImportInWorker": undefined,
- "forOf": true,
- "globalThis": undefined,
- "module": undefined,
- "optionalChaining": true,
- "templateLiteral": true,
+ "arrowFunction": false,
+ "bigIntLiteral": false,
+ "const": false,
+ "destructuring": false,
+ "dynamicImport": false,
+ "dynamicImportInWorker": false,
+ "forOf": false,
+ "globalThis": false,
+ "module": false,
+ "optionalChaining": false,
+ "templateLiteral": false,
@@ ... @@
- "hotUpdateGlobal": "webpackHotUpdatewebpack",
+ "hotUpdateGlobal": "webpackHotUpdatebrowserslist_test",
Expand Down
26 changes: 26 additions & 0 deletions test/__snapshots__/Cli.basictest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5946,6 +5946,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"output-environment-dynamic-import-in-worker": Object {
"configs": Array [
Object {
"description": "The environment supports an async import() is available when creating a worker.",
"multiple": false,
"path": "output.environment.dynamicImportInWorker",
"type": "boolean",
},
],
"description": "The environment supports an async import() is available when creating a worker.",
"multiple": false,
"simpleType": "boolean",
},
"output-environment-for-of": Object {
"configs": Array [
Object {
Expand All @@ -5959,6 +5972,19 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"output-environment-global-this": Object {
"configs": Array [
Object {
"description": "The environment supports 'globalThis'.",
"multiple": false,
"path": "output.environment.globalThis",
"type": "boolean",
},
],
"description": "The environment supports 'globalThis'.",
"multiple": false,
"simpleType": "boolean",
},
"output-environment-module": Object {
"configs": Array [
Object {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ module.exports = {
"const": false,
"destructuring": false,
"dynamicImport": false,
"dynamicImportInWorker": false,
"forOf": false,
"globalThis": false,
"module": false,
"optionalChaining": false,
"templateLiteral": false,
}
`);
expect(compilation.options.externalsPresets).toMatchInlineSnapshot(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ module.exports = {
"const": false,
"destructuring": false,
"dynamicImport": false,
"dynamicImportInWorker": false,
"forOf": false,
"globalThis": false,
"module": false,
"optionalChaining": false,
"templateLiteral": false,
}
`);
expect(compilation.options.externalsPresets).toMatchInlineSnapshot(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ module.exports = {
"const": false,
"destructuring": false,
"dynamicImport": false,
"dynamicImportInWorker": false,
"forOf": false,
"globalThis": false,
"module": false,
"optionalChaining": false,
"templateLiteral": false,
}
`);
expect(compilation.options.externalsPresets).toMatchInlineSnapshot(`
Expand Down
4 changes: 4 additions & 0 deletions test/configCases/ecmaVersion/browserslist/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@ module.exports = {
"const": true,
"destructuring": true,
"dynamicImport": true,
"dynamicImportInWorker": false,
"forOf": true,
"globalThis": true,
"module": true,
"optionalChaining": true,
"templateLiteral": true,
}
`);
expect(compilation.options.externalsPresets).toMatchInlineSnapshot(`
Expand Down
9 changes: 9 additions & 0 deletions test/configCases/ecmaVersion/loader-context/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import mod from "./loader.js!./module";

it("should compile and export target and environment", function() {
expect(mod.target).toBe("node");
expect(mod.environment.globalThis).toBe(false);
expect(mod.environment.optionalChaining).toBe(true);
expect(mod.environment.templateLiteral).toBe(true);
expect(mod.environment.dynamicImportInWorker).toBe(true);
});
7 changes: 7 additions & 0 deletions test/configCases/ecmaVersion/loader-context/loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import("../../../../types").LoaderDefinition<{}>} */
module.exports = function loader(content) {
const target = this.target;
const environment = this.environment;

return `export default ${JSON.stringify({ target, environment})}`;
}
1 change: 1 addition & 0 deletions test/configCases/ecmaVersion/loader-context/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default "test";
10 changes: 10 additions & 0 deletions test/configCases/ecmaVersion/loader-context/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/** @type {import("../../../../").Configuration} */
module.exports = {
target: ["node", "es2020"],
output: {
environment: {
// Our target supports `globalThis`, but for test purposes we set it to `false`
globalThis: false
}
}
};

0 comments on commit 6d8d96b

Please sign in to comment.