@angular-architects/native-federation-v4 20.3.6 → 20.3.8
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/collection.json +5 -0
- package/migration-collection.json +6 -0
- package/package.json +3 -3
- package/src/builders/build/builder.d.ts.map +1 -1
- package/src/builders/build/builder.js +112 -95
- package/src/builders/build/schema.d.ts +3 -4
- package/src/builders/build/schema.json +8 -26
- package/src/builders/build/setup-builder-env-variables.js +3 -1
- package/src/config/angular-skip-list.d.ts +3 -0
- package/src/config/angular-skip-list.d.ts.map +1 -0
- package/src/config/angular-skip-list.js +13 -0
- package/src/config/share-utils.d.ts +9 -0
- package/src/config/share-utils.d.ts.map +1 -0
- package/src/config/share-utils.js +32 -0
- package/src/config.d.ts +2 -2
- package/src/config.d.ts.map +1 -1
- package/src/config.js +2 -2
- package/src/schematics/init/files/federation.config.js__tmpl__ +19 -7
- package/src/schematics/init/schema.d.ts +0 -1
- package/src/schematics/init/schema.json +2 -6
- package/src/schematics/init/schematic.d.ts.map +1 -1
- package/src/schematics/init/schematic.js +50 -25
- package/src/schematics/update-v4/schema.d.ts +4 -0
- package/src/schematics/update-v4/schema.json +23 -0
- package/src/schematics/update-v4/schematic.d.ts +4 -0
- package/src/schematics/update-v4/schematic.d.ts.map +1 -0
- package/src/schematics/update-v4/schematic.js +225 -0
- package/src/utils/angular-bundler.d.ts +7 -0
- package/src/utils/angular-bundler.d.ts.map +1 -0
- package/src/utils/angular-bundler.js +120 -0
- package/src/utils/angular-esbuild-adapter.d.ts +8 -3
- package/src/utils/angular-esbuild-adapter.d.ts.map +1 -1
- package/src/utils/angular-esbuild-adapter.js +63 -245
- package/src/utils/angular-locales.d.ts.map +1 -1
- package/src/utils/create-federation-tsconfig.d.ts +6 -0
- package/src/utils/create-federation-tsconfig.d.ts.map +1 -0
- package/src/utils/create-federation-tsconfig.js +49 -0
- package/src/utils/get-fallback-platform.d.ts +3 -0
- package/src/utils/get-fallback-platform.d.ts.map +1 -0
- package/src/utils/get-fallback-platform.js +13 -0
- package/src/utils/node-modules-bundler.d.ts +11 -0
- package/src/utils/node-modules-bundler.d.ts.map +1 -0
- package/src/utils/node-modules-bundler.js +98 -0
- package/src/utils/normalize-context-options.d.ts +23 -0
- package/src/utils/normalize-context-options.d.ts.map +1 -0
- package/src/utils/normalize-context-options.js +18 -0
- package/src/utils/shared-mappings-plugin.d.ts +2 -2
- package/src/utils/shared-mappings-plugin.d.ts.map +1 -1
- package/src/utils/shared-mappings-plugin.js +4 -4
- package/src/utils/create-compiler-options.d.ts +0 -6
- package/src/utils/create-compiler-options.d.ts.map +0 -1
- package/src/utils/create-compiler-options.js +0 -41
- package/src/utils/mem-resuts.d.ts +0 -29
- package/src/utils/mem-resuts.d.ts.map +0 -1
- package/src/utils/mem-resuts.js +0 -50
|
@@ -1,74 +1,98 @@
|
|
|
1
|
-
import { logger, AbortedError } from '@softarc/native-federation/internal';
|
|
2
|
-
import * as esbuild from 'esbuild';
|
|
3
|
-
import { transformSupportedBrowsersToTargets, getSupportedBrowsers, generateSearchDirectories, findTailwindConfiguration, loadPostcssConfiguration, } from '@angular/build/private';
|
|
4
|
-
import { createCompilerPluginOptions } from './create-compiler-options.js';
|
|
5
|
-
import { normalizeOptimization, normalizeSourceMaps, } from '@angular-devkit/build-angular/src/utils/index.js';
|
|
6
|
-
import { createRequire } from 'node:module';
|
|
7
1
|
import * as fs from 'fs';
|
|
8
2
|
import * as path from 'path';
|
|
9
|
-
import {
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
const
|
|
3
|
+
import { AbortedError } from '@softarc/native-federation/internal';
|
|
4
|
+
import * as esbuild from 'esbuild';
|
|
5
|
+
import { createAngularEsbuildContext } from './angular-bundler.js';
|
|
6
|
+
import { createNodeModulesEsbuildContext } from './node-modules-bundler.js';
|
|
7
|
+
import { normalizeContextOptions } from './normalize-context-options.js';
|
|
8
|
+
function writeResult(result, outdir) {
|
|
9
|
+
const writtenFiles = [];
|
|
10
|
+
for (const outFile of result.outputFiles ?? []) {
|
|
11
|
+
const fileName = path.basename(outFile.path);
|
|
12
|
+
const filePath = path.join(outdir, fileName);
|
|
13
|
+
fs.writeFileSync(filePath, outFile.text);
|
|
14
|
+
writtenFiles.push(filePath);
|
|
15
|
+
}
|
|
16
|
+
return writtenFiles;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Patches @angular/core to infer ngServerMode at runtime.
|
|
20
|
+
* Usually, ngServerMode is set during bundling. However, we need to infer this
|
|
21
|
+
* value at runtime as we are using the same shared bundle for @angular/core
|
|
22
|
+
* on the server and in the browser.
|
|
23
|
+
*/
|
|
24
|
+
function setNgServerMode() {
|
|
25
|
+
const fileToPatch = 'node_modules/@angular/core/fesm2022/core.mjs';
|
|
26
|
+
const lineToAdd = `if (typeof globalThis.ngServerMode ==='undefined') globalThis.ngServerMode = (typeof window === 'undefined') ? true : false;`;
|
|
27
|
+
try {
|
|
28
|
+
if (fs.existsSync(fileToPatch)) {
|
|
29
|
+
let content = fs.readFileSync(fileToPatch, 'utf-8');
|
|
30
|
+
if (!content.includes(lineToAdd)) {
|
|
31
|
+
content = lineToAdd + '\n' + content;
|
|
32
|
+
fs.writeFileSync(fileToPatch, content);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
console.error('Error patching file ', fileToPatch, '\nIs it write-protected?');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export function createAngularBuildAdapter(ngBuilderOptions, context) {
|
|
41
|
+
const bundleContextCache = new Map();
|
|
16
42
|
const dispose = async (name) => {
|
|
17
43
|
if (name) {
|
|
18
|
-
if (!
|
|
44
|
+
if (!bundleContextCache.has(name))
|
|
19
45
|
throw new Error(`Could not dispose of non-existing build '${name}'`);
|
|
20
|
-
const entry =
|
|
46
|
+
const entry = bundleContextCache.get(name);
|
|
21
47
|
await entry.ctx.dispose();
|
|
22
48
|
await entry.pluginDisposed;
|
|
23
|
-
|
|
49
|
+
bundleContextCache.delete(name);
|
|
24
50
|
return;
|
|
25
51
|
}
|
|
26
|
-
// Dispose all if no specific build provided
|
|
27
52
|
const disposals = [];
|
|
28
|
-
for (const [, entry] of
|
|
53
|
+
for (const [, entry] of bundleContextCache) {
|
|
29
54
|
disposals.push((async () => {
|
|
30
55
|
await entry.ctx.dispose();
|
|
31
56
|
await entry.pluginDisposed;
|
|
32
57
|
})());
|
|
33
58
|
}
|
|
34
|
-
|
|
59
|
+
bundleContextCache.clear();
|
|
35
60
|
await Promise.all(disposals);
|
|
61
|
+
await esbuild.stop();
|
|
36
62
|
};
|
|
37
|
-
const setup = async (
|
|
38
|
-
const { entryPoints, tsConfigPath, external, outdir, mappedPaths, bundleName, isNodeModules, dev, chunks, hash, platform, optimizedMappings, cache, } = options;
|
|
63
|
+
const setup = async (name, adapterOptions) => {
|
|
39
64
|
setNgServerMode();
|
|
40
|
-
if (
|
|
65
|
+
if (bundleContextCache.has(name)) {
|
|
41
66
|
return;
|
|
42
67
|
}
|
|
43
|
-
const
|
|
44
|
-
|
|
68
|
+
const normalizedOptions = normalizeContextOptions(ngBuilderOptions, context, adapterOptions);
|
|
69
|
+
const { ctx, pluginDisposed } = normalizedOptions.isMappingOrExposed
|
|
70
|
+
? await createAngularEsbuildContext(normalizedOptions)
|
|
71
|
+
: await createNodeModulesEsbuildContext(normalizedOptions);
|
|
72
|
+
bundleContextCache.set(name, {
|
|
45
73
|
ctx,
|
|
46
74
|
pluginDisposed,
|
|
47
|
-
outdir,
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
workspaceRoot: context.workspaceRoot,
|
|
75
|
+
outdir: normalizedOptions.outdir,
|
|
76
|
+
cache: normalizedOptions.cache,
|
|
77
|
+
isMappingOrExposed: normalizedOptions.isMappingOrExposed,
|
|
78
|
+
dev: normalizedOptions.dev,
|
|
79
|
+
name,
|
|
53
80
|
});
|
|
54
81
|
};
|
|
55
82
|
const build = async (name, opts = {}) => {
|
|
56
|
-
const
|
|
57
|
-
if (!
|
|
83
|
+
const bundleContext = bundleContextCache.get(name);
|
|
84
|
+
if (!bundleContext) {
|
|
58
85
|
throw new Error(`No context found for build "${name}". Call setup() first.`);
|
|
59
86
|
}
|
|
60
87
|
if (opts?.signal?.aborted) {
|
|
61
88
|
throw new AbortedError('[build] Aborted before rebuild');
|
|
62
89
|
}
|
|
63
90
|
try {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (cached.isNodeModules) {
|
|
67
|
-
const scriptFiles = writtenFiles.filter(f => f.endsWith('.js') || f.endsWith('.mjs'));
|
|
68
|
-
for (const file of scriptFiles) {
|
|
69
|
-
await link(file, cached.dev);
|
|
70
|
-
}
|
|
91
|
+
if (opts.files) {
|
|
92
|
+
bundleContext.cache.bundlerCache.invalidate(new Set(opts.files));
|
|
71
93
|
}
|
|
94
|
+
const result = await bundleContext.ctx.rebuild();
|
|
95
|
+
const writtenFiles = writeResult(result, bundleContext.outdir);
|
|
72
96
|
return writtenFiles.map(fileName => ({ fileName }));
|
|
73
97
|
}
|
|
74
98
|
catch (error) {
|
|
@@ -80,209 +104,3 @@ export function createAngularBuildAdapter(builderOptions, context) {
|
|
|
80
104
|
};
|
|
81
105
|
return { setup, build, dispose };
|
|
82
106
|
}
|
|
83
|
-
async function link(outfile, dev) {
|
|
84
|
-
const code = fs.readFileSync(outfile, 'utf-8');
|
|
85
|
-
try {
|
|
86
|
-
const linkerEsm = await loadEsmModule('@angular/compiler-cli/linker/babel');
|
|
87
|
-
const linker = linkerEsm.default;
|
|
88
|
-
const result = await transformAsync(code, {
|
|
89
|
-
filename: outfile,
|
|
90
|
-
compact: !dev,
|
|
91
|
-
configFile: false,
|
|
92
|
-
babelrc: false,
|
|
93
|
-
minified: !dev,
|
|
94
|
-
browserslistConfigFile: false,
|
|
95
|
-
plugins: [linker],
|
|
96
|
-
});
|
|
97
|
-
if (!result)
|
|
98
|
-
logger.warn(`File ${outfile} could not be linked.`);
|
|
99
|
-
if (!result?.code) {
|
|
100
|
-
logger.warn(`File ${outfile} seems to be empty.`);
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
fs.writeFileSync(outfile, result.code, 'utf-8');
|
|
104
|
-
}
|
|
105
|
-
catch (e) {
|
|
106
|
-
logger.error('error linking');
|
|
107
|
-
if (fs.existsSync(`${outfile}.error`)) {
|
|
108
|
-
fs.unlinkSync(`${outfile}.error`);
|
|
109
|
-
}
|
|
110
|
-
fs.renameSync(outfile, `${outfile}.error`);
|
|
111
|
-
throw e;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
async function createEsbuildContext(builderOptions, context, entryPoints, external, outdir, tsConfigPath, mappedPaths, sourceFileCache, dev, isNodeModules, hash = false, chunks, platform, optimizedMappings) {
|
|
115
|
-
const workspaceRoot = context.workspaceRoot;
|
|
116
|
-
const projectMetadata = await context.getProjectMetadata(context.target.project);
|
|
117
|
-
const projectRoot = path.join(workspaceRoot, projectMetadata['root'] ?? '');
|
|
118
|
-
const browsers = getSupportedBrowsers(projectRoot, context.logger);
|
|
119
|
-
const target = transformSupportedBrowsersToTargets(browsers);
|
|
120
|
-
const optimizationOptions = normalizeOptimization(builderOptions.optimization);
|
|
121
|
-
const sourcemapOptions = normalizeSourceMaps(builderOptions.sourceMap);
|
|
122
|
-
const searchDirectories = await generateSearchDirectories([projectRoot, workspaceRoot]);
|
|
123
|
-
const postcssConfiguration = await loadPostcssConfiguration(searchDirectories);
|
|
124
|
-
const tailwindConfiguration = postcssConfiguration
|
|
125
|
-
? undefined
|
|
126
|
-
: await getTailwindConfig(searchDirectories);
|
|
127
|
-
const outputNames = {
|
|
128
|
-
bundles: '[name]',
|
|
129
|
-
media: 'media/[name]',
|
|
130
|
-
};
|
|
131
|
-
let fileReplacements;
|
|
132
|
-
if (builderOptions.fileReplacements) {
|
|
133
|
-
for (const replacement of builderOptions.fileReplacements) {
|
|
134
|
-
fileReplacements ??= {};
|
|
135
|
-
fileReplacements[path.join(workspaceRoot, replacement.replace)] = path.join(workspaceRoot, replacement.with);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
if (!optimizedMappings) {
|
|
139
|
-
tsConfigPath = createTsConfigForFederation(workspaceRoot, tsConfigPath, entryPoints);
|
|
140
|
-
}
|
|
141
|
-
const pluginOptions = createCompilerPluginOptions({
|
|
142
|
-
workspaceRoot,
|
|
143
|
-
optimizationOptions,
|
|
144
|
-
sourcemapOptions,
|
|
145
|
-
tsconfig: tsConfigPath,
|
|
146
|
-
outputNames,
|
|
147
|
-
fileReplacements,
|
|
148
|
-
externalDependencies: external,
|
|
149
|
-
preserveSymlinks: builderOptions.preserveSymlinks,
|
|
150
|
-
stylePreprocessorOptions: builderOptions.stylePreprocessorOptions,
|
|
151
|
-
advancedOptimizations: !dev,
|
|
152
|
-
inlineStyleLanguage: builderOptions.inlineStyleLanguage,
|
|
153
|
-
jit: false,
|
|
154
|
-
tailwindConfiguration,
|
|
155
|
-
postcssConfiguration,
|
|
156
|
-
incremental: !isNodeModules,
|
|
157
|
-
}, target, sourceFileCache);
|
|
158
|
-
const commonjsPluginModule = await import('@chialab/esbuild-plugin-commonjs');
|
|
159
|
-
const commonjsPlugin = commonjsPluginModule.default;
|
|
160
|
-
pluginOptions.styleOptions.externalDependencies = [];
|
|
161
|
-
const [compilerPlugin, pluginDisposed] = createAwaitableCompilerPlugin(pluginOptions.pluginOptions, pluginOptions.styleOptions);
|
|
162
|
-
const config = {
|
|
163
|
-
entryPoints: entryPoints.map(ep => ({
|
|
164
|
-
in: ep.fileName,
|
|
165
|
-
out: path.parse(ep.outName).name,
|
|
166
|
-
})),
|
|
167
|
-
outdir,
|
|
168
|
-
entryNames: hash ? '[name]-[hash]' : '[name]',
|
|
169
|
-
write: false,
|
|
170
|
-
external,
|
|
171
|
-
logLevel: 'warning',
|
|
172
|
-
bundle: true,
|
|
173
|
-
sourcemap: sourcemapOptions.scripts,
|
|
174
|
-
minify: !dev,
|
|
175
|
-
supported: {
|
|
176
|
-
'async-await': false,
|
|
177
|
-
'object-rest-spread': false,
|
|
178
|
-
},
|
|
179
|
-
splitting: chunks,
|
|
180
|
-
platform: platform ?? 'browser',
|
|
181
|
-
format: 'esm',
|
|
182
|
-
target: target,
|
|
183
|
-
logLimit: isNodeModules ? 1 : 0,
|
|
184
|
-
plugins: [
|
|
185
|
-
compilerPlugin,
|
|
186
|
-
...(mappedPaths && mappedPaths.length > 0 ? [createSharedMappingsPlugin(mappedPaths)] : []),
|
|
187
|
-
commonjsPlugin(),
|
|
188
|
-
],
|
|
189
|
-
define: {
|
|
190
|
-
...(!dev ? { ngDevMode: 'false' } : {}),
|
|
191
|
-
ngJitMode: 'false',
|
|
192
|
-
},
|
|
193
|
-
...(builderOptions.loader ? { loader: builderOptions.loader } : {}),
|
|
194
|
-
resolveExtensions: ['.ts', '.tsx', '.mjs', '.js', '.cjs'],
|
|
195
|
-
};
|
|
196
|
-
const ctx = await esbuild.context(config);
|
|
197
|
-
return { ctx, pluginDisposed };
|
|
198
|
-
}
|
|
199
|
-
async function getTailwindConfig(searchDirectories) {
|
|
200
|
-
const tailwindConfigurationPath = findTailwindConfiguration(searchDirectories);
|
|
201
|
-
if (!tailwindConfigurationPath) {
|
|
202
|
-
return undefined;
|
|
203
|
-
}
|
|
204
|
-
return {
|
|
205
|
-
file: tailwindConfigurationPath,
|
|
206
|
-
package: createRequire(tailwindConfigurationPath).resolve('tailwindcss'),
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
function createTsConfigForFederation(workspaceRoot, tsConfigPath, entryPoints) {
|
|
210
|
-
const fullTsConfigPath = path.join(workspaceRoot, tsConfigPath);
|
|
211
|
-
const tsconfigDir = path.dirname(fullTsConfigPath);
|
|
212
|
-
const filtered = entryPoints
|
|
213
|
-
.filter(ep => !ep.fileName.includes('/node_modules/') && !ep.fileName.startsWith('.'))
|
|
214
|
-
.map(ep => path.relative(tsconfigDir, ep.fileName).replace(/\\\\/g, '/'));
|
|
215
|
-
const tsconfigAsString = fs.readFileSync(fullTsConfigPath, 'utf-8');
|
|
216
|
-
const tsconfig = JSON5.parse(tsconfigAsString);
|
|
217
|
-
if (!tsconfig.include) {
|
|
218
|
-
tsconfig.include = [];
|
|
219
|
-
}
|
|
220
|
-
for (const ep of filtered) {
|
|
221
|
-
if (!tsconfig.include.includes(ep)) {
|
|
222
|
-
tsconfig.include.push(ep);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
const content = JSON5.stringify(tsconfig, null, 2);
|
|
226
|
-
const tsconfigFedPath = path.join(tsconfigDir, 'tsconfig.federation.json');
|
|
227
|
-
if (!doesFileExistAndJsonEqual(tsconfigFedPath, content)) {
|
|
228
|
-
fs.writeFileSync(tsconfigFedPath, JSON.stringify(tsconfig, null, 2));
|
|
229
|
-
}
|
|
230
|
-
tsConfigPath = tsconfigFedPath;
|
|
231
|
-
return tsConfigPath;
|
|
232
|
-
}
|
|
233
|
-
/**
|
|
234
|
-
* Checks if a file exists and if its content is equal to the provided content.
|
|
235
|
-
* If the file does not exist, it returns false.
|
|
236
|
-
* If the file or its content is invalid JSON, it returns false.
|
|
237
|
-
* @param {string} path - The path to the file
|
|
238
|
-
* @param {string} content - The content to compare with
|
|
239
|
-
* @returns {boolean} - Returns true if the file exists and its content is equal to the provided content
|
|
240
|
-
*/
|
|
241
|
-
function doesFileExistAndJsonEqual(path, content) {
|
|
242
|
-
if (!fs.existsSync(path)) {
|
|
243
|
-
return false;
|
|
244
|
-
}
|
|
245
|
-
try {
|
|
246
|
-
const currentContent = fs.readFileSync(path, 'utf-8');
|
|
247
|
-
const currentJson = JSON5.parse(currentContent);
|
|
248
|
-
const newJson = JSON5.parse(content);
|
|
249
|
-
return isDeepStrictEqual(currentJson, newJson);
|
|
250
|
-
}
|
|
251
|
-
catch {
|
|
252
|
-
return false;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
function writeResult(result, outdir) {
|
|
256
|
-
const writtenFiles = [];
|
|
257
|
-
for (const outFile of result.outputFiles ?? []) {
|
|
258
|
-
const fileName = path.basename(outFile.path);
|
|
259
|
-
const filePath = path.join(outdir, fileName);
|
|
260
|
-
fs.writeFileSync(filePath, outFile.text);
|
|
261
|
-
writtenFiles.push(filePath);
|
|
262
|
-
}
|
|
263
|
-
return writtenFiles;
|
|
264
|
-
}
|
|
265
|
-
export function loadEsmModule(modulePath) {
|
|
266
|
-
return new Function('modulePath', `return import(modulePath);`)(modulePath);
|
|
267
|
-
}
|
|
268
|
-
//
|
|
269
|
-
// Usually, ngServerMode is set during bundling. However, we need to infer this
|
|
270
|
-
// value at runtime as we are using the same shared bundle for @angular/core
|
|
271
|
-
// on the server and in the browser.
|
|
272
|
-
//
|
|
273
|
-
function setNgServerMode() {
|
|
274
|
-
const fileToPatch = 'node_modules/@angular/core/fesm2022/core.mjs';
|
|
275
|
-
const lineToAdd = `if (typeof globalThis.ngServerMode ==='undefined') globalThis.ngServerMode = (typeof window === 'undefined') ? true : false;`;
|
|
276
|
-
try {
|
|
277
|
-
if (fs.existsSync(fileToPatch)) {
|
|
278
|
-
let content = fs.readFileSync(fileToPatch, 'utf-8');
|
|
279
|
-
if (!content.includes(lineToAdd)) {
|
|
280
|
-
content = lineToAdd + '\n' + content;
|
|
281
|
-
fs.writeFileSync(fileToPatch, content);
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
catch {
|
|
286
|
-
console.error('Error patching file ', fileToPatch, '\nIs it write-protected?');
|
|
287
|
-
}
|
|
288
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"angular-locales.d.ts","sourceRoot":"","sources":["../../../src/utils/angular-locales.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAE/E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,
|
|
1
|
+
{"version":3,"file":"angular-locales.d.ts","sourceRoot":"","sources":["../../../src/utils/angular-locales.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAE/E,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EAAE,EACd,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,qEA0BzD"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { EntryPoint } from '@softarc/native-federation';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a tsconfig.federation.json that includes the federation entry points.
|
|
4
|
+
*/
|
|
5
|
+
export declare function createFederationTsConfig(workspaceRoot: string, tsConfigPath: string, entryPoints: EntryPoint[], optimizedMappings?: boolean): string;
|
|
6
|
+
//# sourceMappingURL=create-federation-tsconfig.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-federation-tsconfig.d.ts","sourceRoot":"","sources":["../../../src/utils/create-federation-tsconfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAM7D;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,EACpB,WAAW,EAAE,UAAU,EAAE,EACzB,iBAAiB,CAAC,EAAE,OAAO,GAC1B,MAAM,CAoCR"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import JSON5 from 'json5';
|
|
4
|
+
import { isDeepStrictEqual } from 'util';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a tsconfig.federation.json that includes the federation entry points.
|
|
7
|
+
*/
|
|
8
|
+
export function createFederationTsConfig(workspaceRoot, tsConfigPath, entryPoints, optimizedMappings) {
|
|
9
|
+
const fullTsConfigPath = path.join(workspaceRoot, tsConfigPath);
|
|
10
|
+
const tsconfigDir = path.dirname(fullTsConfigPath);
|
|
11
|
+
const tsconfigAsString = fs.readFileSync(fullTsConfigPath, 'utf-8');
|
|
12
|
+
const tsconfig = JSON5.parse(tsconfigAsString);
|
|
13
|
+
tsconfig.files = entryPoints
|
|
14
|
+
.filter(ep => ep.fileName.startsWith('.'))
|
|
15
|
+
.map(ep => path.relative(tsconfigDir, ep.fileName).replace(/\\\\/g, '/'));
|
|
16
|
+
if (optimizedMappings) {
|
|
17
|
+
const filtered = entryPoints
|
|
18
|
+
.filter(ep => !ep.fileName.startsWith('.'))
|
|
19
|
+
.map(ep => path.relative(tsconfigDir, ep.fileName).replace(/\\\\/g, '/'));
|
|
20
|
+
if (!tsconfig.include) {
|
|
21
|
+
tsconfig.include = [];
|
|
22
|
+
}
|
|
23
|
+
for (const ep of filtered) {
|
|
24
|
+
if (!tsconfig.include.includes(ep)) {
|
|
25
|
+
tsconfig.include.push(ep);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const content = JSON5.stringify(tsconfig, null, 2);
|
|
30
|
+
const tsconfigFedPath = path.join(tsconfigDir, 'tsconfig.federation.json');
|
|
31
|
+
if (!doesFileExistAndJsonEqual(tsconfigFedPath, content)) {
|
|
32
|
+
fs.writeFileSync(tsconfigFedPath, JSON.stringify(tsconfig, null, 2));
|
|
33
|
+
}
|
|
34
|
+
return tsconfigFedPath;
|
|
35
|
+
}
|
|
36
|
+
function doesFileExistAndJsonEqual(filePath, content) {
|
|
37
|
+
if (!fs.existsSync(filePath)) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const currentContent = fs.readFileSync(filePath, 'utf-8');
|
|
42
|
+
const currentJson = JSON5.parse(currentContent);
|
|
43
|
+
const newJson = JSON5.parse(content);
|
|
44
|
+
return isDeepStrictEqual(currentJson, newJson);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-fallback-platform.d.ts","sourceRoot":"","sources":["../../../src/utils/get-fallback-platform.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,wBAAwB,EAAE,MAAM,EAI5C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAMlE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const DEFAULT_SERVER_DEPS_LIST = [
|
|
2
|
+
'@angular/platform-server',
|
|
3
|
+
'@angular/platform-server/init',
|
|
4
|
+
'@angular/ssr',
|
|
5
|
+
];
|
|
6
|
+
export function getDefaultPlatform(cur) {
|
|
7
|
+
if (DEFAULT_SERVER_DEPS_LIST.find(e => cur.startsWith(e))) {
|
|
8
|
+
return 'node';
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
return 'browser';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import type { NormalizedContextOptions } from './normalize-context-options.js';
|
|
3
|
+
export interface NodeModulesBundleResult {
|
|
4
|
+
ctx: esbuild.BuildContext;
|
|
5
|
+
pluginDisposed: Promise<void>;
|
|
6
|
+
}
|
|
7
|
+
export declare function createNodeModulesEsbuildContext(options: NormalizedContextOptions): Promise<{
|
|
8
|
+
ctx: esbuild.BuildContext;
|
|
9
|
+
pluginDisposed: Promise<void>;
|
|
10
|
+
}>;
|
|
11
|
+
//# sourceMappingURL=node-modules-bundler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-modules-bundler.d.ts","sourceRoot":"","sources":["../../../src/utils/node-modules-bundler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAYnC,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAsD/E,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,wBAAsB,+BAA+B,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC;IAChG,GAAG,EAAE,OAAO,CAAC,YAAY,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B,CAAC,CAwED"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as esbuild from 'esbuild';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import { transformSupportedBrowsersToTargets, getSupportedBrowsers, JavaScriptTransformer, } from '@angular/build/private';
|
|
5
|
+
import { normalizeSourceMaps } from '@angular-devkit/build-angular/src/utils/index.js';
|
|
6
|
+
const LINKER_DECLARATION_PREFIX = 'ɵɵngDeclare';
|
|
7
|
+
/**
|
|
8
|
+
* Excludes @angular/core and @angular/compiler which define the declarations
|
|
9
|
+
* and would cause false positives.
|
|
10
|
+
*/
|
|
11
|
+
function requiresLinking(filePath, source) {
|
|
12
|
+
if (/[\\/]@angular[\\/](?:compiler|core)[\\/]/.test(filePath)) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return source.includes(LINKER_DECLARATION_PREFIX);
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Creates an esbuild plugin that applies the Angular linker to partially compiled
|
|
19
|
+
* Angular libraries like a design system.
|
|
20
|
+
*
|
|
21
|
+
* Uses Angular's JavaScriptTransformer which handles linking internally.
|
|
22
|
+
*/
|
|
23
|
+
function createAngularLinkerPlugin(jsTransformer, advancedOptimizations) {
|
|
24
|
+
return {
|
|
25
|
+
name: 'angular-linker',
|
|
26
|
+
setup(build) {
|
|
27
|
+
build.onLoad({ filter: /\.m?js$/ }, async (args) => {
|
|
28
|
+
const contents = await fs.promises.readFile(args.path, 'utf-8');
|
|
29
|
+
const needsLinking = requiresLinking(args.path, contents);
|
|
30
|
+
if (!needsLinking && !advancedOptimizations) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const result = await jsTransformer.transformData(args.path, contents, !needsLinking, undefined);
|
|
34
|
+
return {
|
|
35
|
+
contents: Buffer.from(result).toString('utf-8'),
|
|
36
|
+
loader: 'js',
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export async function createNodeModulesEsbuildContext(options) {
|
|
43
|
+
const { builderOptions, context, entryPoints, external, outdir, dev, hash, chunks, platform } = options;
|
|
44
|
+
const workspaceRoot = context.workspaceRoot;
|
|
45
|
+
const projectMetadata = await context.getProjectMetadata(context.target.project);
|
|
46
|
+
const projectRoot = path.join(workspaceRoot, projectMetadata['root'] ?? '');
|
|
47
|
+
const browsers = getSupportedBrowsers(projectRoot, context.logger);
|
|
48
|
+
const target = transformSupportedBrowsersToTargets(browsers);
|
|
49
|
+
const sourcemapOptions = normalizeSourceMaps(builderOptions.sourceMap);
|
|
50
|
+
const commonjsPluginModule = await import('@chialab/esbuild-plugin-commonjs');
|
|
51
|
+
const commonjsPlugin = commonjsPluginModule.default;
|
|
52
|
+
// Create JavaScriptTransformer for handling Angular partial compilation linking
|
|
53
|
+
const advancedOptimizations = !dev;
|
|
54
|
+
const jsTransformer = new JavaScriptTransformer({
|
|
55
|
+
sourcemap: !!sourcemapOptions.scripts,
|
|
56
|
+
thirdPartySourcemaps: false,
|
|
57
|
+
advancedOptimizations,
|
|
58
|
+
jit: false,
|
|
59
|
+
}, 1 // maxThreads - keep low for node_modules bundling
|
|
60
|
+
);
|
|
61
|
+
const config = {
|
|
62
|
+
entryPoints: entryPoints.map(ep => ({
|
|
63
|
+
in: ep.fileName,
|
|
64
|
+
out: path.parse(ep.outName).name,
|
|
65
|
+
})),
|
|
66
|
+
outdir,
|
|
67
|
+
entryNames: hash ? '[name]-[hash]' : '[name]',
|
|
68
|
+
write: false,
|
|
69
|
+
external,
|
|
70
|
+
logLevel: 'warning',
|
|
71
|
+
bundle: true,
|
|
72
|
+
sourcemap: sourcemapOptions.scripts,
|
|
73
|
+
minify: !dev,
|
|
74
|
+
supported: {
|
|
75
|
+
'async-await': false,
|
|
76
|
+
'object-rest-spread': false,
|
|
77
|
+
},
|
|
78
|
+
splitting: chunks,
|
|
79
|
+
platform: platform ?? 'browser',
|
|
80
|
+
format: 'esm',
|
|
81
|
+
target: target,
|
|
82
|
+
logLimit: 1,
|
|
83
|
+
plugins: [createAngularLinkerPlugin(jsTransformer, advancedOptimizations), commonjsPlugin()],
|
|
84
|
+
define: {
|
|
85
|
+
ngDevMode: dev ? 'true' : 'false',
|
|
86
|
+
ngJitMode: 'false',
|
|
87
|
+
},
|
|
88
|
+
...(builderOptions.loader ? { loader: builderOptions.loader } : {}),
|
|
89
|
+
resolveExtensions: ['.mjs', '.js', '.cjs'],
|
|
90
|
+
};
|
|
91
|
+
const ctx = await esbuild.context(config);
|
|
92
|
+
const originalDispose = ctx.dispose.bind(ctx);
|
|
93
|
+
ctx.dispose = async () => {
|
|
94
|
+
await originalDispose();
|
|
95
|
+
await jsTransformer.close();
|
|
96
|
+
};
|
|
97
|
+
return { ctx, pluginDisposed: Promise.resolve() };
|
|
98
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ApplicationBuilderOptions } from '@angular/build';
|
|
2
|
+
import type { BuilderContext } from '@angular-devkit/architect';
|
|
3
|
+
import type { SourceFileCache } from '@angular/build/private';
|
|
4
|
+
import type { FederationCache, EntryPoint, NFBuildAdapterOptions } from '@softarc/native-federation';
|
|
5
|
+
import type { PathToImport } from '@softarc/native-federation/internal';
|
|
6
|
+
export interface NormalizedContextOptions {
|
|
7
|
+
builderOptions: ApplicationBuilderOptions;
|
|
8
|
+
context: BuilderContext;
|
|
9
|
+
entryPoints: EntryPoint[];
|
|
10
|
+
external: string[];
|
|
11
|
+
outdir: string;
|
|
12
|
+
tsConfigPath?: string;
|
|
13
|
+
mappedPaths: PathToImport;
|
|
14
|
+
cache: FederationCache<SourceFileCache>;
|
|
15
|
+
dev: boolean;
|
|
16
|
+
isMappingOrExposed: boolean;
|
|
17
|
+
hash: boolean;
|
|
18
|
+
chunks?: boolean;
|
|
19
|
+
platform?: 'browser' | 'node';
|
|
20
|
+
optimizedMappings: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare function normalizeContextOptions(builderOptions: ApplicationBuilderOptions, context: BuilderContext, adapterOptions: NFBuildAdapterOptions<SourceFileCache>): NormalizedContextOptions;
|
|
23
|
+
//# sourceMappingURL=normalize-context-options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-context-options.d.ts","sourceRoot":"","sources":["../../../src/utils/normalize-context-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gBAAgB,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EACV,eAAe,EACf,UAAU,EACV,qBAAqB,EACtB,MAAM,4BAA4B,CAAC;AACpC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAExE,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,yBAAyB,CAAC;IAC1C,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,YAAY,CAAC;IAC1B,KAAK,EAAE,eAAe,CAAC,eAAe,CAAC,CAAC;IACxC,GAAG,EAAE,OAAO,CAAC;IACb,kBAAkB,EAAE,OAAO,CAAC;IAC5B,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,yBAAyB,EACzC,OAAO,EAAE,cAAc,EACvB,cAAc,EAAE,qBAAqB,CAAC,eAAe,CAAC,GACrD,wBAAwB,CAiB1B"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function normalizeContextOptions(builderOptions, context, adapterOptions) {
|
|
2
|
+
return {
|
|
3
|
+
builderOptions,
|
|
4
|
+
context,
|
|
5
|
+
entryPoints: adapterOptions.entryPoints,
|
|
6
|
+
external: adapterOptions.external,
|
|
7
|
+
outdir: adapterOptions.outdir,
|
|
8
|
+
tsConfigPath: adapterOptions.tsConfigPath,
|
|
9
|
+
mappedPaths: adapterOptions.mappedPaths,
|
|
10
|
+
cache: adapterOptions.cache,
|
|
11
|
+
dev: !!adapterOptions.dev,
|
|
12
|
+
isMappingOrExposed: !!adapterOptions.isMappingOrExposed,
|
|
13
|
+
hash: !!adapterOptions.hash,
|
|
14
|
+
chunks: adapterOptions.chunks,
|
|
15
|
+
platform: adapterOptions.platform,
|
|
16
|
+
optimizedMappings: !!adapterOptions.optimizedMappings,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { Plugin } from 'esbuild';
|
|
2
|
-
import type {
|
|
3
|
-
export declare function createSharedMappingsPlugin(mappedPaths:
|
|
2
|
+
import type { PathToImport } from '@softarc/native-federation/internal';
|
|
3
|
+
export declare function createSharedMappingsPlugin(mappedPaths: PathToImport): Plugin;
|
|
4
4
|
//# sourceMappingURL=shared-mappings-plugin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared-mappings-plugin.d.ts","sourceRoot":"","sources":["../../../src/utils/shared-mappings-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"shared-mappings-plugin.d.ts","sourceRoot":"","sources":["../../../src/utils/shared-mappings-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,SAAS,CAAC;AAEnD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AAExE,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,YAAY,GAAG,MAAM,CA8B5E"}
|
|
@@ -4,20 +4,20 @@ export function createSharedMappingsPlugin(mappedPaths) {
|
|
|
4
4
|
name: 'custom',
|
|
5
5
|
setup(build) {
|
|
6
6
|
build.onResolve({ filter: /^[.]/ }, async (args) => {
|
|
7
|
-
let mappedPath =
|
|
7
|
+
let mappedPath = undefined;
|
|
8
8
|
let isSelf = false;
|
|
9
9
|
if (args.kind === 'import-statement') {
|
|
10
10
|
const importPath = path.join(args.resolveDir, args.path);
|
|
11
11
|
if (mappedPaths) {
|
|
12
|
-
mappedPath = mappedPaths.find(p => importPath.startsWith(path.dirname(p
|
|
12
|
+
mappedPath = Object.keys(mappedPaths).find(p => importPath.startsWith(path.dirname(p)));
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
if (mappedPath) {
|
|
16
|
-
isSelf = args.importer.startsWith(path.dirname(mappedPath
|
|
16
|
+
isSelf = args.importer.startsWith(path.dirname(mappedPath));
|
|
17
17
|
}
|
|
18
18
|
if (mappedPath && !isSelf) {
|
|
19
19
|
return {
|
|
20
|
-
path: mappedPath
|
|
20
|
+
path: mappedPaths[mappedPath],
|
|
21
21
|
external: true,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { type SourceFileCache } from '@angular/build/private';
|
|
2
|
-
export declare function createCompilerPluginOptions(options: any, target: string[], sourceFileCache?: SourceFileCache): {
|
|
3
|
-
pluginOptions: any[0];
|
|
4
|
-
styleOptions: any[1];
|
|
5
|
-
};
|
|
6
|
-
//# sourceMappingURL=create-compiler-options.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-compiler-options.d.ts","sourceRoot":"","sources":["../../../src/utils/create-compiler-options.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,EAAE,EAChB,eAAe,CAAC,EAAE,eAAe,GAChC;IACD,aAAa,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IACtB,YAAY,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;CACtB,CAwDA"}
|