@git.zone/tsbundle 2.11.3 → 2.12.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 +1 -0
- package/dist_ts/mod_custom/index.d.ts +10 -3
- package/dist_ts/mod_custom/index.js +277 -86
- package/dist_ts/mod_esbuild/index.child.d.ts +4 -8
- package/dist_ts/mod_esbuild/index.child.js +51 -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_rolldown/index.child.d.ts +4 -2
- package/dist_ts/mod_rolldown/index.child.js +47 -36
- package/dist_ts/mod_rspack/index.child.d.ts +4 -2
- package/dist_ts/mod_rspack/index.child.js +73 -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 +10 -9
- package/readme.hints.md +20 -4
- package/readme.md +23 -6
- package/third-party-notices.md +29 -0
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/interfaces/index.ts +1 -0
- package/ts/mod_custom/index.ts +347 -96
- package/ts/mod_esbuild/index.child.ts +78 -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_rolldown/index.child.ts +65 -42
- package/ts/mod_rspack/index.child.ts +95 -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,71 @@ 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
|
+
format: 'esm',
|
|
60
|
+
target: 'es2022',
|
|
61
|
+
minify: productionArg,
|
|
62
|
+
keepNames: true,
|
|
63
|
+
entryNames: plugins.path.parse(toArg).name,
|
|
64
|
+
outdir: stage.stageDirectory,
|
|
65
|
+
tsconfig: paths.tsconfigPath,
|
|
66
|
+
splitting: false,
|
|
67
|
+
treeShaking: false,
|
|
68
|
+
chunkNames: `chunks/${chunkNamespace}/[name]-[hash]`,
|
|
69
|
+
alias: await this.getAliases(),
|
|
70
|
+
plugins: [workerPlugin()],
|
|
71
|
+
});
|
|
72
|
+
await publishGeneratedArtifacts({
|
|
73
|
+
sourceDirectory: stage.stageDirectory,
|
|
74
|
+
sourceMainPath: stageMainPath,
|
|
75
|
+
targetPath: toArg,
|
|
76
|
+
logicalOutputName,
|
|
77
|
+
chunkNamespace,
|
|
78
|
+
sourceMapsEnabled: argvArg.sourcemap !== false,
|
|
79
|
+
});
|
|
80
|
+
} finally {
|
|
81
|
+
cleanupBuildStage(stage.stageDirectory, outputDirectory, stage.marker);
|
|
82
|
+
}
|
|
54
83
|
}
|
|
55
84
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
85
|
+
public async buildTest(
|
|
86
|
+
fromArg: string,
|
|
87
|
+
toArg: string,
|
|
88
|
+
argvArg: interfaces.ICliOptions,
|
|
89
|
+
): Promise<void> {
|
|
90
|
+
await this.build(fromArg, toArg, argvArg, false);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public async buildProduction(
|
|
94
|
+
fromArg: string,
|
|
95
|
+
toArg: string,
|
|
96
|
+
argvArg: interfaces.ICliOptions,
|
|
97
|
+
): Promise<void> {
|
|
61
98
|
console.log('esbuild specific:');
|
|
62
99
|
console.log(`from: ${fromArg}`);
|
|
63
100
|
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
|
-
});
|
|
101
|
+
await this.build(fromArg, toArg, argvArg, true);
|
|
80
102
|
}
|
|
81
103
|
}
|
|
82
104
|
|
|
@@ -121,15 +143,24 @@ const run = async () => {
|
|
|
121
143
|
);
|
|
122
144
|
}
|
|
123
145
|
process.exit(0);
|
|
124
|
-
} catch (error:
|
|
146
|
+
} catch (error: unknown) {
|
|
125
147
|
console.error('\n\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m');
|
|
126
148
|
console.error('\x1b[31m❌ BUILD FAILED\x1b[0m');
|
|
127
149
|
console.error('\x1b[31m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
128
150
|
|
|
129
|
-
|
|
151
|
+
const errorData = typeof error === 'object' && error !== null
|
|
152
|
+
? error as {
|
|
153
|
+
errors?: Array<{
|
|
154
|
+
location?: { file?: string; line?: number; column?: number };
|
|
155
|
+
text: string;
|
|
156
|
+
}>;
|
|
157
|
+
message?: string;
|
|
158
|
+
}
|
|
159
|
+
: undefined;
|
|
160
|
+
if (Array.isArray(errorData?.errors)) {
|
|
130
161
|
// esbuild errors - format them nicely
|
|
131
|
-
console.error(`Found ${
|
|
132
|
-
for (const err of
|
|
162
|
+
console.error(`Found ${errorData.errors.length} error(s):\n`);
|
|
163
|
+
for (const err of errorData.errors) {
|
|
133
164
|
const file = err.location?.file || 'unknown';
|
|
134
165
|
const line = err.location?.line || '?';
|
|
135
166
|
const column = err.location?.column || '?';
|
|
@@ -137,7 +168,7 @@ const run = async () => {
|
|
|
137
168
|
console.error(` ${err.text}\n`);
|
|
138
169
|
}
|
|
139
170
|
} else {
|
|
140
|
-
console.error(
|
|
171
|
+
console.error(errorData?.message || error);
|
|
141
172
|
}
|
|
142
173
|
|
|
143
174
|
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
|
+
};
|