@nx/angular 19.8.0-canary.20240914-dc821ab → 19.8.0-canary.20240918-eb61254
Sign up to get free protection for your applications and to get access to all the features.
- package/esm2022/mf/mf.mjs +3 -2
- package/fesm2022/nx-angular-mf.mjs +2 -1
- package/fesm2022/nx-angular-mf.mjs.map +1 -1
- package/package.json +9 -8
- package/plugin.d.ts +1 -0
- package/plugin.js +5 -0
- package/src/generators/application/application.js +2 -1
- package/src/generators/application/lib/add-e2e.d.ts +1 -1
- package/src/generators/application/lib/add-e2e.js +1 -23
- package/src/generators/application/lib/add-serve-static-target.d.ts +3 -0
- package/src/generators/application/lib/add-serve-static-target.js +29 -0
- package/src/generators/application/lib/index.d.ts +1 -0
- package/src/generators/application/lib/index.js +1 -0
- package/src/generators/init/init.js +12 -0
- package/src/generators/init/schema.d.ts +3 -0
- package/src/generators/utils/add-mf-env-to-inputs.js +6 -4
- package/src/migrations/update-19-6-1/ensure-depends-on-for-mf.js +7 -1
- package/src/plugins/plugin.d.ts +19 -0
- package/src/plugins/plugin.js +418 -0
package/esm2022/mf/mf.mjs
CHANGED
@@ -2,11 +2,12 @@ let resolveRemoteUrl;
|
|
2
2
|
export function setRemoteUrlResolver(_resolveRemoteUrl) {
|
3
3
|
resolveRemoteUrl = _resolveRemoteUrl;
|
4
4
|
}
|
5
|
-
let remoteUrlDefinitions
|
5
|
+
let remoteUrlDefinitions;
|
6
6
|
export function setRemoteDefinitions(definitions) {
|
7
7
|
remoteUrlDefinitions = definitions;
|
8
8
|
}
|
9
9
|
export function setRemoteDefinition(remoteName, remoteUrl) {
|
10
|
+
remoteUrlDefinitions ??= {};
|
10
11
|
remoteUrlDefinitions[remoteName] = remoteUrl;
|
11
12
|
}
|
12
13
|
let remoteModuleMap = new Map();
|
@@ -48,4 +49,4 @@ async function loadRemoteContainer(remoteName) {
|
|
48
49
|
remoteContainerMap.set(remoteName, container);
|
49
50
|
return container;
|
50
51
|
}
|
51
|
-
//# sourceMappingURL=data:application/json;base64,
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9hbmd1bGFyL21mL21mLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLElBQUksZ0JBQTBDLENBQUM7QUFFL0MsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxpQkFBMkM7SUFFM0MsZ0JBQWdCLEdBQUcsaUJBQWlCLENBQUM7QUFDdkMsQ0FBQztBQUVELElBQUksb0JBQTRDLENBQUM7QUFFakQsTUFBTSxVQUFVLG9CQUFvQixDQUFDLFdBQW1DO0lBQ3RFLG9CQUFvQixHQUFHLFdBQVcsQ0FBQztBQUNyQyxDQUFDO0FBRUQsTUFBTSxVQUFVLG1CQUFtQixDQUFDLFVBQWtCLEVBQUUsU0FBaUI7SUFDdkUsb0JBQW9CLEtBQUssRUFBRSxDQUFDO0lBQzVCLG9CQUFvQixDQUFDLFVBQVUsQ0FBQyxHQUFHLFNBQVMsQ0FBQztBQUMvQyxDQUFDO0FBRUQsSUFBSSxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQW1CLENBQUM7QUFDakQsSUFBSSxrQkFBa0IsR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztBQUVwRCxNQUFNLENBQUMsS0FBSyxVQUFVLGdCQUFnQixDQUFDLFVBQWtCLEVBQUUsVUFBa0I7SUFDM0UsTUFBTSxlQUFlLEdBQUcsR0FBRyxVQUFVLElBQUksVUFBVSxFQUFFLENBQUM7SUFDdEQsSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxFQUFFLENBQUM7UUFDekMsT0FBTyxlQUFlLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxNQUFNLFNBQVMsR0FBRyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO1FBQ2xELENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDO1FBQ3BDLENBQUMsQ0FBQyxNQUFNLG1CQUFtQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBRTFDLE1BQU0sT0FBTyxHQUFHLE1BQU0sU0FBUyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNoRCxNQUFNLE1BQU0sR0FBRyxPQUFPLEVBQUUsQ0FBQztJQUV6QixlQUFlLENBQUMsR0FBRyxDQUFDLGVBQWUsRUFBRSxNQUFNLENBQUMsQ0FBQztJQUU3QyxPQUFPLE1BQU0sQ0FBQztBQUNoQixDQUFDO0FBRUQsU0FBUyxVQUFVLENBQUMsR0FBVztJQUM3QixPQUFPLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBRUQsSUFBSSwwQkFBMEIsR0FBRyxLQUFLLENBQUM7QUFFdkMsS0FBSyxVQUFVLG1CQUFtQixDQUFDLFVBQWtCO0lBQ25ELElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLG9CQUFvQixFQUFFLENBQUM7UUFDL0MsTUFBTSxJQUFJLEtBQUssQ0FDYixrSEFBa0gsQ0FDbkgsQ0FBQztJQUNKLENBQUM7SUFFRCxJQUFJLENBQUMsMEJBQTBCLEVBQUUsQ0FBQztRQUNoQywwQkFBMEIsR0FBRyxJQUFJLENBQUM7UUFDbEMsTUFBTSx3QkFBd0IsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUM1QyxDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsb0JBQW9CO1FBQ3BDLENBQUMsQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLENBQUM7UUFDbEMsQ0FBQyxDQUFDLE1BQU0sZ0JBQWdCLENBQUMsVUFBVSxDQUFDLENBQUM7SUFFdkMsSUFBSSxZQUFZLEdBQUcsU0FBUyxDQUFDO0lBQzdCLElBQUksQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzlELFlBQVksR0FBRyxHQUFHLFNBQVMsR0FDekIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUNqQyxpQkFBaUIsQ0FBQztJQUNwQixDQUFDO0lBRUQsTUFBTSxTQUFTLEdBQUcsTUFBTSxVQUFVLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDakQsTUFBTSxTQUFTLENBQUMsSUFBSSxDQUFDLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBRXZELGtCQUFrQixDQUFDLEdBQUcsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDOUMsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB0eXBlIFJlc29sdmVSZW1vdGVVcmxGdW5jdGlvbiA9IChcbiAgcmVtb3RlTmFtZTogc3RyaW5nXG4pID0+IHN0cmluZyB8IFByb21pc2U8c3RyaW5nPjtcblxuZGVjbGFyZSBjb25zdCBfX3dlYnBhY2tfaW5pdF9zaGFyaW5nX186IChzY29wZTogJ2RlZmF1bHQnKSA9PiBQcm9taXNlPHZvaWQ+O1xuZGVjbGFyZSBjb25zdCBfX3dlYnBhY2tfc2hhcmVfc2NvcGVzX186IHsgZGVmYXVsdDogdW5rbm93biB9O1xuXG5sZXQgcmVzb2x2ZVJlbW90ZVVybDogUmVzb2x2ZVJlbW90ZVVybEZ1bmN0aW9uO1xuXG5leHBvcnQgZnVuY3Rpb24gc2V0UmVtb3RlVXJsUmVzb2x2ZXIoXG4gIF9yZXNvbHZlUmVtb3RlVXJsOiBSZXNvbHZlUmVtb3RlVXJsRnVuY3Rpb25cbikge1xuICByZXNvbHZlUmVtb3RlVXJsID0gX3Jlc29sdmVSZW1vdGVVcmw7XG59XG5cbmxldCByZW1vdGVVcmxEZWZpbml0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcblxuZXhwb3J0IGZ1bmN0aW9uIHNldFJlbW90ZURlZmluaXRpb25zKGRlZmluaXRpb25zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KSB7XG4gIHJlbW90ZVVybERlZmluaXRpb25zID0gZGVmaW5pdGlvbnM7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRSZW1vdGVEZWZpbml0aW9uKHJlbW90ZU5hbWU6IHN0cmluZywgcmVtb3RlVXJsOiBzdHJpbmcpIHtcbiAgcmVtb3RlVXJsRGVmaW5pdGlvbnMgPz89IHt9O1xuICByZW1vdGVVcmxEZWZpbml0aW9uc1tyZW1vdGVOYW1lXSA9IHJlbW90ZVVybDtcbn1cblxubGV0IHJlbW90ZU1vZHVsZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xubGV0IHJlbW90ZUNvbnRhaW5lck1hcCA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbG9hZFJlbW90ZU1vZHVsZShyZW1vdGVOYW1lOiBzdHJpbmcsIG1vZHVsZU5hbWU6IHN0cmluZykge1xuICBjb25zdCByZW1vdGVNb2R1bGVLZXkgPSBgJHtyZW1vdGVOYW1lfToke21vZHVsZU5hbWV9YDtcbiAgaWYgKHJlbW90ZU1vZHVsZU1hcC5oYXMocmVtb3RlTW9kdWxlS2V5KSkge1xuICAgIHJldHVybiByZW1vdGVNb2R1bGVNYXAuZ2V0KHJlbW90ZU1vZHVsZUtleSk7XG4gIH1cblxuICBjb25zdCBjb250YWluZXIgPSByZW1vdGVDb250YWluZXJNYXAuaGFzKHJlbW90ZU5hbWUpXG4gICAgPyByZW1vdGVDb250YWluZXJNYXAuZ2V0KHJlbW90ZU5hbWUpXG4gICAgOiBhd2FpdCBsb2FkUmVtb3RlQ29udGFpbmVyKHJlbW90ZU5hbWUpO1xuXG4gIGNvbnN0IGZhY3RvcnkgPSBhd2FpdCBjb250YWluZXIuZ2V0KG1vZHVsZU5hbWUpO1xuICBjb25zdCBNb2R1bGUgPSBmYWN0b3J5KCk7XG5cbiAgcmVtb3RlTW9kdWxlTWFwLnNldChyZW1vdGVNb2R1bGVLZXksIE1vZHVsZSk7XG5cbiAgcmV0dXJuIE1vZHVsZTtcbn1cblxuZnVuY3Rpb24gbG9hZE1vZHVsZSh1cmw6IHN0cmluZykge1xuICByZXR1cm4gaW1wb3J0KC8qIHdlYnBhY2tJZ25vcmU6dHJ1ZSAqLyB1cmwpO1xufVxuXG5sZXQgaW5pdGlhbFNoYXJpbmdTY29wZUNyZWF0ZWQgPSBmYWxzZTtcblxuYXN5bmMgZnVuY3Rpb24gbG9hZFJlbW90ZUNvbnRhaW5lcihyZW1vdGVOYW1lOiBzdHJpbmcpIHtcbiAgaWYgKCFyZXNvbHZlUmVtb3RlVXJsICYmICFyZW1vdGVVcmxEZWZpbml0aW9ucykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdDYWxsIHNldFJlbW90ZURlZmluaXRpb25zIG9yIHNldFJlbW90ZVVybFJlc29sdmVyIHRvIGFsbG93IER5bmFtaWMgRmVkZXJhdGlvbiB0byBmaW5kIHRoZSByZW1vdGUgYXBwcyBjb3JyZWN0bHkuJ1xuICAgICk7XG4gIH1cblxuICBpZiAoIWluaXRpYWxTaGFyaW5nU2NvcGVDcmVhdGVkKSB7XG4gICAgaW5pdGlhbFNoYXJpbmdTY29wZUNyZWF0ZWQgPSB0cnVlO1xuICAgIGF3YWl0IF9fd2VicGFja19pbml0X3NoYXJpbmdfXygnZGVmYXVsdCcpO1xuICB9XG5cbiAgY29uc3QgcmVtb3RlVXJsID0gcmVtb3RlVXJsRGVmaW5pdGlvbnNcbiAgICA/IHJlbW90ZVVybERlZmluaXRpb25zW3JlbW90ZU5hbWVdXG4gICAgOiBhd2FpdCByZXNvbHZlUmVtb3RlVXJsKHJlbW90ZU5hbWUpO1xuXG4gIGxldCBjb250YWluZXJVcmwgPSByZW1vdGVVcmw7XG4gIGlmICghcmVtb3RlVXJsLmVuZHNXaXRoKCcubWpzJykgJiYgIXJlbW90ZVVybC5lbmRzV2l0aCgnLmpzJykpIHtcbiAgICBjb250YWluZXJVcmwgPSBgJHtyZW1vdGVVcmx9JHtcbiAgICAgIHJlbW90ZVVybC5lbmRzV2l0aCgnLycpID8gJycgOiAnLydcbiAgICB9cmVtb3RlRW50cnkubWpzYDtcbiAgfVxuXG4gIGNvbnN0IGNvbnRhaW5lciA9IGF3YWl0IGxvYWRNb2R1bGUoY29udGFpbmVyVXJsKTtcbiAgYXdhaXQgY29udGFpbmVyLmluaXQoX193ZWJwYWNrX3NoYXJlX3Njb3Blc19fLmRlZmF1bHQpO1xuXG4gIHJlbW90ZUNvbnRhaW5lck1hcC5zZXQocmVtb3RlTmFtZSwgY29udGFpbmVyKTtcbiAgcmV0dXJuIGNvbnRhaW5lcjtcbn1cbiJdfQ==
|
@@ -2,11 +2,12 @@ let resolveRemoteUrl;
|
|
2
2
|
function setRemoteUrlResolver(_resolveRemoteUrl) {
|
3
3
|
resolveRemoteUrl = _resolveRemoteUrl;
|
4
4
|
}
|
5
|
-
let remoteUrlDefinitions
|
5
|
+
let remoteUrlDefinitions;
|
6
6
|
function setRemoteDefinitions(definitions) {
|
7
7
|
remoteUrlDefinitions = definitions;
|
8
8
|
}
|
9
9
|
function setRemoteDefinition(remoteName, remoteUrl) {
|
10
|
+
remoteUrlDefinitions ??= {};
|
10
11
|
remoteUrlDefinitions[remoteName] = remoteUrl;
|
11
12
|
}
|
12
13
|
let remoteModuleMap = new Map();
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"nx-angular-mf.mjs","sources":["../../../../packages/angular/mf/mf.ts","../../../../packages/angular/mf/nx-angular-mf.ts"],"sourcesContent":["export type ResolveRemoteUrlFunction = (\n remoteName: string\n) => string | Promise<string>;\n\ndeclare const __webpack_init_sharing__: (scope: 'default') => Promise<void>;\ndeclare const __webpack_share_scopes__: { default: unknown };\n\nlet resolveRemoteUrl: ResolveRemoteUrlFunction;\nexport function setRemoteUrlResolver(\n _resolveRemoteUrl: ResolveRemoteUrlFunction\n) {\n resolveRemoteUrl = _resolveRemoteUrl;\n}\n\nlet remoteUrlDefinitions: Record<string, string
|
1
|
+
{"version":3,"file":"nx-angular-mf.mjs","sources":["../../../../packages/angular/mf/mf.ts","../../../../packages/angular/mf/nx-angular-mf.ts"],"sourcesContent":["export type ResolveRemoteUrlFunction = (\n remoteName: string\n) => string | Promise<string>;\n\ndeclare const __webpack_init_sharing__: (scope: 'default') => Promise<void>;\ndeclare const __webpack_share_scopes__: { default: unknown };\n\nlet resolveRemoteUrl: ResolveRemoteUrlFunction;\n\nexport function setRemoteUrlResolver(\n _resolveRemoteUrl: ResolveRemoteUrlFunction\n) {\n resolveRemoteUrl = _resolveRemoteUrl;\n}\n\nlet remoteUrlDefinitions: Record<string, string>;\n\nexport function setRemoteDefinitions(definitions: Record<string, string>) {\n remoteUrlDefinitions = definitions;\n}\n\nexport function setRemoteDefinition(remoteName: string, remoteUrl: string) {\n remoteUrlDefinitions ??= {};\n remoteUrlDefinitions[remoteName] = remoteUrl;\n}\n\nlet remoteModuleMap = new Map<string, unknown>();\nlet remoteContainerMap = new Map<string, unknown>();\n\nexport async function loadRemoteModule(remoteName: string, moduleName: string) {\n const remoteModuleKey = `${remoteName}:${moduleName}`;\n if (remoteModuleMap.has(remoteModuleKey)) {\n return remoteModuleMap.get(remoteModuleKey);\n }\n\n const container = remoteContainerMap.has(remoteName)\n ? remoteContainerMap.get(remoteName)\n : await loadRemoteContainer(remoteName);\n\n const factory = await container.get(moduleName);\n const Module = factory();\n\n remoteModuleMap.set(remoteModuleKey, Module);\n\n return Module;\n}\n\nfunction loadModule(url: string) {\n return import(/* webpackIgnore:true */ url);\n}\n\nlet initialSharingScopeCreated = false;\n\nasync function loadRemoteContainer(remoteName: string) {\n if (!resolveRemoteUrl && !remoteUrlDefinitions) {\n throw new Error(\n 'Call setRemoteDefinitions or setRemoteUrlResolver to allow Dynamic Federation to find the remote apps correctly.'\n );\n }\n\n if (!initialSharingScopeCreated) {\n initialSharingScopeCreated = true;\n await __webpack_init_sharing__('default');\n }\n\n const remoteUrl = remoteUrlDefinitions\n ? remoteUrlDefinitions[remoteName]\n : await resolveRemoteUrl(remoteName);\n\n let containerUrl = remoteUrl;\n if (!remoteUrl.endsWith('.mjs') && !remoteUrl.endsWith('.js')) {\n containerUrl = `${remoteUrl}${\n remoteUrl.endsWith('/') ? '' : '/'\n }remoteEntry.mjs`;\n }\n\n const container = await loadModule(containerUrl);\n await container.init(__webpack_share_scopes__.default);\n\n remoteContainerMap.set(remoteName, container);\n return container;\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"AAOA,IAAI,gBAA0C,CAAC;AAEzC,SAAU,oBAAoB,CAClC,iBAA2C,EAAA;IAE3C,gBAAgB,GAAG,iBAAiB,CAAC;AACvC,CAAC;AAED,IAAI,oBAA4C,CAAC;AAE3C,SAAU,oBAAoB,CAAC,WAAmC,EAAA;IACtE,oBAAoB,GAAG,WAAW,CAAC;AACrC,CAAC;AAEe,SAAA,mBAAmB,CAAC,UAAkB,EAAE,SAAiB,EAAA;IACvE,oBAAoB,KAAK,EAAE,CAAC;AAC5B,IAAA,oBAAoB,CAAC,UAAU,CAAC,GAAG,SAAS,CAAC;AAC/C,CAAC;AAED,IAAI,eAAe,GAAG,IAAI,GAAG,EAAmB,CAAC;AACjD,IAAI,kBAAkB,GAAG,IAAI,GAAG,EAAmB,CAAC;AAE7C,eAAe,gBAAgB,CAAC,UAAkB,EAAE,UAAkB,EAAA;AAC3E,IAAA,MAAM,eAAe,GAAG,CAAA,EAAG,UAAU,CAAI,CAAA,EAAA,UAAU,EAAE,CAAC;AACtD,IAAA,IAAI,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,EAAE;AACxC,QAAA,OAAO,eAAe,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;KAC7C;AAED,IAAA,MAAM,SAAS,GAAG,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;AAClD,UAAE,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC;AACpC,UAAE,MAAM,mBAAmB,CAAC,UAAU,CAAC,CAAC;IAE1C,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAChD,IAAA,MAAM,MAAM,GAAG,OAAO,EAAE,CAAC;AAEzB,IAAA,eAAe,CAAC,GAAG,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;AAE7C,IAAA,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS,UAAU,CAAC,GAAW,EAAA;AAC7B,IAAA,OAAO,gCAAgC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,IAAI,0BAA0B,GAAG,KAAK,CAAC;AAEvC,eAAe,mBAAmB,CAAC,UAAkB,EAAA;AACnD,IAAA,IAAI,CAAC,gBAAgB,IAAI,CAAC,oBAAoB,EAAE;AAC9C,QAAA,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAC;KACH;IAED,IAAI,CAAC,0BAA0B,EAAE;QAC/B,0BAA0B,GAAG,IAAI,CAAC;AAClC,QAAA,MAAM,wBAAwB,CAAC,SAAS,CAAC,CAAC;KAC3C;IAED,MAAM,SAAS,GAAG,oBAAoB;AACpC,UAAE,oBAAoB,CAAC,UAAU,CAAC;AAClC,UAAE,MAAM,gBAAgB,CAAC,UAAU,CAAC,CAAC;IAEvC,IAAI,YAAY,GAAG,SAAS,CAAC;AAC7B,IAAA,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC7D,QAAA,YAAY,GAAG,CAAG,EAAA,SAAS,GACzB,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,GACjC,iBAAiB,CAAC;KACnB;AAED,IAAA,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;IACjD,MAAM,SAAS,CAAC,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;AAEvD,IAAA,kBAAkB,CAAC,GAAG,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;AAC9C,IAAA,OAAO,SAAS,CAAC;AACnB;;ACjFA;;AAEG;;;;"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@nx/angular",
|
3
|
-
"version": "19.8.0-canary.
|
3
|
+
"version": "19.8.0-canary.20240918-eb61254",
|
4
4
|
"private": false,
|
5
5
|
"description": "The Nx Plugin for Angular contains executors, generators, and utilities for managing Angular applications and libraries within an Nx workspace. It provides: \n\n- Integration with libraries such as Storybook, Jest, ESLint, Tailwind CSS, Playwright and Cypress. \n\n- Generators to help scaffold code quickly (like: Micro Frontends, Libraries, both internal to your codebase and publishable to npm) \n\n- Single Component Application Modules (SCAMs) \n\n- NgRx helpers. \n\n- Utilities for automatic workspace refactoring.",
|
6
6
|
"repository": {
|
@@ -22,6 +22,7 @@
|
|
22
22
|
"./executors.json": "./executors.json",
|
23
23
|
"./generators": "./generators.js",
|
24
24
|
"./executors": "./executors.js",
|
25
|
+
"./plugin": "./plugin.js",
|
25
26
|
"./tailwind": "./tailwind.js",
|
26
27
|
"./module-federation": "./module-federation/index.js",
|
27
28
|
"./src/utils": "./src/utils/index.js",
|
@@ -79,14 +80,14 @@
|
|
79
80
|
"webpack-merge": "^5.8.0",
|
80
81
|
"webpack": "^5.88.0",
|
81
82
|
"@module-federation/enhanced": "~0.6.0",
|
82
|
-
"@nx/devkit": "19.8.0-canary.
|
83
|
-
"@nx/js": "19.8.0-canary.
|
84
|
-
"@nx/eslint": "19.8.0-canary.
|
85
|
-
"@nx/webpack": "19.8.0-canary.
|
86
|
-
"@nx/web": "19.8.0-canary.
|
87
|
-
"@nx/workspace": "19.8.0-canary.
|
83
|
+
"@nx/devkit": "19.8.0-canary.20240918-eb61254",
|
84
|
+
"@nx/js": "19.8.0-canary.20240918-eb61254",
|
85
|
+
"@nx/eslint": "19.8.0-canary.20240918-eb61254",
|
86
|
+
"@nx/webpack": "19.8.0-canary.20240918-eb61254",
|
87
|
+
"@nx/web": "19.8.0-canary.20240918-eb61254",
|
88
|
+
"@nx/workspace": "19.8.0-canary.20240918-eb61254",
|
88
89
|
"piscina": "^4.4.0",
|
89
|
-
"@nrwl/angular": "19.8.0-canary.
|
90
|
+
"@nrwl/angular": "19.8.0-canary.20240918-eb61254"
|
90
91
|
},
|
91
92
|
"peerDependencies": {
|
92
93
|
"@angular-devkit/build-angular": ">= 16.0.0 < 19.0.0",
|
package/plugin.d.ts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
export { createNodesV2 } from './src/plugins/plugin';
|
package/plugin.js
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.createNodesV2 = void 0;
|
4
|
+
var plugin_1 = require("./src/plugins/plugin");
|
5
|
+
Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return plugin_1.createNodesV2; } });
|
@@ -43,7 +43,8 @@ async function applicationGeneratorInternal(tree, schema) {
|
|
43
43
|
}
|
44
44
|
await (0, lib_1.addLinting)(tree, options);
|
45
45
|
await (0, lib_1.addUnitTestRunner)(tree, options);
|
46
|
-
await (0, lib_1.addE2e)(tree, options);
|
46
|
+
const e2ePort = await (0, lib_1.addE2e)(tree, options);
|
47
|
+
(0, lib_1.addServeStaticTarget)(tree, options, options.e2eTestRunner !== 'none' ? e2ePort : options.port);
|
47
48
|
(0, lib_1.updateEditorTsConfig)(tree, options);
|
48
49
|
(0, lib_1.setGeneratorDefaults)(tree, options);
|
49
50
|
if (options.rootProject) {
|
@@ -1,3 +1,3 @@
|
|
1
1
|
import { Tree } from '@nx/devkit';
|
2
2
|
import type { NormalizedSchema } from './normalized-schema';
|
3
|
-
export declare function addE2e(tree: Tree, options: NormalizedSchema): Promise<
|
3
|
+
export declare function addE2e(tree: Tree, options: NormalizedSchema): Promise<number>;
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.addE2e = addE2e;
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
5
5
|
const versions_1 = require("../../../utils/versions");
|
6
|
-
const version_utils_1 = require("../../utils/version-utils");
|
7
6
|
const target_defaults_utils_1 = require("@nx/devkit/src/generators/target-defaults-utils");
|
8
7
|
async function addE2e(tree, options) {
|
9
8
|
// since e2e are separate projects, default to adding plugins
|
@@ -11,8 +10,6 @@ async function addE2e(tree, options) {
|
|
11
10
|
const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
|
12
11
|
nxJson.useInferencePlugins !== false;
|
13
12
|
const e2eWebServerInfo = getAngularE2EWebServerInfo(tree, options.name, options.port);
|
14
|
-
// TODO: This can call `@nx/web:static-config` generator when ready
|
15
|
-
addFileServerTarget(tree, options, 'serve-static', e2eWebServerInfo.e2ePort);
|
16
13
|
if (options.e2eTestRunner === 'cypress') {
|
17
14
|
const { configurationGenerator } = (0, devkit_1.ensurePackage)('@nx/cypress', versions_1.nxVersion);
|
18
15
|
(0, devkit_1.addProjectConfiguration)(tree, options.e2eProjectName, {
|
@@ -70,26 +67,7 @@ async function addE2e(tree, options) {
|
|
70
67
|
await (0, target_defaults_utils_1.addE2eCiTargetDefaults)(tree, '@nx/playwright/plugin', '^build', (0, devkit_1.joinPathFragments)(options.e2eProjectRoot, 'playwright.config.ts'));
|
71
68
|
}
|
72
69
|
}
|
73
|
-
|
74
|
-
function addFileServerTarget(tree, options, targetName, e2ePort) {
|
75
|
-
if (!options.skipPackageJson) {
|
76
|
-
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@nx/web': versions_1.nxVersion });
|
77
|
-
}
|
78
|
-
const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
|
79
|
-
const isUsingApplicationBuilder = angularMajorVersion >= 17 && options.bundler === 'esbuild';
|
80
|
-
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.name);
|
81
|
-
projectConfig.targets[targetName] = {
|
82
|
-
executor: '@nx/web:file-server',
|
83
|
-
options: {
|
84
|
-
buildTarget: `${options.name}:build`,
|
85
|
-
port: e2ePort,
|
86
|
-
staticFilePath: isUsingApplicationBuilder
|
87
|
-
? (0, devkit_1.joinPathFragments)(options.outputPath, 'browser')
|
88
|
-
: undefined,
|
89
|
-
spa: true,
|
90
|
-
},
|
91
|
-
};
|
92
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.name, projectConfig);
|
70
|
+
return e2eWebServerInfo.e2ePort;
|
93
71
|
}
|
94
72
|
function getAngularE2EWebServerInfo(tree, projectName, portOverride) {
|
95
73
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
@@ -0,0 +1,29 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.addServeStaticTarget = addServeStaticTarget;
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
5
|
+
const versions_1 = require("../../../utils/versions");
|
6
|
+
const version_utils_1 = require("../../utils/version-utils");
|
7
|
+
function addServeStaticTarget(tree, options, port) {
|
8
|
+
addFileServerTarget(tree, options, 'serve-static', port);
|
9
|
+
}
|
10
|
+
function addFileServerTarget(tree, options, targetName, e2ePort) {
|
11
|
+
if (!options.skipPackageJson) {
|
12
|
+
(0, devkit_1.addDependenciesToPackageJson)(tree, {}, { '@nx/web': versions_1.nxVersion });
|
13
|
+
}
|
14
|
+
const { major: angularMajorVersion } = (0, version_utils_1.getInstalledAngularVersionInfo)(tree);
|
15
|
+
const isUsingApplicationBuilder = angularMajorVersion >= 17 && options.bundler === 'esbuild';
|
16
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.name);
|
17
|
+
projectConfig.targets[targetName] = {
|
18
|
+
executor: '@nx/web:file-server',
|
19
|
+
options: {
|
20
|
+
buildTarget: `${options.name}:build`,
|
21
|
+
port: e2ePort,
|
22
|
+
staticFilePath: isUsingApplicationBuilder
|
23
|
+
? (0, devkit_1.joinPathFragments)(options.outputPath, 'browser')
|
24
|
+
: undefined,
|
25
|
+
spa: true,
|
26
|
+
},
|
27
|
+
};
|
28
|
+
(0, devkit_1.updateProjectConfiguration)(tree, options.name, projectConfig);
|
29
|
+
}
|
@@ -13,3 +13,4 @@ tslib_1.__exportStar(require("./normalized-schema"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./set-app-strict-default"), exports);
|
14
14
|
tslib_1.__exportStar(require("./set-generator-defaults"), exports);
|
15
15
|
tslib_1.__exportStar(require("./update-editor-tsconfig"), exports);
|
16
|
+
tslib_1.__exportStar(require("./add-serve-static-target"), exports);
|
@@ -2,10 +2,22 @@
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
3
|
exports.angularInitGenerator = angularInitGenerator;
|
4
4
|
const devkit_1 = require("@nx/devkit");
|
5
|
+
const add_plugin_1 = require("@nx/devkit/src/utils/add-plugin");
|
5
6
|
const version_utils_1 = require("../utils/version-utils");
|
7
|
+
const plugin_1 = require("../../plugins/plugin");
|
6
8
|
async function angularInitGenerator(tree, options) {
|
7
9
|
ignoreAngularCacheDirectory(tree);
|
8
10
|
const installTask = installAngularDevkitCoreIfMissing(tree, options);
|
11
|
+
// For Angular inference plugin, we only want it during import since our
|
12
|
+
// generators do not use `angular.json`, and `nx init` should split
|
13
|
+
// `angular.json` into multiple `project.json` files -- as this is preferred
|
14
|
+
// by most folks we've talked to.
|
15
|
+
options.addPlugin ??= process.env.NX_RUNNING_NX_IMPORT === 'true';
|
16
|
+
if (options.addPlugin) {
|
17
|
+
await (0, add_plugin_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/angular/plugin', plugin_1.createNodesV2, {
|
18
|
+
targetNamePrefix: ['', 'angular:', 'angular-'],
|
19
|
+
}, options.updatePackageScripts);
|
20
|
+
}
|
9
21
|
if (!options.skipFormat) {
|
10
22
|
await (0, devkit_1.formatFiles)(tree);
|
11
23
|
}
|
@@ -6,12 +6,14 @@ function addMfEnvToTargetDefaultInputs(tree) {
|
|
6
6
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
7
7
|
const webpackExecutor = '@nx/angular:webpack-browser';
|
8
8
|
const mfEnvVar = 'NX_MF_DEV_REMOTES';
|
9
|
+
const inputs = [
|
10
|
+
...(nxJson.namedInputs && 'production' in nxJson.namedInputs
|
11
|
+
? ['production', '^production']
|
12
|
+
: ['default', '^default']),
|
13
|
+
];
|
9
14
|
nxJson.targetDefaults ??= {};
|
10
15
|
nxJson.targetDefaults[webpackExecutor] ??= {};
|
11
|
-
nxJson.targetDefaults[webpackExecutor].inputs ??=
|
12
|
-
'production',
|
13
|
-
'^production',
|
14
|
-
];
|
16
|
+
nxJson.targetDefaults[webpackExecutor].inputs ??= inputs;
|
15
17
|
nxJson.targetDefaults[webpackExecutor].dependsOn ??= ['^build'];
|
16
18
|
let mfEnvVarExists = false;
|
17
19
|
for (const input of nxJson.targetDefaults[webpackExecutor].inputs) {
|
@@ -20,12 +20,18 @@ async function default_1(tree) {
|
|
20
20
|
}
|
21
21
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
22
22
|
const nxMFDevRemotesEnvVar = 'NX_MF_DEV_REMOTES';
|
23
|
+
const inputs = [
|
24
|
+
...(nxJson.namedInputs && 'production' in nxJson.namedInputs
|
25
|
+
? ['production', '^production']
|
26
|
+
: ['default', '^default']),
|
27
|
+
{ env: nxMFDevRemotesEnvVar },
|
28
|
+
];
|
23
29
|
if (!nxJson.targetDefaults ||
|
24
30
|
!nxJson.targetDefaults?.['@nx/angular:webpack-browser']) {
|
25
31
|
nxJson.targetDefaults ??= {};
|
26
32
|
nxJson.targetDefaults['@nx/angular:webpack-browser'] = {
|
27
33
|
cache: true,
|
28
|
-
inputs
|
34
|
+
inputs,
|
29
35
|
dependsOn: ['^build'],
|
30
36
|
};
|
31
37
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
import { type CreateNodesV2 } from '@nx/devkit';
|
2
|
+
export interface AngularPluginOptions {
|
3
|
+
targetNamePrefix?: string;
|
4
|
+
}
|
5
|
+
type AngularTargetConfiguration = {
|
6
|
+
builder: string;
|
7
|
+
options?: Record<string, any>;
|
8
|
+
configurations?: Record<string, any>;
|
9
|
+
defaultConfiguration?: string;
|
10
|
+
};
|
11
|
+
export type AngularProjectConfiguration = {
|
12
|
+
projectType: 'application' | 'library';
|
13
|
+
root: string;
|
14
|
+
sourceRoot?: string;
|
15
|
+
architect?: Record<string, AngularTargetConfiguration>;
|
16
|
+
targets?: Record<string, AngularTargetConfiguration>;
|
17
|
+
};
|
18
|
+
export declare const createNodesV2: CreateNodesV2<AngularPluginOptions>;
|
19
|
+
export {};
|
@@ -0,0 +1,418 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.createNodesV2 = void 0;
|
4
|
+
const tslib_1 = require("tslib");
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
6
|
+
const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
|
7
|
+
const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
|
8
|
+
const js_1 = require("@nx/js");
|
9
|
+
const node_fs_1 = require("node:fs");
|
10
|
+
const node_path_1 = require("node:path");
|
11
|
+
const posix = tslib_1.__importStar(require("node:path/posix"));
|
12
|
+
const devkit_internals_1 = require("nx/src/devkit-internals");
|
13
|
+
const cache_directory_1 = require("nx/src/utils/cache-directory");
|
14
|
+
const knownExecutors = {
|
15
|
+
appShell: new Set(['@angular-devkit/build-angular:app-shell']),
|
16
|
+
build: new Set([
|
17
|
+
'@angular-devkit/build-angular:application',
|
18
|
+
'@angular/build:application',
|
19
|
+
'@angular-devkit/build-angular:browser-esbuild',
|
20
|
+
'@angular-devkit/build-angular:browser',
|
21
|
+
'@angular-devkit/build-angular:ng-packagr',
|
22
|
+
]),
|
23
|
+
devServer: new Set(['@angular-devkit/build-angular:dev-server']),
|
24
|
+
extractI18n: new Set(['@angular-devkit/build-angular:extract-i18n']),
|
25
|
+
prerender: new Set([
|
26
|
+
'@angular-devkit/build-angular:prerender',
|
27
|
+
'@nguniversal/builders:prerender',
|
28
|
+
]),
|
29
|
+
server: new Set(['@angular-devkit/build-angular:server']),
|
30
|
+
serveSsr: new Set([
|
31
|
+
'@angular-devkit/build-angular:ssr-dev-server',
|
32
|
+
'@nguniversal/builders:ssr-dev-server',
|
33
|
+
]),
|
34
|
+
test: new Set(['@angular-devkit/build-angular:karma']),
|
35
|
+
};
|
36
|
+
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
37
|
+
function readProjectsCache(cachePath) {
|
38
|
+
return (0, node_fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
|
39
|
+
}
|
40
|
+
function writeProjectsToCache(cachePath, results) {
|
41
|
+
(0, devkit_1.writeJsonFile)(cachePath, results);
|
42
|
+
}
|
43
|
+
exports.createNodesV2 = [
|
44
|
+
'**/angular.json',
|
45
|
+
async (configFiles, options, context) => {
|
46
|
+
const optionsHash = (0, devkit_internals_1.hashObject)(options);
|
47
|
+
const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `angular-${optionsHash}.hash`);
|
48
|
+
const projectsCache = readProjectsCache(cachePath);
|
49
|
+
try {
|
50
|
+
return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, projectsCache), configFiles, options, context);
|
51
|
+
}
|
52
|
+
finally {
|
53
|
+
writeProjectsToCache(cachePath, projectsCache);
|
54
|
+
}
|
55
|
+
},
|
56
|
+
];
|
57
|
+
async function createNodesInternal(configFilePath, options, context, projectsCache) {
|
58
|
+
const angularWorkspaceRoot = (0, node_path_1.dirname)(configFilePath);
|
59
|
+
// Do not create a project if package.json isn't there
|
60
|
+
const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot));
|
61
|
+
if (!siblingFiles.includes('package.json')) {
|
62
|
+
return {};
|
63
|
+
}
|
64
|
+
const hash = await (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(angularWorkspaceRoot, options, context, [(0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot))]);
|
65
|
+
projectsCache[hash] ??= await buildAngularProjects(configFilePath, options, angularWorkspaceRoot, context);
|
66
|
+
return { projects: projectsCache[hash] };
|
67
|
+
}
|
68
|
+
async function buildAngularProjects(configFilePath, options, angularWorkspaceRoot, context) {
|
69
|
+
const projects = {};
|
70
|
+
const absoluteConfigFilePath = (0, node_path_1.join)(context.workspaceRoot, configFilePath);
|
71
|
+
const angularJson = (0, devkit_1.readJsonFile)(absoluteConfigFilePath);
|
72
|
+
const appShellTargets = [];
|
73
|
+
const prerenderTargets = [];
|
74
|
+
for (const [projectName, project] of Object.entries(angularJson.projects ?? {})) {
|
75
|
+
const targets = {};
|
76
|
+
const projectTargets = getAngularJsonProjectTargets(project);
|
77
|
+
if (!projectTargets) {
|
78
|
+
continue;
|
79
|
+
}
|
80
|
+
const namedInputs = (0, get_named_inputs_1.getNamedInputs)(project.root, context);
|
81
|
+
for (const [angularTargetName, angularTarget] of Object.entries(projectTargets)) {
|
82
|
+
const nxTargetName = options?.targetNamePrefix
|
83
|
+
? `${options.targetNamePrefix}${angularTargetName}`
|
84
|
+
: angularTargetName;
|
85
|
+
const externalDependencies = ['@angular/cli'];
|
86
|
+
targets[nxTargetName] = {
|
87
|
+
command:
|
88
|
+
// For targets that are also Angular CLI commands, infer the simplified form.
|
89
|
+
// Otherwise, use `ng run` to support non-command targets so that they will run.
|
90
|
+
angularTargetName === 'build' ||
|
91
|
+
angularTargetName === 'deploy' ||
|
92
|
+
angularTargetName === 'extract-i18n' ||
|
93
|
+
angularTargetName === 'e2e' ||
|
94
|
+
angularTargetName === 'lint' ||
|
95
|
+
angularTargetName === 'serve' ||
|
96
|
+
angularTargetName === 'test'
|
97
|
+
? `ng ${angularTargetName}`
|
98
|
+
: `ng run ${projectName}:${angularTargetName}`,
|
99
|
+
options: { cwd: angularWorkspaceRoot },
|
100
|
+
metadata: {
|
101
|
+
technologies: ['angular'],
|
102
|
+
description: `Run the "${angularTargetName}" target for "${projectName}".`,
|
103
|
+
help: {
|
104
|
+
command: `${pmc.exec} ng run ${projectName}:${angularTargetName} --help`,
|
105
|
+
example: {},
|
106
|
+
},
|
107
|
+
},
|
108
|
+
};
|
109
|
+
if (knownExecutors.appShell.has(angularTarget.builder)) {
|
110
|
+
appShellTargets.push({ target: nxTargetName, project: projectName });
|
111
|
+
}
|
112
|
+
else if (knownExecutors.build.has(angularTarget.builder)) {
|
113
|
+
await updateBuildTarget(nxTargetName, targets[nxTargetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs);
|
114
|
+
}
|
115
|
+
else if (knownExecutors.devServer.has(angularTarget.builder)) {
|
116
|
+
targets[nxTargetName].metadata.help.example.options = { port: 4201 };
|
117
|
+
}
|
118
|
+
else if (knownExecutors.extractI18n.has(angularTarget.builder)) {
|
119
|
+
targets[nxTargetName].metadata.help.example.options = {
|
120
|
+
format: 'json',
|
121
|
+
};
|
122
|
+
}
|
123
|
+
else if (knownExecutors.test.has(angularTarget.builder)) {
|
124
|
+
updateTestTarget(targets[nxTargetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs, externalDependencies);
|
125
|
+
}
|
126
|
+
else if (knownExecutors.server.has(angularTarget.builder)) {
|
127
|
+
updateServerTarget(targets[nxTargetName], angularTarget, context, angularWorkspaceRoot, project.root, namedInputs);
|
128
|
+
}
|
129
|
+
else if (knownExecutors.serveSsr.has(angularTarget.builder)) {
|
130
|
+
targets[nxTargetName].metadata.help.example.options = { port: 4201 };
|
131
|
+
}
|
132
|
+
else if (knownExecutors.prerender.has(angularTarget.builder)) {
|
133
|
+
prerenderTargets.push({ target: nxTargetName, project: projectName });
|
134
|
+
}
|
135
|
+
if (targets[nxTargetName].inputs?.length) {
|
136
|
+
targets[nxTargetName].inputs.push({ externalDependencies });
|
137
|
+
}
|
138
|
+
if (angularTarget.configurations) {
|
139
|
+
for (const configurationName of Object.keys(angularTarget.configurations)) {
|
140
|
+
targets[nxTargetName].configurations = {
|
141
|
+
...targets[nxTargetName].configurations,
|
142
|
+
[configurationName]: {
|
143
|
+
command: `ng run ${projectName}:${angularTargetName}:${configurationName}`,
|
144
|
+
},
|
145
|
+
};
|
146
|
+
}
|
147
|
+
}
|
148
|
+
if (angularTarget.defaultConfiguration) {
|
149
|
+
targets[nxTargetName].defaultConfiguration =
|
150
|
+
angularTarget.defaultConfiguration;
|
151
|
+
}
|
152
|
+
}
|
153
|
+
projects[projectName] = {
|
154
|
+
projectType: project.projectType,
|
155
|
+
root: posix.join(angularWorkspaceRoot, project.root),
|
156
|
+
sourceRoot: project.sourceRoot
|
157
|
+
? posix.join(angularWorkspaceRoot, project.sourceRoot)
|
158
|
+
: undefined,
|
159
|
+
targets,
|
160
|
+
};
|
161
|
+
}
|
162
|
+
for (const { project, target } of appShellTargets) {
|
163
|
+
updateAppShellTarget(project, target, projects, angularJson, angularWorkspaceRoot, context);
|
164
|
+
}
|
165
|
+
for (const { project, target } of prerenderTargets) {
|
166
|
+
updatePrerenderTarget(project, target, projects, angularJson);
|
167
|
+
}
|
168
|
+
return Object.entries(projects).reduce((acc, [projectName, project]) => {
|
169
|
+
acc[project.root] = {
|
170
|
+
projectType: project.projectType,
|
171
|
+
sourceRoot: project.sourceRoot,
|
172
|
+
targets: project.targets,
|
173
|
+
};
|
174
|
+
return acc;
|
175
|
+
}, {});
|
176
|
+
}
|
177
|
+
function updateAppShellTarget(projectName, targetName, projects, angularJson, angularWorkspaceRoot, context) {
|
178
|
+
// it must exist since we collected it when processing it
|
179
|
+
const target = projects[projectName].targets[targetName];
|
180
|
+
target.metadata.help.example.options = { route: '/some/route' };
|
181
|
+
const { inputs, outputs } = getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson);
|
182
|
+
const outputIndexPath = getAngularJsonProjectTargets(angularJson.projects[projectName])[targetName].options?.outputIndexPath;
|
183
|
+
if (outputIndexPath) {
|
184
|
+
const fullOutputIndexPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, outputIndexPath);
|
185
|
+
outputs.push(getOutput(fullOutputIndexPath, context.workspaceRoot, angularWorkspaceRoot, angularJson.projects[projectName].root));
|
186
|
+
}
|
187
|
+
if (!outputs.length) {
|
188
|
+
// no outputs were identified for the build or server target, so we don't
|
189
|
+
// set any Nx cache options
|
190
|
+
return;
|
191
|
+
}
|
192
|
+
target.cache = true;
|
193
|
+
target.inputs = inputs;
|
194
|
+
target.outputs = outputs;
|
195
|
+
}
|
196
|
+
async function updateBuildTarget(targetName, target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs) {
|
197
|
+
target.dependsOn = [`^${targetName}`];
|
198
|
+
if (angularTarget.options?.outputPath) {
|
199
|
+
const fullOutputPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, angularTarget.options.outputPath);
|
200
|
+
target.outputs = [
|
201
|
+
getOutput(fullOutputPath, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
|
202
|
+
];
|
203
|
+
}
|
204
|
+
else if (angularTarget.builder === '@angular-devkit/build-angular:ng-packagr') {
|
205
|
+
const outputs = await getNgPackagrOutputs(angularTarget, angularWorkspaceRoot, projectRoot, context);
|
206
|
+
if (outputs.length) {
|
207
|
+
target.outputs = outputs;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
if (target.outputs?.length) {
|
211
|
+
// make it cacheable if we were able to identify outputs
|
212
|
+
target.cache = true;
|
213
|
+
target.inputs =
|
214
|
+
'production' in namedInputs
|
215
|
+
? ['production', '^production']
|
216
|
+
: ['default', '^default'];
|
217
|
+
}
|
218
|
+
if (angularTarget.builder === '@angular-devkit/build-angular:ng-packagr') {
|
219
|
+
target.metadata.help.example.options = { watch: true };
|
220
|
+
}
|
221
|
+
else {
|
222
|
+
target.metadata.help.example.options = { localize: true };
|
223
|
+
}
|
224
|
+
}
|
225
|
+
function updateTestTarget(target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs, externalDependencies) {
|
226
|
+
target.cache = true;
|
227
|
+
target.inputs =
|
228
|
+
'production' in namedInputs
|
229
|
+
? ['default', '^production']
|
230
|
+
: ['default', '^default'];
|
231
|
+
target.outputs = getKarmaTargetOutputs(angularTarget, angularWorkspaceRoot, projectRoot, context);
|
232
|
+
externalDependencies.push('karma');
|
233
|
+
target.metadata.help.example.options = { codeCoverage: true };
|
234
|
+
}
|
235
|
+
function updateServerTarget(target, angularTarget, context, angularWorkspaceRoot, projectRoot, namedInputs) {
|
236
|
+
target.metadata.help.example.options = { localize: true };
|
237
|
+
if (!angularTarget.options?.outputPath) {
|
238
|
+
// only make it cacheable if we were able to identify outputs
|
239
|
+
return;
|
240
|
+
}
|
241
|
+
target.cache = true;
|
242
|
+
target.inputs =
|
243
|
+
'production' in namedInputs
|
244
|
+
? ['production', '^production']
|
245
|
+
: ['default', '^default'];
|
246
|
+
const fullOutputPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, angularTarget.options.outputPath);
|
247
|
+
target.outputs = [
|
248
|
+
getOutput(fullOutputPath, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
|
249
|
+
];
|
250
|
+
}
|
251
|
+
function updatePrerenderTarget(projectName, targetName, projects, angularJson) {
|
252
|
+
// it must exist since we collected it when processing it
|
253
|
+
const target = projects[projectName].targets[targetName];
|
254
|
+
target.metadata.help.example.options =
|
255
|
+
getAngularJsonProjectTargets(angularJson.projects[projectName])[targetName]
|
256
|
+
.builder === '@angular-devkit/build-angular:prerender'
|
257
|
+
? { discoverRoutes: false }
|
258
|
+
: { guessRoutes: false };
|
259
|
+
const { inputs, outputs } = getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson);
|
260
|
+
if (!outputs.length) {
|
261
|
+
// no outputs were identified for the build or server target, so we don't
|
262
|
+
// set any Nx cache options
|
263
|
+
return;
|
264
|
+
}
|
265
|
+
target.cache = true;
|
266
|
+
target.inputs = inputs;
|
267
|
+
target.outputs = outputs;
|
268
|
+
}
|
269
|
+
async function getNgPackagrOutputs(target, angularWorkspaceRoot, projectRoot, context) {
|
270
|
+
let ngPackageJsonPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, target.options.project);
|
271
|
+
const readConfig = async (configPath) => {
|
272
|
+
if (!(0, node_fs_1.existsSync)(configPath)) {
|
273
|
+
return undefined;
|
274
|
+
}
|
275
|
+
try {
|
276
|
+
if (configPath.endsWith('.js')) {
|
277
|
+
const result = await import(configPath);
|
278
|
+
return result['default'] ?? result;
|
279
|
+
}
|
280
|
+
return (0, devkit_1.readJsonFile)(configPath);
|
281
|
+
}
|
282
|
+
catch { }
|
283
|
+
return undefined;
|
284
|
+
};
|
285
|
+
let ngPackageJson;
|
286
|
+
let basePath;
|
287
|
+
if ((0, node_fs_1.statSync)(ngPackageJsonPath).isDirectory()) {
|
288
|
+
basePath = ngPackageJsonPath;
|
289
|
+
ngPackageJson = await readConfig((0, node_path_1.join)(ngPackageJsonPath, 'ng-package.json'));
|
290
|
+
if (!ngPackageJson) {
|
291
|
+
ngPackageJson = await readConfig((0, node_path_1.join)(ngPackageJsonPath, 'ng-package.js'));
|
292
|
+
}
|
293
|
+
}
|
294
|
+
else {
|
295
|
+
basePath = (0, node_path_1.dirname)(ngPackageJsonPath);
|
296
|
+
ngPackageJson = await readConfig(ngPackageJsonPath);
|
297
|
+
}
|
298
|
+
if (!ngPackageJson) {
|
299
|
+
return [];
|
300
|
+
}
|
301
|
+
const destination = ngPackageJson.dest
|
302
|
+
? (0, node_path_1.join)(basePath, ngPackageJson.dest)
|
303
|
+
: (0, node_path_1.join)(basePath, 'dist');
|
304
|
+
return [
|
305
|
+
getOutput(destination, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
|
306
|
+
];
|
307
|
+
}
|
308
|
+
function getKarmaTargetOutputs(target, angularWorkspaceRoot, projectRoot, context) {
|
309
|
+
const defaultOutput = posix.join('{workspaceRoot}', angularWorkspaceRoot, 'coverage/{projectName}');
|
310
|
+
if (!target.options?.karmaConfig) {
|
311
|
+
return [defaultOutput];
|
312
|
+
}
|
313
|
+
try {
|
314
|
+
const { parseConfig } = require('karma/lib/config');
|
315
|
+
const karmaConfigPath = (0, node_path_1.join)(context.workspaceRoot, angularWorkspaceRoot, projectRoot, target.options.karmaConfig);
|
316
|
+
const config = parseConfig(karmaConfigPath);
|
317
|
+
if (config.coverageReporter.dir) {
|
318
|
+
return [
|
319
|
+
getOutput(config.coverageReporter.dir, context.workspaceRoot, angularWorkspaceRoot, projectRoot),
|
320
|
+
];
|
321
|
+
}
|
322
|
+
}
|
323
|
+
catch {
|
324
|
+
// we silently ignore any error here and fall back to the default output
|
325
|
+
}
|
326
|
+
return [defaultOutput];
|
327
|
+
}
|
328
|
+
function getBrowserAndServerTargetInputsAndOutputs(projectName, targetName, projects, angularJson) {
|
329
|
+
const { browserTarget, serverTarget } = extractBrowserAndServerTargets(angularJson, projectName, targetName);
|
330
|
+
if (!browserTarget || !serverTarget) {
|
331
|
+
// if any of these are missing, the target is invalid so we return empty values
|
332
|
+
return { inputs: [], outputs: [] };
|
333
|
+
}
|
334
|
+
const browserTargetInputs = projects[browserTarget.project]?.targets?.[browserTarget.target]?.inputs ??
|
335
|
+
[];
|
336
|
+
const serverTargetInputs = projects[serverTarget.project]?.targets?.[serverTarget.target]?.inputs ??
|
337
|
+
[];
|
338
|
+
const browserTargetOutputs = projects[browserTarget.project]?.targets?.[browserTarget.target]?.outputs ??
|
339
|
+
[];
|
340
|
+
const serverTargetOutputs = projects[serverTarget.project]?.targets?.[serverTarget.target]?.outputs ??
|
341
|
+
[];
|
342
|
+
return {
|
343
|
+
inputs: mergeInputs(...browserTargetInputs, ...serverTargetInputs),
|
344
|
+
outputs: Array.from(new Set([...browserTargetOutputs, ...serverTargetOutputs])),
|
345
|
+
};
|
346
|
+
}
|
347
|
+
function extractBrowserAndServerTargets(angularJson, projectName, targetName) {
|
348
|
+
let browserTarget;
|
349
|
+
let serverTarget;
|
350
|
+
try {
|
351
|
+
const targets = getAngularJsonProjectTargets(angularJson.projects[projectName]);
|
352
|
+
const target = targets[targetName];
|
353
|
+
let browserTargetSpecifier = target.options?.browserTarget;
|
354
|
+
if (!browserTargetSpecifier) {
|
355
|
+
const configuration = Object.values(target.configurations ?? {}).find((config) => !!config.browserTarget);
|
356
|
+
browserTargetSpecifier = configuration?.browserTarget;
|
357
|
+
}
|
358
|
+
if (browserTargetSpecifier) {
|
359
|
+
browserTarget = targetFromTargetString(browserTargetSpecifier, projectName, targetName);
|
360
|
+
}
|
361
|
+
let serverTargetSpecifier = target.options?.serverTarget;
|
362
|
+
if (!serverTargetSpecifier) {
|
363
|
+
serverTargetSpecifier = Object.values(target.configurations ?? {}).find((config) => !!config.serverTarget)?.serverTarget;
|
364
|
+
}
|
365
|
+
if (serverTargetSpecifier) {
|
366
|
+
serverTarget = targetFromTargetString(serverTargetSpecifier, projectName, targetName);
|
367
|
+
}
|
368
|
+
}
|
369
|
+
catch { }
|
370
|
+
return { browserTarget: browserTarget, serverTarget };
|
371
|
+
}
|
372
|
+
function mergeInputs(...inputs) {
|
373
|
+
const stringInputs = new Set();
|
374
|
+
const externalDependencies = new Set();
|
375
|
+
for (const input of inputs) {
|
376
|
+
if (typeof input === 'string') {
|
377
|
+
stringInputs.add(input);
|
378
|
+
}
|
379
|
+
else if ('externalDependencies' in input) {
|
380
|
+
// we only infer external dependencies, so we don't need to handle the other input definitions
|
381
|
+
for (const externalDependency of input.externalDependencies) {
|
382
|
+
externalDependencies.add(externalDependency);
|
383
|
+
}
|
384
|
+
}
|
385
|
+
}
|
386
|
+
return [
|
387
|
+
...stringInputs,
|
388
|
+
...(externalDependencies.size
|
389
|
+
? [{ externalDependencies: Array.from(externalDependencies) }]
|
390
|
+
: []),
|
391
|
+
];
|
392
|
+
}
|
393
|
+
// angular support abbreviated target specifiers, this is adapter from:
|
394
|
+
// https://github.com/angular/angular-cli/blob/7d9ce246a33c60ec96eb4bf99520f5475716a910/packages/angular_devkit/architect/src/api.ts#L336
|
395
|
+
function targetFromTargetString(specifier, abbreviatedProjectName, abbreviatedTargetName) {
|
396
|
+
const tuple = specifier.split(':', 3);
|
397
|
+
if (tuple.length < 2) {
|
398
|
+
// invalid target, ignore
|
399
|
+
return undefined;
|
400
|
+
}
|
401
|
+
// we only care about project and target
|
402
|
+
return {
|
403
|
+
project: tuple[0] || abbreviatedProjectName || '',
|
404
|
+
target: tuple[1] || abbreviatedTargetName || '',
|
405
|
+
};
|
406
|
+
}
|
407
|
+
function getOutput(path, workspaceRoot, angularWorkspaceRoot, projectRoot) {
|
408
|
+
const relativePath = (0, node_path_1.relative)((0, node_path_1.join)(workspaceRoot, angularWorkspaceRoot, projectRoot), path);
|
409
|
+
if (relativePath.startsWith('..')) {
|
410
|
+
return posix.join('{workspaceRoot}', (0, node_path_1.join)(angularWorkspaceRoot, projectRoot, relativePath));
|
411
|
+
}
|
412
|
+
else {
|
413
|
+
return posix.join('{projectRoot}', relativePath);
|
414
|
+
}
|
415
|
+
}
|
416
|
+
function getAngularJsonProjectTargets(project) {
|
417
|
+
return project.architect ?? project.targets;
|
418
|
+
}
|