Skip to content

Commit 7e85649

Browse files
committed
improve target options
infer target properties from different targets and fill defaults from that custom targets can now be created via `target: false` and a plugin (similar to the other options) add stubs from universal chunk/wasm loading and module chunk format add externalsPresets.electron and externalsPresets.electronRenderer node.__file/dirname: "eval-only"
1 parent 48010fb commit 7e85649

23 files changed

Lines changed: 796 additions & 541 deletions

cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@
180180
"etags",
181181
"destructure",
182182
"onconnect",
183+
"nwjs",
183184

184185
"webassemblyjs",
185186
"fsevents",

declarations/WebpackOptions.d.ts

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -544,20 +544,9 @@ export type StatsValue =
544544
| boolean
545545
| StatsOptions;
546546
/**
547-
* Environment to build for.
547+
* Environment to build for. An array of environments to build for all of them when possible.
548548
*/
549-
export type Target =
550-
| (
551-
| "web"
552-
| "webworker"
553-
| "node"
554-
| "async-node"
555-
| "node-webkit"
556-
| "electron-main"
557-
| "electron-renderer"
558-
| "electron-preload"
559-
)
560-
| ((compiler: import("../lib/Compiler")) => void);
549+
export type Target = [string, ...string[]] | false | string;
561550
/**
562551
* Enter watch mode, which rebuilds on file change.
563552
*/
@@ -720,7 +709,7 @@ export interface WebpackOptions {
720709
*/
721710
stats?: StatsValue;
722711
/**
723-
* Environment to build for.
712+
* Environment to build for. An array of environments to build for all of them when possible.
724713
*/
725714
target?: Target;
726715
/**
@@ -939,6 +928,10 @@ export interface Experiments {
939928
* Enable presets of externals for specific targets.
940929
*/
941930
export interface ExternalsPresets {
931+
/**
932+
* Treat common electron built-in modules in main and preload context like 'electron', 'ipc' or 'shell' as external and load them via require() when used.
933+
*/
934+
electron?: boolean;
942935
/**
943936
* Treat electron built-in modules in the main context like 'app', 'ipc-main' or 'shell' as external and load them via require() when used.
944937
*/
@@ -947,14 +940,18 @@ export interface ExternalsPresets {
947940
* Treat electron built-in modules in the preload context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.
948941
*/
949942
electronPreload?: boolean;
943+
/**
944+
* Treat electron built-in modules in the renderer context like 'web-frame', 'ipc-renderer' or 'shell' as external and load them via require() when used.
945+
*/
946+
electronRenderer?: boolean;
950947
/**
951948
* Treat node.js built-in modules like fs, path or vm as external and load them via require() when used.
952949
*/
953950
node?: boolean;
954951
/**
955-
* Treat node-webkit legacy nw.gui module as external and load it via require() when used.
952+
* Treat NW.js legacy nw.gui module as external and load it via require() when used.
956953
*/
957-
nodeWebkit?: boolean;
954+
nwjs?: boolean;
958955
/**
959956
* Treat references to 'http(s)://...' and 'std:...' as external and load them via import when used (Note that this changes execution order as externals are executed before any other code in the chunk).
960957
*/
@@ -1308,11 +1305,11 @@ export interface NodeOptions {
13081305
/**
13091306
* Include a polyfill for the '__dirname' variable.
13101307
*/
1311-
__dirname?: false | true | "mock";
1308+
__dirname?: false | true | "mock" | "eval-only";
13121309
/**
13131310
* Include a polyfill for the '__filename' variable.
13141311
*/
1315-
__filename?: false | true | "mock";
1312+
__filename?: false | true | "mock" | "eval-only";
13161313
/**
13171314
* Include a polyfill for the 'global' variable.
13181315
*/
@@ -1836,21 +1833,13 @@ export interface Environment {
18361833
*/
18371834
const?: boolean;
18381835
/**
1839-
* The environment supports destructing ('{ a, b } = obj').
1836+
* The environment supports destructuring ('{ a, b } = obj').
18401837
*/
1841-
destructing?: boolean;
1838+
destructuring?: boolean;
18421839
/**
18431840
* The environment supports 'for of' iteration ('for (const x of array) { ... }').
18441841
*/
18451842
forOf?: boolean;
1846-
/**
1847-
* The environment supports a global 'global' variable which points to the global context.
1848-
*/
1849-
global?: boolean;
1850-
/**
1851-
* The environment supports a global 'globalThis' variable which points to the global context.
1852-
*/
1853-
globalThis?: boolean;
18541843
/**
18551844
* The environment supports an async import() function to import EcmaScript modules.
18561845
*/
@@ -2607,7 +2596,7 @@ export interface WebpackOptionsNormalized {
26072596
*/
26082597
stats: StatsValue;
26092598
/**
2610-
* Environment to build for.
2599+
* Environment to build for. An array of environments to build for all of them when possible.
26112600
*/
26122601
target?: Target;
26132602
/**

lib/NodeStuffPlugin.js

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@
55

66
"use strict";
77

8+
const RuntimeGlobals = require("./RuntimeGlobals");
89
const CachedConstDependency = require("./dependencies/CachedConstDependency");
10+
const ConstDependency = require("./dependencies/ConstDependency");
911
const {
1012
evaluateToString,
1113
expressionIsUnsupported
1214
} = require("./javascript/JavascriptParserHelpers");
1315
const { relative } = require("./util/fs");
16+
const { parseResource } = require("./util/identifier");
1417

1518
/** @typedef {import("webpack-sources").ReplaceSource} ReplaceSource */
1619
/** @typedef {import("./Compiler")} Compiler */
@@ -41,6 +44,20 @@ class NodeStuffPlugin {
4144
localOptions = { ...localOptions, ...parserOptions.node };
4245
}
4346

47+
if (localOptions.global) {
48+
parser.hooks.expression
49+
.for("global")
50+
.tap("NodeStuffPlugin", expr => {
51+
const dep = new ConstDependency(
52+
RuntimeGlobals.global,
53+
expr.range,
54+
[RuntimeGlobals.global]
55+
);
56+
dep.loc = expr.loc;
57+
parser.state.module.addPresentationalDependency(dep);
58+
});
59+
}
60+
4461
const setModuleConstant = (expressionName, fn) => {
4562
parser.hooks.expression
4663
.for(expressionName)
@@ -63,7 +80,7 @@ class NodeStuffPlugin {
6380
if (localOptions.__filename) {
6481
if (localOptions.__filename === "mock") {
6582
setConstant("__filename", "/index.js");
66-
} else {
83+
} else if (localOptions.__filename === true) {
6784
setModuleConstant("__filename", module =>
6885
relative(compiler.inputFileSystem, context, module.resource)
6986
);
@@ -72,17 +89,14 @@ class NodeStuffPlugin {
7289
.for("__filename")
7390
.tap("NodeStuffPlugin", expr => {
7491
if (!parser.state.module) return;
75-
const resource = parser.state.module.resource;
76-
const i = resource.indexOf("?");
77-
return evaluateToString(
78-
i < 0 ? resource : resource.substr(0, i)
79-
)(expr);
92+
const resource = parseResource(parser.state.module.resource);
93+
return evaluateToString(resource.path)(expr);
8094
});
8195
}
8296
if (localOptions.__dirname) {
8397
if (localOptions.__dirname === "mock") {
8498
setConstant("__dirname", "/");
85-
} else {
99+
} else if (localOptions.__dirname === true) {
86100
setModuleConstant("__dirname", module =>
87101
relative(compiler.inputFileSystem, context, module.context)
88102
);

lib/RuntimeTemplate.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ class RuntimeTemplate {
7575
return this.outputOptions.environment.forOf;
7676
}
7777

78-
supportsDestructing() {
79-
return this.outputOptions.environment.destructing;
78+
supportsDestructuring() {
79+
return this.outputOptions.environment.destructuring;
8080
}
8181

8282
supportsBigIntLiteral() {
@@ -104,7 +104,7 @@ class RuntimeTemplate {
104104
}
105105

106106
destructureArray(items, value) {
107-
return this.supportsDestructing()
107+
return this.supportsDestructuring()
108108
? `var [${items.join(", ")}] = ${value};`
109109
: Template.asString(
110110
items.map((item, i) => `var ${item} = ${value}[${i}];`)

lib/WebpackOptionsApply.js

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,32 +70,33 @@ class WebpackOptionsApply extends OptionsApply {
7070
compiler.recordsInputPath = options.recordsInputPath || null;
7171
compiler.recordsOutputPath = options.recordsOutputPath || null;
7272
compiler.name = options.name;
73-
if (typeof options.target === "string") {
74-
switch (options.target) {
75-
case "web":
76-
case "webworker": {
77-
const NodeSourcePlugin = require("./node/NodeSourcePlugin");
78-
new NodeSourcePlugin(options.node).apply(compiler);
79-
break;
80-
}
81-
}
82-
} else {
83-
options.target(compiler);
84-
}
8573

8674
if (options.externalsPresets.node) {
8775
const NodeTargetPlugin = require("./node/NodeTargetPlugin");
8876
new NodeTargetPlugin().apply(compiler);
8977
}
9078
if (options.externalsPresets.electronMain) {
9179
const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
92-
new ElectronTargetPlugin(true).apply(compiler);
80+
new ElectronTargetPlugin("main").apply(compiler);
9381
}
9482
if (options.externalsPresets.electronPreload) {
9583
const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
96-
new ElectronTargetPlugin(false).apply(compiler);
84+
new ElectronTargetPlugin("preload").apply(compiler);
9785
}
98-
if (options.externalsPresets.nodeWebkit) {
86+
if (options.externalsPresets.electronRenderer) {
87+
const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
88+
new ElectronTargetPlugin("renderer").apply(compiler);
89+
}
90+
if (
91+
options.externalsPresets.electron &&
92+
!options.externalsPresets.electronMain &&
93+
!options.externalsPresets.electronPreload &&
94+
!options.externalsPresets.electronRenderer
95+
) {
96+
const ElectronTargetPlugin = require("./electron/ElectronTargetPlugin");
97+
new ElectronTargetPlugin().apply(compiler);
98+
}
99+
if (options.externalsPresets.nwjs) {
99100
const ExternalsPlugin = require("./ExternalsPlugin");
100101
new ExternalsPlugin("commonjs", "nw.gui").apply(compiler);
101102
}
@@ -121,6 +122,10 @@ class WebpackOptionsApply extends OptionsApply {
121122
new CommonJsChunkFormatPlugin().apply(compiler);
122123
break;
123124
}
125+
case "module":
126+
throw new Error(
127+
"EcmaScript Module CHunk Format is not implemented yet"
128+
);
124129
default:
125130
throw new Error(
126131
"Unsupported chunk format '" + options.output.chunkFormat + "'."

0 commit comments

Comments
 (0)