rollup-plugin-concurrent-top-level-await 0.1.0 → 0.2.1
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/README.md +10 -3
- package/dist/index.d.mts +6 -1
- package/dist/index.mjs +36 -15
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -99,6 +99,14 @@ postponed until the subgraph is analyzed. This may lead to slower builds.
|
|
|
99
99
|
|
|
100
100
|
If you notice significant performance degradation, please open an issue.
|
|
101
101
|
|
|
102
|
+
### Exposed Module Structure
|
|
103
|
+
|
|
104
|
+
Because the execution of modules gets wrapped in functions, the bundled output will contain more information about the source module structure. This may be a consideration for projects where code obfuscation is important.
|
|
105
|
+
|
|
106
|
+
### Tree Shaking
|
|
107
|
+
|
|
108
|
+
Wrapping code in functions may reduce tree shaking effectiveness. We mitigate this where possible, such as by not wrapping declarations.
|
|
109
|
+
|
|
102
110
|
### Changing Variable Types
|
|
103
111
|
|
|
104
112
|
In the process of transforming the code, top level `const` declarations may get replaced with `let` declarations. This
|
|
@@ -106,7 +114,6 @@ can lead to `const` variables being assignable at runtime instead of throwing an
|
|
|
106
114
|
|
|
107
115
|
Additionally, variable declarations may be hoisted, which removes temporal dead zone (TDZ) checks.
|
|
108
116
|
|
|
109
|
-
###
|
|
117
|
+
### Default export class name
|
|
110
118
|
|
|
111
|
-
|
|
112
|
-
relies on a top level await expression, it may not work as expected.
|
|
119
|
+
When using `export default class {}`, the runtime `.name` of the exported value will be `<generatedVariablePrefix>_default` (e.g. `__tla_default`) instead of `default`.
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { FilterPattern } from "@rollup/pluginutils";
|
|
2
2
|
import * as magic_string0 from "magic-string";
|
|
3
3
|
import * as rollup0 from "rollup";
|
|
4
|
+
import { TransformPluginContext } from "rollup";
|
|
4
5
|
|
|
5
6
|
//#region src/index.d.ts
|
|
6
7
|
declare function concurrentTopLevelAwait(options?: {
|
|
@@ -17,7 +18,10 @@ declare function concurrentTopLevelAwait(options?: {
|
|
|
17
18
|
name: string;
|
|
18
19
|
apply: "build";
|
|
19
20
|
transform: {
|
|
20
|
-
handler(this:
|
|
21
|
+
handler(this: TransformPluginContext, code: string, id: string, transformOptions: {
|
|
22
|
+
ssr?: boolean | undefined;
|
|
23
|
+
attributes?: Record<string, string>;
|
|
24
|
+
} | undefined): Promise<{
|
|
21
25
|
code: string;
|
|
22
26
|
map: magic_string0.SourceMap | null;
|
|
23
27
|
} | undefined>;
|
|
@@ -25,6 +29,7 @@ declare function concurrentTopLevelAwait(options?: {
|
|
|
25
29
|
resolveImportMeta(this: rollup0.PluginContext, property: string | null, {
|
|
26
30
|
moduleId
|
|
27
31
|
}: {
|
|
32
|
+
attributes: Record<string, string>;
|
|
28
33
|
chunkId: string;
|
|
29
34
|
format: rollup0.InternalModuleFormat;
|
|
30
35
|
moduleId: string;
|
package/dist/index.mjs
CHANGED
|
@@ -129,7 +129,7 @@ var AsyncModuleTracker = class {
|
|
|
129
129
|
//#endregion
|
|
130
130
|
//#region src/transform.ts
|
|
131
131
|
function transform(s, ast, asyncImports, hasAwait, variablePrefix) {
|
|
132
|
-
const declarationsEnd =
|
|
132
|
+
const declarationsEnd = transformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variablePrefix);
|
|
133
133
|
s.appendRight(declarationsEnd, `async function ${variablePrefix}_initModuleExports() {\n`);
|
|
134
134
|
s.append("\n}\n");
|
|
135
135
|
const asyncDeps = `[${asyncImports.map((_, i) => `${variablePrefix}${i}`).join()}].flatMap(a => {
|
|
@@ -149,7 +149,7 @@ function transform(s, ast, asyncImports, hasAwait, variablePrefix) {
|
|
|
149
149
|
s.append(`if (import.meta.useTla) await ${variablePrefix}_initPromise;\n`);
|
|
150
150
|
s.append(`export function ${variablePrefix}_access() { return ${variablePrefix}; };\n`);
|
|
151
151
|
}
|
|
152
|
-
function
|
|
152
|
+
function transformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variablePrefix) {
|
|
153
153
|
let moduleScopeEnd = 0;
|
|
154
154
|
let i = 0;
|
|
155
155
|
for (const node of ast.body) {
|
|
@@ -158,11 +158,20 @@ function tansformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variable
|
|
|
158
158
|
s.appendLeft(node.end, tlaImport);
|
|
159
159
|
i++;
|
|
160
160
|
}
|
|
161
|
+
if (node.type === "ClassDeclaration") {
|
|
162
|
+
s.appendLeft(moduleScopeEnd, `let ${node.id.name};\n`);
|
|
163
|
+
s.appendRight(node.start, `${node.id.name} = `);
|
|
164
|
+
}
|
|
161
165
|
if (node.type === "ExportNamedDeclaration") {
|
|
162
166
|
if (node.declaration?.type === "VariableDeclaration") {
|
|
163
167
|
s.appendLeft(moduleScopeEnd, "export ");
|
|
164
168
|
s.remove(node.start, node.declaration.start);
|
|
165
169
|
moveVariableDeclarationToModuleScope(s, node.declaration, moduleScopeEnd);
|
|
170
|
+
} else if (node.declaration?.type === "ClassDeclaration") {
|
|
171
|
+
s.appendLeft(moduleScopeEnd, `export let ${node.declaration.id.name};\n`);
|
|
172
|
+
const declarationStart = getClassDeclarationStart(node.declaration);
|
|
173
|
+
s.remove(node.start, declarationStart);
|
|
174
|
+
s.appendRight(declarationStart, `${node.declaration.id.name} = `);
|
|
166
175
|
}
|
|
167
176
|
} else if (node.type === "VariableDeclaration") if (node.kind.endsWith("using")) moveVariableDeclarationWithUsingToModuleScope(s, node, moduleScopeEnd, variablePrefix);
|
|
168
177
|
else moveVariableDeclarationToModuleScope(s, node, moduleScopeEnd);
|
|
@@ -170,13 +179,15 @@ function tansformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variable
|
|
|
170
179
|
if (n.type === "VariableDeclaration" && n.kind === "var") moveVariableDeclarationToModuleScope(s, n, moduleScopeEnd);
|
|
171
180
|
return false;
|
|
172
181
|
});
|
|
173
|
-
if (node.type === "ExportDefaultDeclaration" && !
|
|
174
|
-
|
|
175
|
-
s.
|
|
176
|
-
|
|
182
|
+
if (node.type === "ExportDefaultDeclaration" && !isFunctionDeclaration(node.declaration.type)) {
|
|
183
|
+
const variableName = node.declaration.type === "ClassDeclaration" ? node.declaration.id?.name ?? `${variablePrefix}_default` : `${variablePrefix}_default`;
|
|
184
|
+
s.appendLeft(moduleScopeEnd, `let ${variableName};\nexport { ${variableName} as default };\n`);
|
|
185
|
+
const declarationStart = node.declaration.type === "ClassDeclaration" ? getClassDeclarationStart(node.declaration) : node.declaration.start;
|
|
186
|
+
s.remove(node.start, declarationStart);
|
|
187
|
+
s.appendRight(declarationStart, `${variableName} = (`);
|
|
177
188
|
s.appendLeft(node.declaration.end, ");");
|
|
178
189
|
}
|
|
179
|
-
if (
|
|
190
|
+
if (isFunctionDeclaration(node.type) || node.type === "ImportDeclaration" || node.type === "ExportDefaultDeclaration" && isFunctionDeclaration(node.declaration.type) || node.type === "ExportNamedDeclaration" && isFunctionDeclaration(node.declaration?.type) || node.type === "ExportNamedDeclaration" && node.declaration == null || node.type === "ExportAllDeclaration") if (node.start > moduleScopeEnd) {
|
|
180
191
|
s.appendLeft(node.end, "\n");
|
|
181
192
|
s.move(node.start, node.end, moduleScopeEnd);
|
|
182
193
|
s.appendLeft(node.start, ";");
|
|
@@ -184,8 +195,11 @@ function tansformAndMoveDeclarationsToModuleScope(s, ast, asyncImports, variable
|
|
|
184
195
|
}
|
|
185
196
|
return moduleScopeEnd;
|
|
186
197
|
}
|
|
187
|
-
function
|
|
188
|
-
return type === "
|
|
198
|
+
function isFunctionDeclaration(type) {
|
|
199
|
+
return type === "FunctionDeclaration";
|
|
200
|
+
}
|
|
201
|
+
function getClassDeclarationStart(node) {
|
|
202
|
+
return node.decorators[0]?.start ?? node.start;
|
|
189
203
|
}
|
|
190
204
|
function moveVariableDeclarationToModuleScope(s, node, declarationsEnd) {
|
|
191
205
|
const kind = replaceConstWithLet(node.kind);
|
|
@@ -229,13 +243,20 @@ function getNames(pattern) {
|
|
|
229
243
|
|
|
230
244
|
//#endregion
|
|
231
245
|
//#region src/index.ts
|
|
246
|
+
function resolveDeclarationSource(context, id, importerAttributes = {}, declaration) {
|
|
247
|
+
return context.resolve(declaration.source.value, id, {
|
|
248
|
+
attributes: Object.fromEntries(declaration.attributes.map((attr) => [attr.key.type === "Identifier" ? attr.key.name : attr.key.value, attr.value.value])),
|
|
249
|
+
importerAttributes,
|
|
250
|
+
custom: {}
|
|
251
|
+
});
|
|
252
|
+
}
|
|
232
253
|
function concurrentTopLevelAwait(options = {}) {
|
|
233
254
|
const filter = createFilter(options.include, options.exclude);
|
|
234
255
|
const asyncTracker = new AsyncModuleTracker();
|
|
235
256
|
return {
|
|
236
257
|
name: "rollup-plugin-concurrent-tla-plugin",
|
|
237
258
|
apply: "build",
|
|
238
|
-
transform: { async handler(code, id) {
|
|
259
|
+
transform: { async handler(code, id, transformOptions) {
|
|
239
260
|
if (!filter(id)) return;
|
|
240
261
|
const ast = this.parse(code);
|
|
241
262
|
const importDeclarations = ast.body.filter((a) => a.type === "ImportDeclaration");
|
|
@@ -244,14 +265,14 @@ function concurrentTopLevelAwait(options = {}) {
|
|
|
244
265
|
if (hasAwait) asyncTracker.setDependencies(id, []);
|
|
245
266
|
else {
|
|
246
267
|
const childrenIds = (await Promise.all(importDeclarations.map(async (declaration) => {
|
|
247
|
-
const importId = await this
|
|
268
|
+
const importId = await resolveDeclarationSource(this, id, transformOptions?.attributes, declaration);
|
|
248
269
|
if (!importId || !filter(importId.id)) return null;
|
|
249
270
|
return importId.id;
|
|
250
271
|
}))).filter((a) => a != null);
|
|
251
272
|
asyncTracker.setDependencies(id, childrenIds);
|
|
252
273
|
}
|
|
253
274
|
const asyncImports = (await Promise.all(importDeclarations.map(async (declaration) => {
|
|
254
|
-
const importId = await this
|
|
275
|
+
const importId = await resolveDeclarationSource(this, id, transformOptions?.attributes, declaration);
|
|
255
276
|
if (!importId || !filter(importId.id)) return null;
|
|
256
277
|
this.load(importId);
|
|
257
278
|
if (!await asyncTracker.isAsync(importId.id)) return null;
|
|
@@ -268,9 +289,9 @@ function concurrentTopLevelAwait(options = {}) {
|
|
|
268
289
|
resolveImportMeta(property, { moduleId }) {
|
|
269
290
|
if (property !== "useTla") return;
|
|
270
291
|
const moduleInfo = this.getModuleInfo(moduleId);
|
|
271
|
-
|
|
272
|
-
if (moduleInfo?.
|
|
273
|
-
if (importers
|
|
292
|
+
if (moduleInfo?.isEntry) return "true";
|
|
293
|
+
if (moduleInfo?.dynamicImporters.length) return "true";
|
|
294
|
+
if ((moduleInfo?.importers)?.some((id) => !filter(id))) return "true";
|
|
274
295
|
return "false";
|
|
275
296
|
}
|
|
276
297
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rollup-plugin-concurrent-top-level-await",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Rollup (and Vite) plugin enabling concurrent execution of modules that contain top level await.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"rollup-plugin",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/estree": "^1.0.8",
|
|
49
|
-
"prettier": "3.7.4"
|
|
49
|
+
"prettier": "3.7.4",
|
|
50
|
+
"rollup": "^4.57.1"
|
|
50
51
|
},
|
|
51
52
|
"scripts": {
|
|
52
53
|
"build": "tsdown --dts"
|