@git.zone/tsbundle 2.11.4 → 2.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/interfaces/index.d.ts +3 -0
- package/dist_ts/mod_custom/index.d.ts +10 -3
- package/dist_ts/mod_custom/index.js +278 -86
- package/dist_ts/mod_esbuild/index.child.d.ts +4 -8
- package/dist_ts/mod_esbuild/index.child.js +54 -44
- package/dist_ts/mod_esbuild/plugins.d.ts +5 -2
- package/dist_ts/mod_esbuild/plugins.js +5 -3
- package/dist_ts/mod_esbuild/workerplugin.d.ts +12 -0
- package/dist_ts/mod_esbuild/workerplugin.js +254 -0
- package/dist_ts/mod_output/artifactpublisher.d.ts +43 -0
- package/dist_ts/mod_output/artifactpublisher.js +925 -0
- package/dist_ts/mod_output/index.d.ts +1 -0
- package/dist_ts/mod_output/index.js +11 -3
- package/dist_ts/mod_presets/index.js +2 -1
- package/dist_ts/mod_rolldown/index.child.d.ts +4 -2
- package/dist_ts/mod_rolldown/index.child.js +48 -36
- package/dist_ts/mod_rspack/index.child.d.ts +4 -2
- package/dist_ts/mod_rspack/index.child.js +76 -115
- package/dist_ts/plugins.d.ts +3 -1
- package/dist_ts/plugins.js +4 -2
- package/dist_ts/tsbundle.class.tsbundle.js +98 -16
- package/package.json +7 -5
- package/readme.hints.md +20 -4
- package/readme.md +29 -6
- package/third-party-notices.md +29 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/interfaces/index.ts +3 -0
- package/ts/mod_custom/index.ts +348 -96
- package/ts/mod_esbuild/index.child.ts +81 -47
- package/ts/mod_esbuild/plugins.ts +9 -2
- package/ts/mod_esbuild/workerplugin.ts +328 -0
- package/ts/mod_output/artifactpublisher.ts +1185 -0
- package/ts/mod_output/index.ts +10 -2
- package/ts/mod_presets/index.ts +1 -0
- package/ts/mod_rolldown/index.child.ts +66 -42
- package/ts/mod_rspack/index.child.ts +98 -127
- package/ts/plugins.ts +3 -1
- package/ts/tsbundle.class.tsbundle.ts +102 -14
|
@@ -2,13 +2,20 @@ import * as plugins from './plugins.js';
|
|
|
2
2
|
import * as paths from '../paths.js';
|
|
3
3
|
import * as interfaces from '../interfaces/index.js';
|
|
4
4
|
import { logger } from '../tsbundle.logging.js';
|
|
5
|
+
import { workerPlugin } from './workerplugin.js';
|
|
6
|
+
import {
|
|
7
|
+
cleanupBuildStage,
|
|
8
|
+
createBuildStage,
|
|
9
|
+
getChunkNamespace,
|
|
10
|
+
publishGeneratedArtifacts,
|
|
11
|
+
} from '../mod_output/artifactpublisher.js';
|
|
5
12
|
|
|
6
13
|
export class TsBundleProcess {
|
|
7
14
|
constructor() {
|
|
8
15
|
// Nothing here
|
|
9
16
|
}
|
|
10
17
|
|
|
11
|
-
public async getAliases() {
|
|
18
|
+
public async getAliases(): Promise<Record<string, string>> {
|
|
12
19
|
try {
|
|
13
20
|
const aliasObject: Record<string, string> = {};
|
|
14
21
|
const tsconfigPath = plugins.path.join(paths.cwd, 'tsconfig.json');
|
|
@@ -27,56 +34,74 @@ export class TsBundleProcess {
|
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
return aliasObject;
|
|
30
|
-
} catch
|
|
37
|
+
} catch {
|
|
31
38
|
return {};
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
private async build(
|
|
43
|
+
fromArg: string,
|
|
44
|
+
toArg: string,
|
|
45
|
+
argvArg: interfaces.ICliOptions,
|
|
46
|
+
productionArg: boolean,
|
|
47
|
+
): Promise<void> {
|
|
48
|
+
const logicalOutputName = plugins.path.basename(argvArg.chunkOwner || toArg);
|
|
49
|
+
const chunkNamespace = getChunkNamespace(logicalOutputName);
|
|
50
|
+
const outputDirectory = plugins.path.dirname(toArg);
|
|
51
|
+
const stage = createBuildStage(outputDirectory);
|
|
52
|
+
const stageMainPath = plugins.path.join(stage.stageDirectory, plugins.path.basename(toArg));
|
|
53
|
+
try {
|
|
54
|
+
await plugins.esbuild.build({
|
|
55
|
+
absWorkingDir: process.cwd(),
|
|
56
|
+
entryPoints: [fromArg],
|
|
57
|
+
bundle: true,
|
|
58
|
+
sourcemap: argvArg.sourcemap !== false,
|
|
59
|
+
...(argvArg.banner !== undefined ? {
|
|
60
|
+
banner: { js: argvArg.banner },
|
|
61
|
+
} : {}),
|
|
62
|
+
format: 'esm',
|
|
63
|
+
target: 'es2022',
|
|
64
|
+
minify: productionArg,
|
|
65
|
+
keepNames: true,
|
|
66
|
+
entryNames: plugins.path.parse(toArg).name,
|
|
67
|
+
outdir: stage.stageDirectory,
|
|
68
|
+
tsconfig: paths.tsconfigPath,
|
|
69
|
+
splitting: false,
|
|
70
|
+
treeShaking: false,
|
|
71
|
+
chunkNames: `chunks/${chunkNamespace}/[name]-[hash]`,
|
|
72
|
+
alias: await this.getAliases(),
|
|
73
|
+
plugins: [workerPlugin()],
|
|
74
|
+
});
|
|
75
|
+
await publishGeneratedArtifacts({
|
|
76
|
+
sourceDirectory: stage.stageDirectory,
|
|
77
|
+
sourceMainPath: stageMainPath,
|
|
78
|
+
targetPath: toArg,
|
|
79
|
+
logicalOutputName,
|
|
80
|
+
chunkNamespace,
|
|
81
|
+
sourceMapsEnabled: argvArg.sourcemap !== false,
|
|
82
|
+
});
|
|
83
|
+
} finally {
|
|
84
|
+
cleanupBuildStage(stage.stageDirectory, outputDirectory, stage.marker);
|
|
85
|
+
}
|
|
54
86
|
}
|
|
55
87
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
88
|
+
public async buildTest(
|
|
89
|
+
fromArg: string,
|
|
90
|
+
toArg: string,
|
|
91
|
+
argvArg: interfaces.ICliOptions,
|
|
92
|
+
): Promise<void> {
|
|
93
|
+
await this.build(fromArg, toArg, argvArg, false);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public async buildProduction(
|
|
97
|
+
fromArg: string,
|
|
98
|
+
toArg: string,
|
|
99
|
+
argvArg: interfaces.ICliOptions,
|
|
100
|
+
): Promise<void> {
|
|
61
101
|
console.log('esbuild specific:');
|
|
62
102
|
console.log(`from: ${fromArg}`);
|
|
63
103
|
console.log(`to: ${toArg}`);
|
|
64
|
-
|
|
65
|
-
entryPoints: [fromArg],
|
|
66
|
-
bundle: true,
|
|
67
|
-
sourcemap: argvArg.sourcemap !== false,
|
|
68
|
-
format: 'esm',
|
|
69
|
-
target: 'es2022',
|
|
70
|
-
minify: true,
|
|
71
|
-
keepNames: true,
|
|
72
|
-
entryNames: plugins.path.parse(toArg).name,
|
|
73
|
-
outdir: plugins.path.parse(toArg).dir,
|
|
74
|
-
tsconfig: paths.tsconfigPath,
|
|
75
|
-
splitting: false,
|
|
76
|
-
treeShaking: false,
|
|
77
|
-
chunkNames: 'chunks/[name]-[hash]',
|
|
78
|
-
alias: await this.getAliases(),
|
|
79
|
-
});
|
|
104
|
+
await this.build(fromArg, toArg, argvArg, true);
|
|
80
105
|
}
|
|
81
106
|
}
|
|
82
107
|
|
|
@@ -121,15 +146,24 @@ const run = async () => {
|
|
|
121
146
|
);
|
|
122
147
|
}
|
|
123
148
|
process.exit(0);
|
|
124
|
-
} catch (error:
|
|
149
|
+
} catch (error: unknown) {
|
|
125
150
|
console.error('\n\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
|
|
126
151
|
console.error('\x1b[31m❌ BUILD FAILED\x1b[0m');
|
|
127
152
|
console.error('\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
128
153
|
|
|
129
|
-
|
|
154
|
+
const errorData = typeof error === 'object' && error !== null
|
|
155
|
+
? error as {
|
|
156
|
+
errors?: Array<{
|
|
157
|
+
location?: { file?: string; line?: number; column?: number };
|
|
158
|
+
text: string;
|
|
159
|
+
}>;
|
|
160
|
+
message?: string;
|
|
161
|
+
}
|
|
162
|
+
: undefined;
|
|
163
|
+
if (Array.isArray(errorData?.errors)) {
|
|
130
164
|
// esbuild errors - format them nicely
|
|
131
|
-
console.error(`Found ${
|
|
132
|
-
for (const err of
|
|
165
|
+
console.error(`Found ${errorData.errors.length} error(s):\n`);
|
|
166
|
+
for (const err of errorData.errors) {
|
|
133
167
|
const file = err.location?.file || 'unknown';
|
|
134
168
|
const line = err.location?.line || '?';
|
|
135
169
|
const column = err.location?.column || '?';
|
|
@@ -137,7 +171,7 @@ const run = async () => {
|
|
|
137
171
|
console.error(` ${err.text}\n`);
|
|
138
172
|
}
|
|
139
173
|
} else {
|
|
140
|
-
console.error(
|
|
174
|
+
console.error(errorData?.message || error);
|
|
141
175
|
}
|
|
142
176
|
|
|
143
177
|
console.error('\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
export * from '../plugins.js';
|
|
2
2
|
|
|
3
|
-
import esbuild
|
|
3
|
+
import esbuild, {
|
|
4
|
+
type BuildOptions,
|
|
5
|
+
type Loader,
|
|
6
|
+
type Plugin,
|
|
7
|
+
} from 'esbuild';
|
|
8
|
+
import MagicString from 'magic-string';
|
|
9
|
+
import ts from 'typescript';
|
|
4
10
|
|
|
5
|
-
export { esbuild };
|
|
11
|
+
export { esbuild, MagicString, ts };
|
|
12
|
+
export type { BuildOptions, Loader, Plugin };
|
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Derived from @chialab/esbuild-plugin-worker 0.19.2.
|
|
3
|
+
* Copyright (c) 2021 Chialab. Licensed under the MIT License.
|
|
4
|
+
* See third-party-notices.md in the published package.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import * as plugins from './plugins.js';
|
|
8
|
+
|
|
9
|
+
interface IWorkerPluginOptions {
|
|
10
|
+
constructors?: string[];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
interface IWorkerReference {
|
|
14
|
+
argument: plugins.ts.NewExpression;
|
|
15
|
+
module: boolean;
|
|
16
|
+
value: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface IWorkerBuildState {
|
|
20
|
+
dependencyGraph: Map<string, Set<string>>;
|
|
21
|
+
emittedWorkers: Map<string, Promise<string>>;
|
|
22
|
+
parentKey: string;
|
|
23
|
+
parentOutputDirectory: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const rootWorkerKey = 'tsbundle:main';
|
|
27
|
+
|
|
28
|
+
const hasDependencyPath = (
|
|
29
|
+
graphArg: Map<string, Set<string>>,
|
|
30
|
+
fromKeyArg: string,
|
|
31
|
+
targetKeyArg: string,
|
|
32
|
+
visitedArg = new Set<string>(),
|
|
33
|
+
): boolean => {
|
|
34
|
+
if (fromKeyArg === targetKeyArg) {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
if (visitedArg.has(fromKeyArg)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
visitedArg.add(fromKeyArg);
|
|
41
|
+
for (const dependencyKey of graphArg.get(fromKeyArg) || []) {
|
|
42
|
+
if (hasDependencyPath(graphArg, dependencyKey, targetKeyArg, visitedArg)) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const addWorkerDependency = (
|
|
50
|
+
graphArg: Map<string, Set<string>>,
|
|
51
|
+
parentKeyArg: string,
|
|
52
|
+
childKeyArg: string,
|
|
53
|
+
): void => {
|
|
54
|
+
if (hasDependencyPath(graphArg, childKeyArg, parentKeyArg)) {
|
|
55
|
+
throw new Error(`Cyclic module-worker dependency detected: ${parentKeyArg} -> ${childKeyArg}`);
|
|
56
|
+
}
|
|
57
|
+
const dependencies = graphArg.get(parentKeyArg) || new Set<string>();
|
|
58
|
+
dependencies.add(childKeyArg);
|
|
59
|
+
graphArg.set(parentKeyArg, dependencies);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const getLoader = (filePathArg: string): plugins.Loader => {
|
|
63
|
+
switch (plugins.path.extname(filePathArg)) {
|
|
64
|
+
case '.tsx':
|
|
65
|
+
return 'tsx';
|
|
66
|
+
case '.jsx':
|
|
67
|
+
return 'jsx';
|
|
68
|
+
case '.ts':
|
|
69
|
+
case '.mts':
|
|
70
|
+
case '.cts':
|
|
71
|
+
return 'ts';
|
|
72
|
+
default:
|
|
73
|
+
return 'js';
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const getScriptKind = (filePathArg: string): plugins.ts.ScriptKind => {
|
|
78
|
+
switch (plugins.path.extname(filePathArg)) {
|
|
79
|
+
case '.tsx':
|
|
80
|
+
return plugins.ts.ScriptKind.TSX;
|
|
81
|
+
case '.jsx':
|
|
82
|
+
return plugins.ts.ScriptKind.JSX;
|
|
83
|
+
case '.ts':
|
|
84
|
+
case '.mts':
|
|
85
|
+
case '.cts':
|
|
86
|
+
return plugins.ts.ScriptKind.TS;
|
|
87
|
+
default:
|
|
88
|
+
return plugins.ts.ScriptKind.JS;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
const isImportMetaUrl = (nodeArg: plugins.ts.Node): boolean => {
|
|
93
|
+
return plugins.ts.isPropertyAccessExpression(nodeArg)
|
|
94
|
+
&& nodeArg.name.text === 'url'
|
|
95
|
+
&& plugins.ts.isMetaProperty(nodeArg.expression)
|
|
96
|
+
&& nodeArg.expression.keywordToken === plugins.ts.SyntaxKind.ImportKeyword
|
|
97
|
+
&& nodeArg.expression.name.text === 'meta';
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const getWorkerConstructorName = (nodeArg: plugins.ts.Expression): string | undefined => {
|
|
101
|
+
if (plugins.ts.isIdentifier(nodeArg)) {
|
|
102
|
+
return nodeArg.text;
|
|
103
|
+
}
|
|
104
|
+
if (
|
|
105
|
+
plugins.ts.isPropertyAccessExpression(nodeArg)
|
|
106
|
+
&& plugins.ts.isIdentifier(nodeArg.expression)
|
|
107
|
+
&& ['window', 'globalThis', 'self', 'global'].includes(nodeArg.expression.text)
|
|
108
|
+
) {
|
|
109
|
+
return nodeArg.name.text;
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const isModuleWorker = (optionsArg: plugins.ts.Expression | undefined): boolean => {
|
|
115
|
+
if (!optionsArg || !plugins.ts.isObjectLiteralExpression(optionsArg)) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
return optionsArg.properties.some((property) => (
|
|
119
|
+
plugins.ts.isPropertyAssignment(property)
|
|
120
|
+
&& property.name.getText() === 'type'
|
|
121
|
+
&& plugins.ts.isStringLiteral(property.initializer)
|
|
122
|
+
&& property.initializer.text === 'module'
|
|
123
|
+
));
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const workerPlugin = ({
|
|
127
|
+
constructors = ['Worker', 'SharedWorker'],
|
|
128
|
+
}: IWorkerPluginOptions = {}, stateArg?: IWorkerBuildState): plugins.Plugin => {
|
|
129
|
+
const state: IWorkerBuildState = stateArg || {
|
|
130
|
+
dependencyGraph: new Map<string, Set<string>>(),
|
|
131
|
+
emittedWorkers: new Map<string, Promise<string>>(),
|
|
132
|
+
parentKey: rootWorkerKey,
|
|
133
|
+
parentOutputDirectory: '',
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const plugin: plugins.Plugin = {
|
|
137
|
+
name: 'tsbundle-worker',
|
|
138
|
+
setup(pluginBuild) {
|
|
139
|
+
pluginBuild.onLoad({
|
|
140
|
+
filter: /\.[cm]?[jt]sx?$/,
|
|
141
|
+
namespace: 'file',
|
|
142
|
+
}, async (args) => {
|
|
143
|
+
const code = await plugins.fsPromises.readFile(args.path, 'utf8');
|
|
144
|
+
if (!constructors.some((constructorName) => code.includes(`new ${constructorName}`))) {
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
const sourceFile = plugins.ts.createSourceFile(
|
|
149
|
+
args.path,
|
|
150
|
+
code,
|
|
151
|
+
plugins.ts.ScriptTarget.Latest,
|
|
152
|
+
true,
|
|
153
|
+
getScriptKind(args.path),
|
|
154
|
+
);
|
|
155
|
+
const localClasses = new Set<string>();
|
|
156
|
+
const symbols = new Map<string, string>();
|
|
157
|
+
const references: IWorkerReference[] = [];
|
|
158
|
+
|
|
159
|
+
const collectDeclarations = (node: plugins.ts.Node): void => {
|
|
160
|
+
if (plugins.ts.isClassDeclaration(node) && node.name) {
|
|
161
|
+
localClasses.add(node.name.text);
|
|
162
|
+
} else if (
|
|
163
|
+
plugins.ts.isVariableDeclaration(node)
|
|
164
|
+
&& plugins.ts.isIdentifier(node.name)
|
|
165
|
+
&& node.initializer
|
|
166
|
+
&& plugins.ts.isStringLiteral(node.initializer)
|
|
167
|
+
) {
|
|
168
|
+
symbols.set(node.name.text, node.initializer.text);
|
|
169
|
+
}
|
|
170
|
+
plugins.ts.forEachChild(node, collectDeclarations);
|
|
171
|
+
};
|
|
172
|
+
collectDeclarations(sourceFile);
|
|
173
|
+
|
|
174
|
+
const collectReferences = (node: plugins.ts.Node): void => {
|
|
175
|
+
if (plugins.ts.isNewExpression(node)) {
|
|
176
|
+
const constructorName = getWorkerConstructorName(node.expression);
|
|
177
|
+
const argument = node.arguments?.[0];
|
|
178
|
+
if (
|
|
179
|
+
constructorName
|
|
180
|
+
&& constructors.includes(constructorName)
|
|
181
|
+
&& !localClasses.has(constructorName)
|
|
182
|
+
&& argument
|
|
183
|
+
&& plugins.ts.isNewExpression(argument)
|
|
184
|
+
&& plugins.ts.isIdentifier(argument.expression)
|
|
185
|
+
&& argument.expression.text === 'URL'
|
|
186
|
+
&& argument.arguments?.length === 2
|
|
187
|
+
&& isImportMetaUrl(argument.arguments[1])
|
|
188
|
+
) {
|
|
189
|
+
const reference = argument.arguments[0];
|
|
190
|
+
const value = plugins.ts.isStringLiteral(reference)
|
|
191
|
+
? reference.text
|
|
192
|
+
: plugins.ts.isIdentifier(reference)
|
|
193
|
+
? symbols.get(reference.text)
|
|
194
|
+
: undefined;
|
|
195
|
+
if (value) {
|
|
196
|
+
references.push({
|
|
197
|
+
argument,
|
|
198
|
+
module: isModuleWorker(node.arguments?.[1]),
|
|
199
|
+
value,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
plugins.ts.forEachChild(node, collectReferences);
|
|
205
|
+
};
|
|
206
|
+
collectReferences(sourceFile);
|
|
207
|
+
if (references.length === 0) {
|
|
208
|
+
return undefined;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const outdir = pluginBuild.initialOptions.outdir;
|
|
212
|
+
const chunkNames = pluginBuild.initialOptions.chunkNames;
|
|
213
|
+
if (!outdir || !chunkNames) {
|
|
214
|
+
throw new Error('Module workers require esbuild outdir and chunkNames options.');
|
|
215
|
+
}
|
|
216
|
+
const workerEntryPattern = chunkNames.replace('[name]', 'worker');
|
|
217
|
+
const workerOutputDirectoryRaw = plugins.path.dirname(workerEntryPattern);
|
|
218
|
+
const workerOutputDirectory = workerOutputDirectoryRaw === '.'
|
|
219
|
+
? ''
|
|
220
|
+
: workerOutputDirectoryRaw;
|
|
221
|
+
if (
|
|
222
|
+
plugins.path.isAbsolute(workerOutputDirectory)
|
|
223
|
+
|| workerOutputDirectory === '..'
|
|
224
|
+
|| workerOutputDirectory.startsWith(`..${plugins.path.sep}`)
|
|
225
|
+
|| /\[[^\]]+\]/.test(workerOutputDirectory)
|
|
226
|
+
) {
|
|
227
|
+
throw new Error(`Module-worker output directory must stay fixed within esbuild outdir: ${chunkNames}`);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
const magicString = new plugins.MagicString(code);
|
|
231
|
+
const watchFiles = new Set<string>([args.path]);
|
|
232
|
+
for (const reference of references) {
|
|
233
|
+
const resolved = await pluginBuild.resolve(reference.value, {
|
|
234
|
+
kind: 'dynamic-import',
|
|
235
|
+
importer: args.path,
|
|
236
|
+
namespace: 'file',
|
|
237
|
+
resolveDir: plugins.path.dirname(args.path),
|
|
238
|
+
});
|
|
239
|
+
if (resolved.external) {
|
|
240
|
+
continue;
|
|
241
|
+
}
|
|
242
|
+
if (!resolved.path) {
|
|
243
|
+
throw new Error(`Unable to resolve worker entry '${reference.value}' from ${args.path}.`);
|
|
244
|
+
}
|
|
245
|
+
watchFiles.add(resolved.path);
|
|
246
|
+
|
|
247
|
+
const canonicalWorkerPath = await plugins.fsPromises.realpath(resolved.path);
|
|
248
|
+
const cacheKey = `${reference.module ? 'module' : 'classic'}:${canonicalWorkerPath}`;
|
|
249
|
+
addWorkerDependency(state.dependencyGraph, state.parentKey, cacheKey);
|
|
250
|
+
let emittedWorkerPromise = state.emittedWorkers.get(cacheKey);
|
|
251
|
+
if (!emittedWorkerPromise) {
|
|
252
|
+
emittedWorkerPromise = (async () => {
|
|
253
|
+
const initialOptions = pluginBuild.initialOptions;
|
|
254
|
+
const workerResult = await plugins.esbuild.build({
|
|
255
|
+
...initialOptions,
|
|
256
|
+
entryPoints: [resolved.path],
|
|
257
|
+
stdin: undefined,
|
|
258
|
+
outfile: undefined,
|
|
259
|
+
outdir,
|
|
260
|
+
entryNames: workerEntryPattern,
|
|
261
|
+
bundle: true,
|
|
262
|
+
format: reference.module ? 'esm' : 'iife',
|
|
263
|
+
platform: initialOptions.platform || 'browser',
|
|
264
|
+
splitting: false,
|
|
265
|
+
metafile: true,
|
|
266
|
+
write: true,
|
|
267
|
+
plugins: [workerPlugin({ constructors }, {
|
|
268
|
+
dependencyGraph: state.dependencyGraph,
|
|
269
|
+
emittedWorkers: state.emittedWorkers,
|
|
270
|
+
parentKey: cacheKey,
|
|
271
|
+
parentOutputDirectory: workerOutputDirectory,
|
|
272
|
+
})],
|
|
273
|
+
});
|
|
274
|
+
const outputEntry = Object.entries(workerResult.metafile.outputs).find(([, output]) => (
|
|
275
|
+
!!output.entryPoint && !output.cssBundle
|
|
276
|
+
));
|
|
277
|
+
if (!outputEntry) {
|
|
278
|
+
throw new Error(`Worker build produced no JavaScript output for ${resolved.path}.`);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const outputPath = plugins.path.isAbsolute(outputEntry[0])
|
|
282
|
+
? outputEntry[0]
|
|
283
|
+
: plugins.path.resolve(initialOptions.absWorkingDir || process.cwd(), outputEntry[0]);
|
|
284
|
+
const relativeOutputPath = plugins.path.relative(outdir, outputPath);
|
|
285
|
+
if (
|
|
286
|
+
relativeOutputPath === '..'
|
|
287
|
+
|| relativeOutputPath.startsWith(`..${plugins.path.sep}`)
|
|
288
|
+
|| plugins.path.isAbsolute(relativeOutputPath)
|
|
289
|
+
) {
|
|
290
|
+
throw new Error(`Worker output escaped esbuild outdir: ${outputPath}`);
|
|
291
|
+
}
|
|
292
|
+
return relativeOutputPath;
|
|
293
|
+
})();
|
|
294
|
+
state.emittedWorkers.set(cacheKey, emittedWorkerPromise);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
const emittedWorker = await emittedWorkerPromise;
|
|
298
|
+
const relativeWorkerPath = plugins.path.relative(
|
|
299
|
+
state.parentOutputDirectory || '.',
|
|
300
|
+
emittedWorker,
|
|
301
|
+
).split(plugins.path.sep).join('/');
|
|
302
|
+
const workerUrl = relativeWorkerPath.startsWith('.')
|
|
303
|
+
? relativeWorkerPath
|
|
304
|
+
: `./${relativeWorkerPath}`;
|
|
305
|
+
magicString.overwrite(
|
|
306
|
+
reference.argument.getStart(sourceFile),
|
|
307
|
+
reference.argument.end,
|
|
308
|
+
`new URL('${workerUrl}', import.meta.url).href`,
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const sourceMap = magicString.generateMap({
|
|
313
|
+
source: plugins.path.basename(args.path),
|
|
314
|
+
includeContent: true,
|
|
315
|
+
hires: true,
|
|
316
|
+
});
|
|
317
|
+
return {
|
|
318
|
+
contents: `${magicString.toString()}\n//# sourceMappingURL=${sourceMap.toUrl()}`,
|
|
319
|
+
loader: getLoader(args.path),
|
|
320
|
+
resolveDir: plugins.path.dirname(args.path),
|
|
321
|
+
watchFiles: [...watchFiles],
|
|
322
|
+
};
|
|
323
|
+
});
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
return plugin;
|
|
328
|
+
};
|