@atlaspack/core 2.29.2 → 2.30.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/CHANGELOG.md +20 -0
- package/dist/applyRuntimes.js +79 -1
- package/dist/requests/AssetGraphRequest.js +32 -22
- package/dist/requests/BundleGraphRequest.js +2 -2
- package/lib/applyRuntimes.js +87 -3
- package/lib/requests/AssetGraphRequest.js +32 -22
- package/lib/requests/BundleGraphRequest.js +2 -2
- package/lib/types/requests/AssetGraphRequest.d.ts +2 -0
- package/lib/types/types.d.ts +2 -1
- package/package.json +11 -11
- package/src/applyRuntimes.ts +98 -0
- package/src/requests/AssetGraphRequest.ts +46 -32
- package/src/requests/BundleGraphRequest.ts +13 -11
- package/src/types.ts +2 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/applyRuntimes.ts
CHANGED
|
@@ -9,6 +9,7 @@ import type {
|
|
|
9
9
|
DevDepRequest,
|
|
10
10
|
AtlaspackOptions,
|
|
11
11
|
DevDepRequestRef,
|
|
12
|
+
DependencyNode,
|
|
12
13
|
} from './types';
|
|
13
14
|
import type {AtlaspackConfig} from './AtlaspackConfig';
|
|
14
15
|
import type PluginOptions from './public/PluginOptions';
|
|
@@ -19,6 +20,7 @@ import assert from 'assert';
|
|
|
19
20
|
import invariant from 'assert';
|
|
20
21
|
import nullthrows from 'nullthrows';
|
|
21
22
|
import {nodeFromAssetGroup} from './AssetGraph';
|
|
23
|
+
import type AssetGraph from './AssetGraph';
|
|
22
24
|
import BundleGraph from './public/BundleGraph';
|
|
23
25
|
import InternalBundleGraph, {bundleGraphEdgeTypes} from './BundleGraph';
|
|
24
26
|
import {NamedBundle} from './public/Bundle';
|
|
@@ -33,6 +35,7 @@ import {toProjectPath, fromProjectPathRelative} from './projectPath';
|
|
|
33
35
|
import {tracer, PluginTracer} from '@atlaspack/profiler';
|
|
34
36
|
import {DefaultMap} from '@atlaspack/utils';
|
|
35
37
|
import {fromEnvironmentId} from './EnvironmentManager';
|
|
38
|
+
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
36
39
|
|
|
37
40
|
type RuntimeConnection = {
|
|
38
41
|
bundle: InternalBundle;
|
|
@@ -152,6 +155,7 @@ export default async function applyRuntimes<TResult extends RequestResult>({
|
|
|
152
155
|
env,
|
|
153
156
|
runtimeAssetRequiringExecutionOnLoad,
|
|
154
157
|
priority,
|
|
158
|
+
symbolData,
|
|
155
159
|
} of runtimeAssets) {
|
|
156
160
|
let sourceName = path.join(
|
|
157
161
|
path.dirname(filePath),
|
|
@@ -170,6 +174,7 @@ export default async function applyRuntimes<TResult extends RequestResult>({
|
|
|
170
174
|
// Runtime assets should be considered source, as they should be
|
|
171
175
|
// e.g. compiled to run in the target environment
|
|
172
176
|
isSource: true,
|
|
177
|
+
symbolData,
|
|
173
178
|
};
|
|
174
179
|
|
|
175
180
|
let connectionBundle = bundle;
|
|
@@ -276,6 +281,11 @@ export default async function applyRuntimes<TResult extends RequestResult>({
|
|
|
276
281
|
let {assetGraph: runtimesAssetGraph, changedAssets} =
|
|
277
282
|
await reconcileNewRuntimes(api, connections, optionsRef);
|
|
278
283
|
|
|
284
|
+
if (getFeatureFlag('skipRuntimeSymbolProp')) {
|
|
285
|
+
// Apply pre-computed symbol data from runtime assets to skip symbol propagation
|
|
286
|
+
applyRuntimeSymbolData(runtimesAssetGraph, connections);
|
|
287
|
+
}
|
|
288
|
+
|
|
279
289
|
// Convert the runtime AssetGraph into a BundleGraph, this includes assigning
|
|
280
290
|
// the assets their public ids
|
|
281
291
|
let runtimesBundleGraph = InternalBundleGraph.fromAssetGraph(
|
|
@@ -398,6 +408,93 @@ export default async function applyRuntimes<TResult extends RequestResult>({
|
|
|
398
408
|
return changedAssets;
|
|
399
409
|
}
|
|
400
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Apply pre-computed symbol data from runtime assets to the asset graph
|
|
413
|
+
* to avoid running symbol propagation on runtime code we control.
|
|
414
|
+
*/
|
|
415
|
+
function applyRuntimeSymbolData(
|
|
416
|
+
assetGraph: AssetGraph,
|
|
417
|
+
connections: Array<RuntimeConnection>,
|
|
418
|
+
) {
|
|
419
|
+
for (let {assetGroup} of connections) {
|
|
420
|
+
let assetGroupNode = nodeFromAssetGroup(assetGroup);
|
|
421
|
+
let assetGroupAssetNodeIds = assetGraph.getNodeIdsConnectedFrom(
|
|
422
|
+
assetGraph.getNodeIdByContentKey(assetGroupNode.id),
|
|
423
|
+
);
|
|
424
|
+
|
|
425
|
+
if (assetGroupAssetNodeIds.length !== 1) {
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
let runtimeAssetNodeId = assetGroupAssetNodeIds[0];
|
|
430
|
+
let runtimeAssetNode = assetGraph.getNode(runtimeAssetNodeId);
|
|
431
|
+
if (!runtimeAssetNode || runtimeAssetNode.type !== 'asset') {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
let symbolData = assetGroup.symbolData;
|
|
436
|
+
if (!symbolData) {
|
|
437
|
+
// We completely skip symbol propagation for runtime assets, so symbolData
|
|
438
|
+
// is required
|
|
439
|
+
throw new Error('Runtime asset is missing symbol data');
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (symbolData.symbols) {
|
|
443
|
+
// Convert from SymbolData format to internal Asset.symbols format
|
|
444
|
+
let internalSymbols = new Map();
|
|
445
|
+
for (let [symbol, data] of symbolData.symbols) {
|
|
446
|
+
internalSymbols.set(symbol, {
|
|
447
|
+
local: data.local,
|
|
448
|
+
loc: data.loc || null,
|
|
449
|
+
meta: data.meta,
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
runtimeAssetNode.value.symbols = internalSymbols;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
if (symbolData.dependencies && symbolData.dependencies.length > 0) {
|
|
456
|
+
let outgoingDeps = assetGraph
|
|
457
|
+
.getNodeIdsConnectedFrom(runtimeAssetNodeId)
|
|
458
|
+
.map((id) => assetGraph.getNode(id))
|
|
459
|
+
.filter((node) => node?.type === 'dependency')
|
|
460
|
+
.map((node) => node as DependencyNode);
|
|
461
|
+
|
|
462
|
+
for (let depSymbolData of symbolData.dependencies) {
|
|
463
|
+
let matchingDep = outgoingDeps.find(
|
|
464
|
+
(depNode) => depNode.value.specifier === depSymbolData.specifier,
|
|
465
|
+
);
|
|
466
|
+
|
|
467
|
+
if (matchingDep) {
|
|
468
|
+
if (depSymbolData.symbols) {
|
|
469
|
+
let internalDepSymbols = new Map();
|
|
470
|
+
for (let [symbol, data] of depSymbolData.symbols) {
|
|
471
|
+
internalDepSymbols.set(symbol, {
|
|
472
|
+
local: data.local,
|
|
473
|
+
loc: data.loc || null,
|
|
474
|
+
isWeak: data.isWeak,
|
|
475
|
+
meta: data.meta,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
matchingDep.value.symbols = internalDepSymbols;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
if (depSymbolData.usedSymbols) {
|
|
482
|
+
matchingDep.usedSymbolsDown = new Set(depSymbolData.usedSymbols);
|
|
483
|
+
// For runtime assets, usedSymbolsUp will be the same as usedSymbolsDown
|
|
484
|
+
// since we know exactly what we're using
|
|
485
|
+
let usedSymbolsUp = new Map();
|
|
486
|
+
for (let symbol of depSymbolData.usedSymbols) {
|
|
487
|
+
// Mark as resolved to external (null) since runtime deps are typically external
|
|
488
|
+
usedSymbolsUp.set(symbol, null);
|
|
489
|
+
}
|
|
490
|
+
matchingDep.usedSymbolsUp = usedSymbolsUp;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
401
498
|
function reconcileNewRuntimes<TResult extends RequestResult>(
|
|
402
499
|
api: RunAPI<TResult>,
|
|
403
500
|
connections: Array<RuntimeConnection>,
|
|
@@ -408,6 +505,7 @@ function reconcileNewRuntimes<TResult extends RequestResult>(
|
|
|
408
505
|
name: 'Runtimes',
|
|
409
506
|
assetGroups,
|
|
410
507
|
optionsRef,
|
|
508
|
+
skipSymbolProp: getFeatureFlag('skipRuntimeSymbolProp'),
|
|
411
509
|
});
|
|
412
510
|
|
|
413
511
|
// rebuild the graph
|
|
@@ -43,6 +43,7 @@ export type AssetGraphRequestInput = {
|
|
|
43
43
|
lazyIncludes?: RegExp[];
|
|
44
44
|
lazyExcludes?: RegExp[];
|
|
45
45
|
requestedAssetIds?: Set<string>;
|
|
46
|
+
skipSymbolProp?: boolean;
|
|
46
47
|
};
|
|
47
48
|
|
|
48
49
|
export type AssetGraphRequestResult = {
|
|
@@ -128,6 +129,7 @@ export class AssetGraphBuilder {
|
|
|
128
129
|
isSingleChangeRebuild: boolean;
|
|
129
130
|
assetGroupsWithRemovedParents: Set<NodeId>;
|
|
130
131
|
previousSymbolPropagationErrors: Map<NodeId, Array<Diagnostic>>;
|
|
132
|
+
skipSymbolProp: boolean;
|
|
131
133
|
|
|
132
134
|
constructor(
|
|
133
135
|
{input, api, options}: RunInput,
|
|
@@ -167,6 +169,8 @@ export class AssetGraphBuilder {
|
|
|
167
169
|
this.shouldBuildLazily = shouldBuildLazily ?? false;
|
|
168
170
|
this.lazyIncludes = lazyIncludes ?? [];
|
|
169
171
|
this.lazyExcludes = lazyExcludes ?? [];
|
|
172
|
+
this.skipSymbolProp = input.skipSymbolProp ?? false;
|
|
173
|
+
|
|
170
174
|
if (getFeatureFlag('cachePerformanceImprovements')) {
|
|
171
175
|
const key = hashString(
|
|
172
176
|
`${ATLASPACK_VERSION}${name}${JSON.stringify(entries) ?? ''}${
|
|
@@ -298,41 +302,51 @@ export class AssetGraphBuilder {
|
|
|
298
302
|
this.assetGraph,
|
|
299
303
|
'AssetGraph_' + this.name + '_before_prop',
|
|
300
304
|
);
|
|
301
|
-
try {
|
|
302
|
-
let errors = propagateSymbols({
|
|
303
|
-
options: this.options,
|
|
304
|
-
assetGraph: this.assetGraph,
|
|
305
|
-
changedAssetsPropagation: this.changedAssetsPropagation,
|
|
306
|
-
assetGroupsWithRemovedParents: this.assetGroupsWithRemovedParents,
|
|
307
|
-
previousErrors: this.previousSymbolPropagationErrors,
|
|
308
|
-
});
|
|
309
|
-
this.changedAssetsPropagation.clear();
|
|
310
|
-
|
|
311
|
-
if (errors.size > 0) {
|
|
312
|
-
this.api.storeResult(
|
|
313
|
-
{
|
|
314
|
-
assetGraph: this.assetGraph,
|
|
315
|
-
changedAssets: this.changedAssets,
|
|
316
|
-
changedAssetsPropagation: this.changedAssetsPropagation,
|
|
317
|
-
assetGroupsWithRemovedParents: this.assetGroupsWithRemovedParents,
|
|
318
|
-
previousSymbolPropagationErrors: errors,
|
|
319
|
-
assetRequests: [],
|
|
320
|
-
},
|
|
321
|
-
this.cacheKey,
|
|
322
|
-
);
|
|
323
305
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
306
|
+
// Skip symbol propagation for runtime assets - they have pre-computed symbol data
|
|
307
|
+
if (this.skipSymbolProp) {
|
|
308
|
+
logger.verbose({
|
|
309
|
+
origin: '@atlaspack/core',
|
|
310
|
+
message: 'Skipping symbol propagation for runtime asset graph',
|
|
311
|
+
});
|
|
312
|
+
} else {
|
|
313
|
+
try {
|
|
314
|
+
let errors = propagateSymbols({
|
|
315
|
+
options: this.options,
|
|
316
|
+
assetGraph: this.assetGraph,
|
|
317
|
+
changedAssetsPropagation: this.changedAssetsPropagation,
|
|
318
|
+
assetGroupsWithRemovedParents: this.assetGroupsWithRemovedParents,
|
|
319
|
+
previousErrors: this.previousSymbolPropagationErrors,
|
|
328
320
|
});
|
|
321
|
+
this.changedAssetsPropagation.clear();
|
|
322
|
+
|
|
323
|
+
if (errors.size > 0) {
|
|
324
|
+
this.api.storeResult(
|
|
325
|
+
{
|
|
326
|
+
assetGraph: this.assetGraph,
|
|
327
|
+
changedAssets: this.changedAssets,
|
|
328
|
+
changedAssetsPropagation: this.changedAssetsPropagation,
|
|
329
|
+
assetGroupsWithRemovedParents:
|
|
330
|
+
this.assetGroupsWithRemovedParents,
|
|
331
|
+
previousSymbolPropagationErrors: errors,
|
|
332
|
+
assetRequests: [],
|
|
333
|
+
},
|
|
334
|
+
this.cacheKey,
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
// Just throw the first error. Since errors can bubble (e.g. reexporting a reexported symbol also fails),
|
|
338
|
+
// determining which failing export is the root cause is nontrivial (because of circular dependencies).
|
|
339
|
+
throw new ThrowableDiagnostic({
|
|
340
|
+
diagnostic: [...errors.values()][0],
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
} catch (e: any) {
|
|
344
|
+
await dumpGraphToGraphViz(
|
|
345
|
+
this.assetGraph,
|
|
346
|
+
'AssetGraph_' + this.name + '_failed',
|
|
347
|
+
);
|
|
348
|
+
throw e;
|
|
329
349
|
}
|
|
330
|
-
} catch (e: any) {
|
|
331
|
-
await dumpGraphToGraphViz(
|
|
332
|
-
this.assetGraph,
|
|
333
|
-
'AssetGraph_' + this.name + '_failed',
|
|
334
|
-
);
|
|
335
|
-
throw e;
|
|
336
350
|
}
|
|
337
351
|
}
|
|
338
352
|
await dumpGraphToGraphViz(this.assetGraph, 'AssetGraph_' + this.name);
|
|
@@ -523,17 +523,19 @@ class BundlerRunner {
|
|
|
523
523
|
),
|
|
524
524
|
);
|
|
525
525
|
|
|
526
|
-
changedRuntimes = await applyRuntimes(
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
526
|
+
changedRuntimes = await instrumentAsync('applyRuntimes', () =>
|
|
527
|
+
applyRuntimes({
|
|
528
|
+
bundleGraph: internalBundleGraph,
|
|
529
|
+
api: this.api,
|
|
530
|
+
config: this.config,
|
|
531
|
+
options: this.options,
|
|
532
|
+
optionsRef: this.optionsRef,
|
|
533
|
+
pluginOptions: this.pluginOptions,
|
|
534
|
+
previousDevDeps: this.previousDevDeps,
|
|
535
|
+
devDepRequests: this.devDepRequests,
|
|
536
|
+
configs: this.configs,
|
|
537
|
+
}),
|
|
538
|
+
);
|
|
537
539
|
|
|
538
540
|
// Add dev deps for namers, AFTER running them to account for lazy require().
|
|
539
541
|
for (let namer of namers) {
|
package/src/types.ts
CHANGED
|
@@ -23,6 +23,7 @@ import type {
|
|
|
23
23
|
HMROptions,
|
|
24
24
|
DetailedReportOptions,
|
|
25
25
|
Symbol,
|
|
26
|
+
SymbolData,
|
|
26
27
|
} from '@atlaspack/types';
|
|
27
28
|
import type {SharedReference} from '@atlaspack/workers';
|
|
28
29
|
import type {FileSystem} from '@atlaspack/fs';
|
|
@@ -438,6 +439,7 @@ export type AssetRequestInput = {
|
|
|
438
439
|
isURL?: boolean;
|
|
439
440
|
query?: string | null | undefined;
|
|
440
441
|
isSingleChangeRebuild?: boolean;
|
|
442
|
+
symbolData?: SymbolData;
|
|
441
443
|
};
|
|
442
444
|
|
|
443
445
|
export type AssetRequestResult = Array<Asset>;
|