@atlaspack/core 2.12.1-canary.3354
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/LICENSE +201 -0
- package/index.d.ts +22 -0
- package/lib/AssetGraph.js +518 -0
- package/lib/Atlaspack.js +587 -0
- package/lib/AtlaspackConfig.js +298 -0
- package/lib/AtlaspackConfig.schema.js +125 -0
- package/lib/BundleGraph.js +1445 -0
- package/lib/CommittedAsset.js +133 -0
- package/lib/Dependency.js +88 -0
- package/lib/Environment.js +128 -0
- package/lib/InternalConfig.js +48 -0
- package/lib/PackagerRunner.js +519 -0
- package/lib/ReporterRunner.js +151 -0
- package/lib/RequestTracker.js +1089 -0
- package/lib/SymbolPropagation.js +625 -0
- package/lib/TargetDescriptor.schema.js +115 -0
- package/lib/Transformation.js +536 -0
- package/lib/UncommittedAsset.js +342 -0
- package/lib/Validation.js +215 -0
- package/lib/applyRuntimes.js +279 -0
- package/lib/assetUtils.js +189 -0
- package/lib/atlaspack-v3/AtlaspackV3.js +74 -0
- package/lib/atlaspack-v3/fs.js +30 -0
- package/lib/atlaspack-v3/index.js +19 -0
- package/lib/atlaspack-v3/jsCallable.js +15 -0
- package/lib/atlaspack-v3/plugins/Resolver.js +12 -0
- package/lib/atlaspack-v3/plugins/index.js +16 -0
- package/lib/atlaspack-v3/worker/index.js +3 -0
- package/lib/atlaspack-v3/worker/worker.js +30 -0
- package/lib/buildCache.js +18 -0
- package/lib/constants.js +21 -0
- package/lib/dumpGraphToGraphViz.js +206 -0
- package/lib/index.js +106 -0
- package/lib/loadAtlaspackPlugin.js +148 -0
- package/lib/loadDotEnv.js +54 -0
- package/lib/projectPath.js +86 -0
- package/lib/public/Asset.js +259 -0
- package/lib/public/Bundle.js +231 -0
- package/lib/public/BundleGraph.js +193 -0
- package/lib/public/BundleGroup.js +44 -0
- package/lib/public/Config.js +202 -0
- package/lib/public/Dependency.js +131 -0
- package/lib/public/Environment.js +244 -0
- package/lib/public/MutableBundleGraph.js +184 -0
- package/lib/public/PluginOptions.js +71 -0
- package/lib/public/Symbols.js +247 -0
- package/lib/public/Target.js +64 -0
- package/lib/registerCoreWithSerializer.js +45 -0
- package/lib/requests/AssetGraphRequest.js +427 -0
- package/lib/requests/AssetGraphRequestRust.js +187 -0
- package/lib/requests/AssetRequest.js +137 -0
- package/lib/requests/AtlaspackBuildRequest.js +78 -0
- package/lib/requests/AtlaspackConfigRequest.js +473 -0
- package/lib/requests/BundleGraphRequest.js +419 -0
- package/lib/requests/ConfigRequest.js +198 -0
- package/lib/requests/DevDepRequest.js +166 -0
- package/lib/requests/EntryRequest.js +295 -0
- package/lib/requests/PackageRequest.js +88 -0
- package/lib/requests/PathRequest.js +349 -0
- package/lib/requests/TargetRequest.js +1177 -0
- package/lib/requests/ValidationRequest.js +66 -0
- package/lib/requests/WriteBundleRequest.js +252 -0
- package/lib/requests/WriteBundlesRequest.js +153 -0
- package/lib/resolveOptions.js +234 -0
- package/lib/serializer.js +216 -0
- package/lib/serializerCore.browser.js +29 -0
- package/lib/serializerCore.js +16 -0
- package/lib/summarizeRequest.js +55 -0
- package/lib/types.js +35 -0
- package/lib/utils.js +160 -0
- package/lib/worker.js +170 -0
- package/package.json +59 -0
- package/src/AssetGraph.js +646 -0
- package/src/Atlaspack.js +632 -0
- package/src/AtlaspackConfig.js +490 -0
- package/src/AtlaspackConfig.schema.js +141 -0
- package/src/BundleGraph.js +2193 -0
- package/src/CommittedAsset.js +143 -0
- package/src/Dependency.js +142 -0
- package/src/Environment.js +151 -0
- package/src/InternalConfig.js +72 -0
- package/src/PackagerRunner.js +790 -0
- package/src/ReporterRunner.js +158 -0
- package/src/RequestTracker.js +1697 -0
- package/src/SymbolPropagation.js +794 -0
- package/src/TargetDescriptor.schema.js +136 -0
- package/src/Transformation.js +752 -0
- package/src/UncommittedAsset.js +426 -0
- package/src/Validation.js +223 -0
- package/src/applyRuntimes.js +341 -0
- package/src/assetUtils.js +254 -0
- package/src/atlaspack-v3/AtlaspackV3.js +73 -0
- package/src/atlaspack-v3/fs.js +36 -0
- package/src/atlaspack-v3/index.js +5 -0
- package/src/atlaspack-v3/jsCallable.js +13 -0
- package/src/atlaspack-v3/plugins/Resolver.js +9 -0
- package/src/atlaspack-v3/plugins/index.js +3 -0
- package/src/atlaspack-v3/worker/index.js +8 -0
- package/src/atlaspack-v3/worker/worker.js +14 -0
- package/src/buildCache.js +15 -0
- package/src/constants.js +22 -0
- package/src/dumpGraphToGraphViz.js +244 -0
- package/src/index.js +22 -0
- package/src/loadAtlaspackPlugin.js +239 -0
- package/src/loadDotEnv.js +56 -0
- package/src/projectPath.js +87 -0
- package/src/public/Asset.js +359 -0
- package/src/public/Bundle.js +337 -0
- package/src/public/BundleGraph.js +335 -0
- package/src/public/BundleGroup.js +55 -0
- package/src/public/Config.js +261 -0
- package/src/public/Dependency.js +176 -0
- package/src/public/Environment.js +316 -0
- package/src/public/MutableBundleGraph.js +320 -0
- package/src/public/PluginOptions.js +99 -0
- package/src/public/Symbols.js +315 -0
- package/src/public/Target.js +71 -0
- package/src/registerCoreWithSerializer.js +34 -0
- package/src/requests/AssetGraphRequest.js +577 -0
- package/src/requests/AssetGraphRequestRust.js +222 -0
- package/src/requests/AssetRequest.js +179 -0
- package/src/requests/AtlaspackBuildRequest.js +109 -0
- package/src/requests/AtlaspackConfigRequest.js +709 -0
- package/src/requests/BundleGraphRequest.js +547 -0
- package/src/requests/ConfigRequest.js +287 -0
- package/src/requests/DevDepRequest.js +246 -0
- package/src/requests/EntryRequest.js +385 -0
- package/src/requests/PackageRequest.js +105 -0
- package/src/requests/PathRequest.js +454 -0
- package/src/requests/TargetRequest.js +1632 -0
- package/src/requests/ValidationRequest.js +79 -0
- package/src/requests/WriteBundleRequest.js +362 -0
- package/src/requests/WriteBundlesRequest.js +209 -0
- package/src/resolveOptions.js +278 -0
- package/src/serializer.js +255 -0
- package/src/serializerCore.browser.js +8 -0
- package/src/serializerCore.js +5 -0
- package/src/summarizeRequest.js +47 -0
- package/src/types.js +581 -0
- package/src/utils.js +211 -0
- package/src/worker.js +189 -0
- package/test/AssetGraph.test.js +679 -0
- package/test/Atlaspack.test.js +142 -0
- package/test/AtlaspackConfig.test.js +405 -0
- package/test/AtlaspackConfigRequest.test.js +993 -0
- package/test/BundleGraph.test.js +121 -0
- package/test/EntryRequest.test.js +215 -0
- package/test/Environment.test.js +99 -0
- package/test/InternalAsset.test.js +76 -0
- package/test/PackagerRunner.test.js +27 -0
- package/test/PublicAsset.test.js +40 -0
- package/test/PublicBundle.test.js +68 -0
- package/test/PublicDependency.test.js +22 -0
- package/test/PublicEnvironment.test.js +27 -0
- package/test/PublicMutableBundleGraph.test.js +192 -0
- package/test/RequestTracker.test.js +448 -0
- package/test/SymbolPropagation.test.js +716 -0
- package/test/TargetRequest.test.js +1715 -0
- package/test/fixtures/application-targets/package.json +3 -0
- package/test/fixtures/atlaspack/index.js +1 -0
- package/test/fixtures/atlaspack/other.js +3 -0
- package/test/fixtures/atlaspack/package.json +1 -0
- package/test/fixtures/atlaspack/yarn.lock +0 -0
- package/test/fixtures/bundle.js +10 -0
- package/test/fixtures/common-targets/package.json +24 -0
- package/test/fixtures/common-targets-ignore/package.json +13 -0
- package/test/fixtures/config/.atlaspackrc +6 -0
- package/test/fixtures/config/subfolder/.atlaspackrc +6 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-json5 +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-multiple +3 -0
- package/test/fixtures/config-extends-not-found/.atlaspackrc-node-modules +3 -0
- package/test/fixtures/config-malformed/.atlaspackrc +3 -0
- package/test/fixtures/config-node-pipeline/.atlaspackrc +6 -0
- package/test/fixtures/config-plugin-not-found/.atlaspackrc +6 -0
- package/test/fixtures/context/package.json +8 -0
- package/test/fixtures/custom-format-infer-ext/package.json +6 -0
- package/test/fixtures/custom-format-infer-type/package.json +7 -0
- package/test/fixtures/custom-format-mismatch/package.json +8 -0
- package/test/fixtures/custom-targets/package.json +20 -0
- package/test/fixtures/custom-targets-distdir/package.json +11 -0
- package/test/fixtures/duplicate-targets/package.json +4 -0
- package/test/fixtures/glob-like/[entry].js +0 -0
- package/test/fixtures/invalid-distpath/package.json +11 -0
- package/test/fixtures/invalid-engines/package.json +12 -0
- package/test/fixtures/invalid-source-missing/package.json +5 -0
- package/test/fixtures/invalid-source-not-file/package.json +5 -0
- package/test/fixtures/invalid-source-not-file/src/index.js +1 -0
- package/test/fixtures/invalid-target-source-missing/package.json +9 -0
- package/test/fixtures/invalid-target-source-not-file/package.json +9 -0
- package/test/fixtures/invalid-target-source-not-file/src/index.js +1 -0
- package/test/fixtures/invalid-targets/package.json +19 -0
- package/test/fixtures/library-custom-scopehoist/package.json +9 -0
- package/test/fixtures/library-scopehoist/package.json +8 -0
- package/test/fixtures/local-plugin-config-pkg/.atlaspackrc +3 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/index.json +8 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/local-plugin.js +7 -0
- package/test/fixtures/local-plugin-config-pkg/node_modules/atlaspack-config-local/package.json +7 -0
- package/test/fixtures/main-format-mismatch/package.json +8 -0
- package/test/fixtures/main-global/package.json +8 -0
- package/test/fixtures/main-mjs/package.json +8 -0
- package/test/fixtures/module-a.js +1 -0
- package/test/fixtures/module-b.js +1 -0
- package/test/fixtures/plugins/local-plugin.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/index.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-bad-engines/package.json +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/index.js +7 -0
- package/test/fixtures/plugins/node_modules/atlaspack-transformer-no-engines/package.json +4 -0
- package/test/fixtures/targets-default-distdir-none/package.json +5 -0
- package/test/fixtures/targets-default-distdir-one/package.json +8 -0
- package/test/fixtures/targets-default-distdir-two/package.json +18 -0
- package/test/requests/ConfigRequest.test.js +254 -0
- package/test/serializer.test.js +302 -0
- package/test/test-utils.js +80 -0
- package/test/utils.test.js +43 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {ContentKey} from '@atlaspack/graph';
|
|
4
|
+
import type {Dependency, NamedBundle as INamedBundle} from '@atlaspack/types';
|
|
5
|
+
import type {SharedReference} from '@atlaspack/workers';
|
|
6
|
+
import type {
|
|
7
|
+
Asset,
|
|
8
|
+
AssetGroup,
|
|
9
|
+
Bundle as InternalBundle,
|
|
10
|
+
Config,
|
|
11
|
+
DevDepRequest,
|
|
12
|
+
AtlaspackOptions,
|
|
13
|
+
} from './types';
|
|
14
|
+
import type AtlaspackConfig from './AtlaspackConfig';
|
|
15
|
+
import type PluginOptions from './public/PluginOptions';
|
|
16
|
+
import type {RequestResult, RunAPI} from './RequestTracker';
|
|
17
|
+
|
|
18
|
+
import path from 'path';
|
|
19
|
+
import assert from 'assert';
|
|
20
|
+
import invariant from 'assert';
|
|
21
|
+
import nullthrows from 'nullthrows';
|
|
22
|
+
import {nodeFromAssetGroup} from './AssetGraph';
|
|
23
|
+
import BundleGraph from './public/BundleGraph';
|
|
24
|
+
import InternalBundleGraph, {bundleGraphEdgeTypes} from './BundleGraph';
|
|
25
|
+
import {NamedBundle} from './public/Bundle';
|
|
26
|
+
import {PluginLogger} from '@atlaspack/logger';
|
|
27
|
+
import {hashString} from '@atlaspack/rust';
|
|
28
|
+
import ThrowableDiagnostic, {errorToDiagnostic} from '@atlaspack/diagnostic';
|
|
29
|
+
import {dependencyToInternalDependency} from './public/Dependency';
|
|
30
|
+
import {mergeEnvironments} from './Environment';
|
|
31
|
+
import createAssetGraphRequest from './requests/AssetGraphRequest';
|
|
32
|
+
import {createDevDependency, runDevDepRequest} from './requests/DevDepRequest';
|
|
33
|
+
import {toProjectPath, fromProjectPathRelative} from './projectPath';
|
|
34
|
+
import {tracer, PluginTracer} from '@atlaspack/profiler';
|
|
35
|
+
|
|
36
|
+
type RuntimeConnection = {|
|
|
37
|
+
bundle: InternalBundle,
|
|
38
|
+
assetGroup: AssetGroup,
|
|
39
|
+
dependency: ?Dependency,
|
|
40
|
+
isEntry: ?boolean,
|
|
41
|
+
|};
|
|
42
|
+
|
|
43
|
+
function nameRuntimeBundle(
|
|
44
|
+
bundle: InternalBundle,
|
|
45
|
+
siblingBundle: InternalBundle,
|
|
46
|
+
) {
|
|
47
|
+
// We don't run custom namers on runtime bundles as the runtime assumes that they are
|
|
48
|
+
// located at the same nesting level as their owning bundle. Custom naming could
|
|
49
|
+
// be added in future as long as the custom name is validated.
|
|
50
|
+
let {hashReference} = bundle;
|
|
51
|
+
|
|
52
|
+
let name = nullthrows(siblingBundle.name)
|
|
53
|
+
// Remove the existing hash from standard file patterns
|
|
54
|
+
// e.g. 'main.[hash].js' -> 'main.js' or 'main~[hash].js' -> 'main.js'
|
|
55
|
+
.replace(new RegExp(`[\\.~\\-_]?${siblingBundle.hashReference}`), '')
|
|
56
|
+
// Ensure the file ends with 'runtime.[hash].js'
|
|
57
|
+
.replace(`.${bundle.type}`, `.runtime.${hashReference}.${bundle.type}`);
|
|
58
|
+
|
|
59
|
+
bundle.name = name;
|
|
60
|
+
bundle.displayName = name.replace(hashReference, '[hash]');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export default async function applyRuntimes<TResult: RequestResult>({
|
|
64
|
+
bundleGraph,
|
|
65
|
+
config,
|
|
66
|
+
options,
|
|
67
|
+
pluginOptions,
|
|
68
|
+
api,
|
|
69
|
+
optionsRef,
|
|
70
|
+
previousDevDeps,
|
|
71
|
+
devDepRequests,
|
|
72
|
+
configs,
|
|
73
|
+
}: {|
|
|
74
|
+
bundleGraph: InternalBundleGraph,
|
|
75
|
+
config: AtlaspackConfig,
|
|
76
|
+
options: AtlaspackOptions,
|
|
77
|
+
optionsRef: SharedReference,
|
|
78
|
+
pluginOptions: PluginOptions,
|
|
79
|
+
api: RunAPI<TResult>,
|
|
80
|
+
previousDevDeps: Map<string, string>,
|
|
81
|
+
devDepRequests: Map<string, DevDepRequest>,
|
|
82
|
+
configs: Map<string, Config>,
|
|
83
|
+
|}): Promise<Map<string, Asset>> {
|
|
84
|
+
let runtimes = await config.getRuntimes();
|
|
85
|
+
let connections: Array<RuntimeConnection> = [];
|
|
86
|
+
|
|
87
|
+
// As manifest bundles may be added during runtimes we process them in reverse topological
|
|
88
|
+
// sort order. This allows bundles to be added to their bundle groups before they are referenced
|
|
89
|
+
// by other bundle groups by loader runtimes
|
|
90
|
+
let bundles = [];
|
|
91
|
+
bundleGraph.traverseBundles({
|
|
92
|
+
exit(bundle) {
|
|
93
|
+
bundles.push(bundle);
|
|
94
|
+
},
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
for (let bundle of bundles) {
|
|
98
|
+
for (let runtime of runtimes) {
|
|
99
|
+
let measurement;
|
|
100
|
+
try {
|
|
101
|
+
const namedBundle = NamedBundle.get(bundle, bundleGraph, options);
|
|
102
|
+
measurement = tracer.createMeasurement(
|
|
103
|
+
runtime.name,
|
|
104
|
+
'applyRuntime',
|
|
105
|
+
namedBundle.displayName,
|
|
106
|
+
);
|
|
107
|
+
let applied = await runtime.plugin.apply({
|
|
108
|
+
bundle: namedBundle,
|
|
109
|
+
bundleGraph: new BundleGraph<INamedBundle>(
|
|
110
|
+
bundleGraph,
|
|
111
|
+
NamedBundle.get.bind(NamedBundle),
|
|
112
|
+
options,
|
|
113
|
+
),
|
|
114
|
+
config: configs.get(runtime.name)?.result,
|
|
115
|
+
options: pluginOptions,
|
|
116
|
+
logger: new PluginLogger({origin: runtime.name}),
|
|
117
|
+
tracer: new PluginTracer({
|
|
118
|
+
origin: runtime.name,
|
|
119
|
+
category: 'applyRuntime',
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
if (applied) {
|
|
124
|
+
let runtimeAssets = Array.isArray(applied) ? applied : [applied];
|
|
125
|
+
for (let {
|
|
126
|
+
code,
|
|
127
|
+
dependency,
|
|
128
|
+
filePath,
|
|
129
|
+
isEntry,
|
|
130
|
+
env,
|
|
131
|
+
priority,
|
|
132
|
+
} of runtimeAssets) {
|
|
133
|
+
let sourceName = path.join(
|
|
134
|
+
path.dirname(filePath),
|
|
135
|
+
`runtime-${hashString(code)}.${bundle.type}`,
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
let assetGroup = {
|
|
139
|
+
code,
|
|
140
|
+
filePath: toProjectPath(options.projectRoot, sourceName),
|
|
141
|
+
env: mergeEnvironments(options.projectRoot, bundle.env, env),
|
|
142
|
+
// Runtime assets should be considered source, as they should be
|
|
143
|
+
// e.g. compiled to run in the target environment
|
|
144
|
+
isSource: true,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
let connectionBundle = bundle;
|
|
148
|
+
|
|
149
|
+
if (priority === 'parallel' && !bundle.needsStableName) {
|
|
150
|
+
let bundleGroups =
|
|
151
|
+
bundleGraph.getBundleGroupsContainingBundle(bundle);
|
|
152
|
+
|
|
153
|
+
connectionBundle = nullthrows(
|
|
154
|
+
bundleGraph.createBundle({
|
|
155
|
+
type: bundle.type,
|
|
156
|
+
needsStableName: false,
|
|
157
|
+
env: bundle.env,
|
|
158
|
+
target: bundle.target,
|
|
159
|
+
uniqueKey: 'runtime-manifest:' + bundle.id,
|
|
160
|
+
shouldContentHash: options.shouldContentHash,
|
|
161
|
+
}),
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
for (let bundleGroup of bundleGroups) {
|
|
165
|
+
bundleGraph.addBundleToBundleGroup(
|
|
166
|
+
connectionBundle,
|
|
167
|
+
bundleGroup,
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
bundleGraph.createBundleReference(bundle, connectionBundle);
|
|
171
|
+
|
|
172
|
+
nameRuntimeBundle(connectionBundle, bundle);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
connections.push({
|
|
176
|
+
bundle: connectionBundle,
|
|
177
|
+
assetGroup,
|
|
178
|
+
dependency,
|
|
179
|
+
isEntry,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
} catch (e) {
|
|
184
|
+
throw new ThrowableDiagnostic({
|
|
185
|
+
diagnostic: errorToDiagnostic(e, {
|
|
186
|
+
origin: runtime.name,
|
|
187
|
+
}),
|
|
188
|
+
});
|
|
189
|
+
} finally {
|
|
190
|
+
measurement && measurement.end();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Correct connection order after generating runtimes in reverse order
|
|
196
|
+
connections.reverse();
|
|
197
|
+
|
|
198
|
+
// Add dev deps for runtime plugins AFTER running them, to account for lazy require().
|
|
199
|
+
for (let runtime of runtimes) {
|
|
200
|
+
let devDepRequest = await createDevDependency(
|
|
201
|
+
{
|
|
202
|
+
specifier: runtime.name,
|
|
203
|
+
resolveFrom: runtime.resolveFrom,
|
|
204
|
+
},
|
|
205
|
+
previousDevDeps,
|
|
206
|
+
options,
|
|
207
|
+
);
|
|
208
|
+
devDepRequests.set(
|
|
209
|
+
`${devDepRequest.specifier}:${fromProjectPathRelative(
|
|
210
|
+
devDepRequest.resolveFrom,
|
|
211
|
+
)}`,
|
|
212
|
+
devDepRequest,
|
|
213
|
+
);
|
|
214
|
+
await runDevDepRequest(api, devDepRequest);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
let {assetGraph: runtimesAssetGraph, changedAssets} =
|
|
218
|
+
await reconcileNewRuntimes(api, connections, optionsRef);
|
|
219
|
+
|
|
220
|
+
let runtimesGraph = InternalBundleGraph.fromAssetGraph(
|
|
221
|
+
runtimesAssetGraph,
|
|
222
|
+
options.mode === 'production',
|
|
223
|
+
bundleGraph._publicIdByAssetId,
|
|
224
|
+
bundleGraph._assetPublicIds,
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
// Merge the runtimes graph into the main bundle graph.
|
|
228
|
+
bundleGraph.merge(runtimesGraph);
|
|
229
|
+
for (let [assetId, publicId] of runtimesGraph._publicIdByAssetId) {
|
|
230
|
+
bundleGraph._publicIdByAssetId.set(assetId, publicId);
|
|
231
|
+
bundleGraph._assetPublicIds.add(publicId);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
for (let {bundle, assetGroup, dependency, isEntry} of connections) {
|
|
235
|
+
let assetGroupNode = nodeFromAssetGroup(assetGroup);
|
|
236
|
+
let assetGroupAssetNodeIds = runtimesAssetGraph.getNodeIdsConnectedFrom(
|
|
237
|
+
runtimesAssetGraph.getNodeIdByContentKey(assetGroupNode.id),
|
|
238
|
+
);
|
|
239
|
+
invariant(assetGroupAssetNodeIds.length === 1);
|
|
240
|
+
let runtimeNodeId = assetGroupAssetNodeIds[0];
|
|
241
|
+
let runtimeNode = nullthrows(runtimesAssetGraph.getNode(runtimeNodeId));
|
|
242
|
+
invariant(runtimeNode.type === 'asset');
|
|
243
|
+
|
|
244
|
+
let resolution =
|
|
245
|
+
dependency &&
|
|
246
|
+
bundleGraph.getResolvedAsset(
|
|
247
|
+
dependencyToInternalDependency(dependency),
|
|
248
|
+
bundle,
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
let runtimesGraphRuntimeNodeId = runtimesGraph._graph.getNodeIdByContentKey(
|
|
252
|
+
runtimeNode.id,
|
|
253
|
+
);
|
|
254
|
+
let duplicatedContentKeys: Set<ContentKey> = new Set();
|
|
255
|
+
runtimesGraph._graph.traverse((nodeId, _, actions) => {
|
|
256
|
+
let node = nullthrows(runtimesGraph._graph.getNode(nodeId));
|
|
257
|
+
if (node.type !== 'dependency') {
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
let assets = runtimesGraph._graph
|
|
262
|
+
.getNodeIdsConnectedFrom(nodeId)
|
|
263
|
+
.map(assetNodeId => {
|
|
264
|
+
let assetNode = nullthrows(runtimesGraph._graph.getNode(assetNodeId));
|
|
265
|
+
invariant(assetNode.type === 'asset');
|
|
266
|
+
return assetNode.value;
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
for (let asset of assets) {
|
|
270
|
+
if (
|
|
271
|
+
bundleGraph.isAssetReachableFromBundle(asset, bundle) ||
|
|
272
|
+
resolution?.id === asset.id
|
|
273
|
+
) {
|
|
274
|
+
duplicatedContentKeys.add(asset.id);
|
|
275
|
+
actions.skipChildren();
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}, runtimesGraphRuntimeNodeId);
|
|
279
|
+
|
|
280
|
+
let bundleNodeId = bundleGraph._graph.getNodeIdByContentKey(bundle.id);
|
|
281
|
+
let bundleGraphRuntimeNodeId = bundleGraph._graph.getNodeIdByContentKey(
|
|
282
|
+
runtimeNode.id,
|
|
283
|
+
); // the node id is not constant between graphs
|
|
284
|
+
|
|
285
|
+
runtimesGraph._graph.traverse((nodeId, _, actions) => {
|
|
286
|
+
let node = nullthrows(runtimesGraph._graph.getNode(nodeId));
|
|
287
|
+
if (node.type === 'asset' || node.type === 'dependency') {
|
|
288
|
+
if (duplicatedContentKeys.has(node.id)) {
|
|
289
|
+
actions.skipChildren();
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const bundleGraphNodeId = bundleGraph._graph.getNodeIdByContentKey(
|
|
294
|
+
node.id,
|
|
295
|
+
); // the node id is not constant between graphs
|
|
296
|
+
bundleGraph._graph.addEdge(
|
|
297
|
+
bundleNodeId,
|
|
298
|
+
bundleGraphNodeId,
|
|
299
|
+
bundleGraphEdgeTypes.contains,
|
|
300
|
+
);
|
|
301
|
+
}
|
|
302
|
+
}, runtimesGraphRuntimeNodeId);
|
|
303
|
+
|
|
304
|
+
if (isEntry) {
|
|
305
|
+
bundleGraph._graph.addEdge(bundleNodeId, bundleGraphRuntimeNodeId);
|
|
306
|
+
bundle.entryAssetIds.unshift(runtimeNode.id);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (dependency == null) {
|
|
310
|
+
// Verify this asset won't become an island
|
|
311
|
+
assert(
|
|
312
|
+
bundleGraph._graph.getNodeIdsConnectedTo(bundleGraphRuntimeNodeId)
|
|
313
|
+
.length > 0,
|
|
314
|
+
'Runtime must have an inbound dependency or be an entry',
|
|
315
|
+
);
|
|
316
|
+
} else {
|
|
317
|
+
let dependencyNodeId = bundleGraph._graph.getNodeIdByContentKey(
|
|
318
|
+
dependency.id,
|
|
319
|
+
);
|
|
320
|
+
bundleGraph._graph.addEdge(dependencyNodeId, bundleGraphRuntimeNodeId);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
return changedAssets;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
function reconcileNewRuntimes<TResult: RequestResult>(
|
|
328
|
+
api: RunAPI<TResult>,
|
|
329
|
+
connections: Array<RuntimeConnection>,
|
|
330
|
+
optionsRef: SharedReference,
|
|
331
|
+
) {
|
|
332
|
+
let assetGroups = connections.map(t => t.assetGroup);
|
|
333
|
+
let request = createAssetGraphRequest({
|
|
334
|
+
name: 'Runtimes',
|
|
335
|
+
assetGroups,
|
|
336
|
+
optionsRef,
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
// rebuild the graph
|
|
340
|
+
return api.runRequest(request, {force: true});
|
|
341
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
ASTGenerator,
|
|
5
|
+
BundleBehavior,
|
|
6
|
+
FilePath,
|
|
7
|
+
GenerateOutput,
|
|
8
|
+
Meta,
|
|
9
|
+
PackageName,
|
|
10
|
+
Stats,
|
|
11
|
+
Symbol,
|
|
12
|
+
SourceLocation,
|
|
13
|
+
Transformer,
|
|
14
|
+
} from '@atlaspack/types';
|
|
15
|
+
import type {
|
|
16
|
+
Asset,
|
|
17
|
+
RequestInvalidation,
|
|
18
|
+
Dependency,
|
|
19
|
+
Environment,
|
|
20
|
+
AtlaspackOptions,
|
|
21
|
+
} from './types';
|
|
22
|
+
|
|
23
|
+
import {Readable} from 'stream';
|
|
24
|
+
import {PluginLogger} from '@atlaspack/logger';
|
|
25
|
+
import nullthrows from 'nullthrows';
|
|
26
|
+
import CommittedAsset from './CommittedAsset';
|
|
27
|
+
import UncommittedAsset from './UncommittedAsset';
|
|
28
|
+
import loadPlugin from './loadAtlaspackPlugin';
|
|
29
|
+
import {Asset as PublicAsset} from './public/Asset';
|
|
30
|
+
import PluginOptions from './public/PluginOptions';
|
|
31
|
+
import {blobToStream, hashFile} from '@atlaspack/utils';
|
|
32
|
+
import {hashFromOption, toInternalSourceLocation} from './utils';
|
|
33
|
+
import {createBuildCache} from './buildCache';
|
|
34
|
+
import {
|
|
35
|
+
type ProjectPath,
|
|
36
|
+
fromProjectPath,
|
|
37
|
+
fromProjectPathRelative,
|
|
38
|
+
} from './projectPath';
|
|
39
|
+
import {hashString} from '@atlaspack/rust';
|
|
40
|
+
import {BundleBehavior as BundleBehaviorMap} from './types';
|
|
41
|
+
import {PluginTracer} from '@atlaspack/profiler';
|
|
42
|
+
|
|
43
|
+
type AssetOptions = {|
|
|
44
|
+
id?: string,
|
|
45
|
+
committed?: boolean,
|
|
46
|
+
idBase?: ?string,
|
|
47
|
+
filePath: ProjectPath,
|
|
48
|
+
query?: ?string,
|
|
49
|
+
type: string,
|
|
50
|
+
contentKey?: ?string,
|
|
51
|
+
mapKey?: ?string,
|
|
52
|
+
astKey?: ?string,
|
|
53
|
+
astGenerator?: ?ASTGenerator,
|
|
54
|
+
dependencies?: Map<string, Dependency>,
|
|
55
|
+
bundleBehavior?: ?BundleBehavior,
|
|
56
|
+
isBundleSplittable?: ?boolean,
|
|
57
|
+
isSource: boolean,
|
|
58
|
+
env: Environment,
|
|
59
|
+
meta?: Meta,
|
|
60
|
+
outputHash?: ?string,
|
|
61
|
+
pipeline?: ?string,
|
|
62
|
+
stats: Stats,
|
|
63
|
+
symbols?: ?Map<Symbol, {|local: Symbol, loc: ?SourceLocation, meta?: ?Meta|}>,
|
|
64
|
+
sideEffects?: boolean,
|
|
65
|
+
uniqueKey?: ?string,
|
|
66
|
+
plugin?: PackageName,
|
|
67
|
+
configPath?: ProjectPath,
|
|
68
|
+
configKeyPath?: string,
|
|
69
|
+
|};
|
|
70
|
+
|
|
71
|
+
export function createAssetIdFromOptions(options: AssetOptions): string {
|
|
72
|
+
let uniqueKey = options.uniqueKey ?? '';
|
|
73
|
+
let idBase =
|
|
74
|
+
options.idBase != null
|
|
75
|
+
? options.idBase
|
|
76
|
+
: fromProjectPathRelative(options.filePath);
|
|
77
|
+
|
|
78
|
+
return hashString(
|
|
79
|
+
idBase +
|
|
80
|
+
options.type +
|
|
81
|
+
options.env.id +
|
|
82
|
+
uniqueKey +
|
|
83
|
+
':' +
|
|
84
|
+
(options.pipeline ?? '') +
|
|
85
|
+
':' +
|
|
86
|
+
(options.query ?? ''),
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function createAsset(
|
|
91
|
+
projectRoot: FilePath,
|
|
92
|
+
options: AssetOptions,
|
|
93
|
+
): Asset {
|
|
94
|
+
return {
|
|
95
|
+
id: options.id != null ? options.id : createAssetIdFromOptions(options),
|
|
96
|
+
committed: options.committed ?? false,
|
|
97
|
+
filePath: options.filePath,
|
|
98
|
+
query: options.query,
|
|
99
|
+
bundleBehavior: options.bundleBehavior
|
|
100
|
+
? BundleBehaviorMap[options.bundleBehavior]
|
|
101
|
+
: null,
|
|
102
|
+
isBundleSplittable: options.isBundleSplittable ?? true,
|
|
103
|
+
type: options.type,
|
|
104
|
+
contentKey: options.contentKey,
|
|
105
|
+
mapKey: options.mapKey,
|
|
106
|
+
astKey: options.astKey,
|
|
107
|
+
astGenerator: options.astGenerator,
|
|
108
|
+
dependencies: options.dependencies || new Map(),
|
|
109
|
+
isSource: options.isSource,
|
|
110
|
+
outputHash: options.outputHash,
|
|
111
|
+
pipeline: options.pipeline,
|
|
112
|
+
env: options.env,
|
|
113
|
+
meta: options.meta || {},
|
|
114
|
+
stats: options.stats,
|
|
115
|
+
symbols:
|
|
116
|
+
options.symbols &&
|
|
117
|
+
new Map(
|
|
118
|
+
[...options.symbols].map(([k, v]) => [
|
|
119
|
+
k,
|
|
120
|
+
{
|
|
121
|
+
local: v.local,
|
|
122
|
+
meta: v.meta,
|
|
123
|
+
loc: toInternalSourceLocation(projectRoot, v.loc),
|
|
124
|
+
},
|
|
125
|
+
]),
|
|
126
|
+
),
|
|
127
|
+
sideEffects: options.sideEffects ?? true,
|
|
128
|
+
uniqueKey: options.uniqueKey,
|
|
129
|
+
plugin: options.plugin,
|
|
130
|
+
configPath: options.configPath,
|
|
131
|
+
configKeyPath: options.configKeyPath,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const generateResults: WeakMap<Asset, Promise<GenerateOutput>> = new WeakMap();
|
|
136
|
+
|
|
137
|
+
export function generateFromAST(
|
|
138
|
+
asset: CommittedAsset | UncommittedAsset,
|
|
139
|
+
): Promise<GenerateOutput> {
|
|
140
|
+
let output = generateResults.get(asset.value);
|
|
141
|
+
if (output == null) {
|
|
142
|
+
output = _generateFromAST(asset);
|
|
143
|
+
generateResults.set(asset.value, output);
|
|
144
|
+
}
|
|
145
|
+
return output;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async function _generateFromAST(asset: CommittedAsset | UncommittedAsset) {
|
|
149
|
+
let ast = await asset.getAST();
|
|
150
|
+
if (ast == null) {
|
|
151
|
+
throw new Error('Asset has no AST');
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
let pluginName = nullthrows(asset.value.plugin);
|
|
155
|
+
let {plugin} = await loadPlugin<Transformer<mixed>>(
|
|
156
|
+
pluginName,
|
|
157
|
+
fromProjectPath(
|
|
158
|
+
asset.options.projectRoot,
|
|
159
|
+
nullthrows(asset.value.configPath),
|
|
160
|
+
),
|
|
161
|
+
nullthrows(asset.value.configKeyPath),
|
|
162
|
+
asset.options,
|
|
163
|
+
);
|
|
164
|
+
let generate = plugin.generate?.bind(plugin);
|
|
165
|
+
if (!generate) {
|
|
166
|
+
throw new Error(`${pluginName} does not have a generate method`);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
let {content, map} = await generate({
|
|
170
|
+
asset: new PublicAsset(asset),
|
|
171
|
+
ast,
|
|
172
|
+
options: new PluginOptions(asset.options),
|
|
173
|
+
logger: new PluginLogger({origin: pluginName}),
|
|
174
|
+
tracer: new PluginTracer({origin: pluginName, category: 'asset-generate'}),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
let mapBuffer = map?.toBuffer();
|
|
178
|
+
// Store the results in the cache so we can avoid generating again next time
|
|
179
|
+
await Promise.all([
|
|
180
|
+
asset.options.cache.setStream(
|
|
181
|
+
nullthrows(asset.value.contentKey),
|
|
182
|
+
blobToStream(content),
|
|
183
|
+
),
|
|
184
|
+
mapBuffer != null &&
|
|
185
|
+
asset.options.cache.setBlob(nullthrows(asset.value.mapKey), mapBuffer),
|
|
186
|
+
]);
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
content:
|
|
190
|
+
content instanceof Readable
|
|
191
|
+
? asset.options.cache.getStream(nullthrows(asset.value.contentKey))
|
|
192
|
+
: content,
|
|
193
|
+
map,
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
export function getInvalidationId(invalidation: RequestInvalidation): string {
|
|
198
|
+
switch (invalidation.type) {
|
|
199
|
+
case 'file':
|
|
200
|
+
return 'file:' + fromProjectPathRelative(invalidation.filePath);
|
|
201
|
+
case 'env':
|
|
202
|
+
return 'env:' + invalidation.key;
|
|
203
|
+
case 'option':
|
|
204
|
+
return 'option:' + invalidation.key;
|
|
205
|
+
default:
|
|
206
|
+
throw new Error('Unknown invalidation type: ' + invalidation.type);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const hashCache = createBuildCache();
|
|
211
|
+
|
|
212
|
+
export async function getInvalidationHash(
|
|
213
|
+
invalidations: Array<RequestInvalidation>,
|
|
214
|
+
options: AtlaspackOptions,
|
|
215
|
+
): Promise<string> {
|
|
216
|
+
if (invalidations.length === 0) {
|
|
217
|
+
return '';
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
let sortedInvalidations = invalidations
|
|
221
|
+
.slice()
|
|
222
|
+
.sort((a, b) => (getInvalidationId(a) < getInvalidationId(b) ? -1 : 1));
|
|
223
|
+
|
|
224
|
+
let hashes = '';
|
|
225
|
+
for (let invalidation of sortedInvalidations) {
|
|
226
|
+
switch (invalidation.type) {
|
|
227
|
+
case 'file': {
|
|
228
|
+
// Only recompute the hash of this file if we haven't seen it already during this build.
|
|
229
|
+
let fileHash = hashCache.get(invalidation.filePath);
|
|
230
|
+
if (fileHash == null) {
|
|
231
|
+
fileHash = hashFile(
|
|
232
|
+
options.inputFS,
|
|
233
|
+
fromProjectPath(options.projectRoot, invalidation.filePath),
|
|
234
|
+
);
|
|
235
|
+
hashCache.set(invalidation.filePath, fileHash);
|
|
236
|
+
}
|
|
237
|
+
hashes += await fileHash;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
case 'env':
|
|
241
|
+
hashes +=
|
|
242
|
+
invalidation.key + ':' + (options.env[invalidation.key] || '');
|
|
243
|
+
break;
|
|
244
|
+
case 'option':
|
|
245
|
+
hashes +=
|
|
246
|
+
invalidation.key + ':' + hashFromOption(options[invalidation.key]);
|
|
247
|
+
break;
|
|
248
|
+
default:
|
|
249
|
+
throw new Error('Unknown invalidation type: ' + invalidation.type);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return hashString(hashes);
|
|
254
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// @flow
|
|
2
|
+
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import {Worker} from 'worker_threads';
|
|
5
|
+
import {AtlaspackNapi, type AtlaspackNapiOptions} from '@atlaspack/rust';
|
|
6
|
+
|
|
7
|
+
const WORKER_PATH = path.join(__dirname, 'worker', 'index.js');
|
|
8
|
+
|
|
9
|
+
export type AtlaspackV3Options = {|
|
|
10
|
+
fs?: AtlaspackNapiOptions['fs'],
|
|
11
|
+
nodeWorkers?: number,
|
|
12
|
+
packageManager?: AtlaspackNapiOptions['packageManager'],
|
|
13
|
+
threads?: number,
|
|
14
|
+
...AtlaspackNapiOptions['options'],
|
|
15
|
+
|};
|
|
16
|
+
|
|
17
|
+
export class AtlaspackV3 {
|
|
18
|
+
_internal: AtlaspackNapi;
|
|
19
|
+
|
|
20
|
+
constructor({
|
|
21
|
+
fs,
|
|
22
|
+
nodeWorkers,
|
|
23
|
+
packageManager,
|
|
24
|
+
threads,
|
|
25
|
+
...options
|
|
26
|
+
}: AtlaspackV3Options) {
|
|
27
|
+
this._internal = new AtlaspackNapi({
|
|
28
|
+
fs,
|
|
29
|
+
nodeWorkers,
|
|
30
|
+
packageManager,
|
|
31
|
+
threads,
|
|
32
|
+
options,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async build(): Promise<any> {
|
|
37
|
+
const [workers, registerWorker] = this.#createWorkers();
|
|
38
|
+
|
|
39
|
+
let result = await this._internal.build({
|
|
40
|
+
registerWorker,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
for (const worker of workers) worker.terminate();
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async buildAssetGraph(): Promise<any> {
|
|
48
|
+
const [workers, registerWorker] = this.#createWorkers();
|
|
49
|
+
|
|
50
|
+
let result = await this._internal.buildAssetGraph({
|
|
51
|
+
registerWorker,
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
for (const worker of workers) worker.terminate();
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
#createWorkers() {
|
|
59
|
+
const workers = [];
|
|
60
|
+
|
|
61
|
+
return [
|
|
62
|
+
workers,
|
|
63
|
+
tx_worker => {
|
|
64
|
+
let worker = new Worker(WORKER_PATH, {
|
|
65
|
+
workerData: {
|
|
66
|
+
tx_worker,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
workers.push(worker);
|
|
70
|
+
},
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @flow strict-local
|
|
2
|
+
|
|
3
|
+
import type {FileSystem} from '@atlaspack/rust';
|
|
4
|
+
import type {
|
|
5
|
+
Encoding,
|
|
6
|
+
FilePath,
|
|
7
|
+
FileSystem as ClassicFileSystem,
|
|
8
|
+
} from '@atlaspack/types-internal';
|
|
9
|
+
|
|
10
|
+
import {jsCallable} from './jsCallable';
|
|
11
|
+
|
|
12
|
+
// Move to @atlaspack/utils or a dedicated v3 / migration package later
|
|
13
|
+
export function toFileSystemV3(fs: ClassicFileSystem): FileSystem {
|
|
14
|
+
return {
|
|
15
|
+
canonicalize: jsCallable((path: FilePath) => fs.realpathSync(path)),
|
|
16
|
+
createDirectory: jsCallable((path: FilePath) => fs.mkdirp(path)),
|
|
17
|
+
cwd: jsCallable(() => fs.cwd()),
|
|
18
|
+
readFile: jsCallable((path: string, encoding?: Encoding) =>
|
|
19
|
+
fs.readFileSync(path, encoding ?? 'utf8'),
|
|
20
|
+
),
|
|
21
|
+
isFile: (path: string) => {
|
|
22
|
+
try {
|
|
23
|
+
return fs.statSync(path).isFile();
|
|
24
|
+
} catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
isDir: (path: string) => {
|
|
29
|
+
try {
|
|
30
|
+
return fs.statSync(path).isDirectory();
|
|
31
|
+
} catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|