Skip to content

[TBD] feat(nf): Use es-module-shims during initFederation and loadRemoteModule to ensure having latest importMap #513

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
faf5f94
fix(nf): properly handle outputPath object
wszydlak Feb 1, 2024
d36e63c
Write actual contents, not text representation
FlorianRappl Feb 27, 2024
2c687f1
fix(nf): Inject `importmap-shim` to the `<head>` instead of the end o…
jogelin Mar 11, 2024
40849a5
feat(nf): Add `esmsInitOptions` to Angular builder to inject addition…
jogelin Mar 11, 2024
7a4b3af
fix(nf): Remove orphans `</scripts>` tags after `updateScriptTags`
jogelin Mar 11, 2024
7edb1f1
Merge pull request #498 from jogelin/add-builder-esms-init-options
manfredsteyer Mar 11, 2024
9897a1f
Merge pull request #499 from jogelin/inject-importmap-to-head
manfredsteyer Mar 11, 2024
3ee67ba
Merge pull request #500 from jogelin/fix-orphan-close-script-tags
manfredsteyer Mar 11, 2024
3410927
Merge pull request #481 from FlorianRappl/patch-1
manfredsteyer Mar 11, 2024
775db9d
Merge pull request #455 from wszydlak/patch-2
manfredsteyer Mar 11, 2024
4eaa04e
fix(dep): fix peer dependency `browser-sync` not aligned with root de…
jogelin Mar 12, 2024
f95cee8
fix(test): fix jest tests
jogelin Mar 12, 2024
de0b92f
fix(lint): fix linting
jogelin Mar 12, 2024
bbaf18c
ci: init Github actions config file
jogelin Mar 12, 2024
d6998ba
Merge pull request #503 from jogelin/fix-npm-install-peer-dep-conflict
manfredsteyer Mar 12, 2024
041d478
Merge pull request #504 from jogelin/fix-tests
manfredsteyer Mar 12, 2024
8fc5f7e
Merge pull request #505 from jogelin/fix-linting
manfredsteyer Mar 12, 2024
1c88a77
Merge pull request #506 from jogelin/init-github-action-config
manfredsteyer Mar 12, 2024
b74451f
feat(nf): Use es-module-shims during initFederation and loadRemoteMod…
jogelin Mar 13, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"],
"rules": {
"@typescript-eslint/no-explicit-any": "warn",
"@nx/enforce-module-boundaries": [
"error",
{
Expand All @@ -24,7 +25,7 @@
{
"files": ["*.ts", "*.tsx"],
"extends": ["plugin:@nx/typescript"],
"rules": {}
"rules": { "@typescript-eslint/no-explicit-any": "warn" }
},
{
"files": ["*.js", "*.jsx"],
Expand Down
30 changes: 30 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: CI

on:
push:
branches:
- main
pull_request:

permissions:
actions: read
contents: read

jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-node@v3
with:
node-version: 20
cache: 'npm'
- run: npm ci
- uses: nrwl/nx-set-shas@v3
# This line is needed for nx affected to work when CI is running on a PR
- run: git branch --track main origin/main

- run: npx nx format:check
- run: npx nx affected -t lint,test,build
4 changes: 1 addition & 3 deletions apps/mfe1/src/app/demo/demo.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ describe('DemoComponent', () => {
let fixture: ComponentFixture<DemoComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [DemoComponent],
}).compileComponents();
await TestBed.configureTestingModule({}).compileComponents();

fixture = TestBed.createComponent(DemoComponent);
component = fixture.componentInstance;
Expand Down
2 changes: 1 addition & 1 deletion apps/mfe1/src/app/demo/demo.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
PlaygroundLibModule,
} from '@angular-architects/playground-lib';
import { CommonModule } from '@angular/common';
import { Component, OnInit } from '@angular/core';
import { Component } from '@angular/core';

@Component({
standalone: true,
Expand Down
2 changes: 1 addition & 1 deletion apps/mfe2/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { initFederation } from '@angular-architects/native-federation';

initFederation('/assets/federation.manifest.json')
.catch((err) => console.error(err))
.then((_) => import('./bootstrap'))
.then(() => import('./bootstrap'))
.catch((err) => console.error(err));
2 changes: 1 addition & 1 deletion apps/playground-e2e/src/integration/app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ describe('playground', () => {
cy.login('[email protected]', 'myPassword');

// Function helper example, see `../support/app.po.ts` file
getGreeting().contains('Welcome to playground!');
getGreeting().contains('Hello Native Federation!');
});
});
2 changes: 1 addition & 1 deletion apps/playground/src/app/app.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ describe('AppComponent', () => {
fixture.detectChanges();
const compiled = fixture.nativeElement;
expect(compiled.querySelector('h1').textContent).toContain(
'Welcome to playground!'
'Hello Native Federation!'
);
});
});
4 changes: 4 additions & 0 deletions jest.preset.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ module.exports = {
* More info: https://jestjs.io/docs/upgrading-to-jest29#snapshot-format
*/
snapshotFormat: { escapeString: true, printBasicPrototype: true },
// because of https://github.com/jestjs/jest/issues/4422
globals: {
Uint8Array: Uint8Array,
},
};
42 changes: 0 additions & 42 deletions libs/mf/src/builders/build/builder.spec.ts

This file was deleted.

12 changes: 7 additions & 5 deletions libs/mf/src/schematics/mf/schematic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export function add(options: MfSchematicSchema): Rule {
}

export function adjustSSR(sourceRoot: string, ssrMappings: string): Rule {
return async function (tree, context) {
return async function (tree) {
const server = path.join(sourceRoot, 'server.ts');

if (!tree.exists(server)) {
Expand Down Expand Up @@ -70,7 +70,7 @@ const ssrEngine = new Engine();
}

function makeMainAsync(main: string, options: MfSchematicSchema): Rule {
return async function (tree, context) {
return async function (tree) {
const mainPath = path.dirname(main);
const bootstrapName = path.join(mainPath, 'bootstrap.ts');

Expand Down Expand Up @@ -149,7 +149,10 @@ function nxBuildersAvailable(tree: Tree): boolean {
function infereNxBuilderNames(tree: Tree): { dev: string; prod: string } {
const dep = getPackageJsonDependency(tree, '@nx/angular');

const useDevServer = dep && dep.version && semver.satisfies(semver.minVersion(dep.version), '>=17.2.0');
const useDevServer =
dep &&
dep.version &&
semver.satisfies(semver.minVersion(dep.version), '>=17.2.0');

const defaultResult = {
dev: useDevServer
Expand Down Expand Up @@ -264,8 +267,7 @@ export default function config(options: MfSchematicSchema): Rule {
projectName,
remotes,
relTsConfigPath,
projectRoot,
port
projectRoot
);
tree.create(configPath, webpackConfig);
} else {
Expand Down
6 changes: 3 additions & 3 deletions libs/mf/src/schematics/migrate-to-13/schematic.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Rule } from '@angular-devkit/schematics';

export function index(): Rule {
return async function (tree, context) {
return async function () {
console.info(`!!!
Angular 13 compiles bundles as EcmaScript modules.
Hence, we need to adjust how we use Module Federation.
Angular 13 compiles bundles as EcmaScript modules.
Hence, we need to adjust how we use Module Federation.
We've got you covered. Please find all information here:
https://github.com/angular-architects/module-federation-plugin/blob/main/migration-guide.md
!!!
Expand Down
2 changes: 1 addition & 1 deletion libs/mf/src/schematics/migrate-to-14-3/schema.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
type BootAsyncSchema = {};
type BootAsyncSchema = object;
17 changes: 8 additions & 9 deletions libs/mf/src/utils/create-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ export function createConfig(
projectName: string,
remotes: string,
tsConfigName: string,
root: string,
port: number
root: string
): string {
return `const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
const mf = require("@angular-architects/module-federation/webpack");
Expand All @@ -24,7 +23,7 @@ module.exports = {
},
optimization: {
runtimeChunk: false
},
},
resolve: {
alias: {
...sharedMappings.getAliases(),
Expand All @@ -42,22 +41,22 @@ module.exports = {
// filename: "remoteEntry.js",
// exposes: {
// './Component': './${root}/src/app/app.component.ts',
// },
// },

// For hosts (please adjust)
// remotes: {
${remotes}
// },

shared: share({
"@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/core": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/common": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/common/http": { singleton: true, strictVersion: true, requiredVersion: 'auto' },
"@angular/router": { singleton: true, strictVersion: true, requiredVersion: 'auto' },

...sharedMappings.getDescriptors()
})

}),
sharedMappings.getPlugin()
],
Expand Down
5 changes: 4 additions & 1 deletion libs/mf/src/utils/share-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,10 @@ export function share(
return result;
}

function addSecondaries(secondaries: Record<string, SharedConfig>, result: {}) {
function addSecondaries(
secondaries: Record<string, SharedConfig>,
result: object
) {
for (const key in secondaries) {
result[key] = secondaries[key];
}
Expand Down
17 changes: 9 additions & 8 deletions libs/native-federation-core/src/lib/config/share-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,15 @@ function findPackageJson(folder: string): string {
);
}

function readVersionMap(packagePath: string): VersionMap {
// eslint-disable-next-line @typescript-eslint/no-var-requires
const json = require(packagePath);
const versions = {
...json['dependencies'],
};
return versions;
}
// TODO: Unused, to delete?
// function readVersionMap(packagePath: string): VersionMap {
// // eslint-disable-next-line @typescript-eslint/no-var-requires
// const json = require(packagePath);
// const versions = {
// ...json['dependencies'],
// };
// return versions;
// }

function lookupVersion(key: string, workspaceRoot: string): string {
const versionMaps = getVersionMaps(workspaceRoot, workspaceRoot);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { getMappedPaths, MappedPath } from '../utils/mapped-paths';
import { shareAll, share, findRootTsConfigJson } from './share-utils';
import { shareAll, findRootTsConfigJson } from './share-utils';
import {
FederationConfig,
NormalizedFederationConfig,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ export async function buildForFederation(
};

writeFederationInfo(federationInfo, fedOptions);
writeImportMap(sharedInfo, fedOptions);
writeImportMap(federationInfo, fedOptions);

return federationInfo;
}
17 changes: 12 additions & 5 deletions libs/native-federation-core/src/lib/core/write-import-map.ts
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not process host during initFederation

During the build, an importmap.json is already generated.
I just adapted the code to apply the same modifications done by the deleted processHostInfo

Original file line number Diff line number Diff line change
@@ -1,20 +1,27 @@
import * as path from 'path';
import * as fs from 'fs';
import { SharedInfo } from '@softarc/native-federation-runtime';
import { FederationInfo } from '@softarc/native-federation-runtime';
import { FederationOptions } from './federation-options';

export function writeImportMap(
sharedInfo: SharedInfo[],
{ name, shared, exposes }: FederationInfo,
fedOption: FederationOptions
) {
const imports = sharedInfo.reduce((acc, cur) => {
const sharedImports = shared.reduce((acc, cur) => {
return {
...acc,
[cur.packageName]: cur.outFileName,
[cur.packageName]: `./${cur.outFileName}`,
};
}, {});

const importMap = { imports };
const exposesImports = exposes.reduce((acc, cur) => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not process host during initFederation

Add the exposes when the remotes are loaded independently

return {
...acc,
[`${name}/${cur.key}`]: `./${cur.outFileName}`,
};
}, {});

const importMap = { imports: { ...sharedImports, ...exposesImports } };
const importMapPath = path.join(
fedOption.workspaceRoot,
fedOption.outputPath,
Expand Down
40 changes: 20 additions & 20 deletions libs/native-federation-esbuild/src/lib/adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import * as esbuild from 'esbuild';
import { rollup } from 'rollup';
import resolve from '@rollup/plugin-node-resolve';
import { externals } from 'rollup-plugin-node-externals';
import { collectExports } from './collect-exports';
import * as fs from 'fs';
import path from 'path';

Expand Down Expand Up @@ -104,31 +103,32 @@ function writeResult(
for (const outFile of outputFiles) {
const fileName = path.basename(outFile.path);
const filePath = path.join(outdir, fileName);
fs.writeFileSync(filePath, outFile.text);
fs.writeFileSync(filePath, outFile.contents);
writtenFiles.push(filePath);
}

return writtenFiles;
}

function compensateExports(entryPoint: string, outfile?: string): void {
const inExports = collectExports(entryPoint);
const outExports = outfile ? collectExports(outfile) : inExports;

if (!outExports.hasDefaultExport || outExports.hasFurtherExports) {
return;
}
const defaultName = outExports.defaultExportName;

let exports = '/*Try to compensate missing exports*/\n\n';
for (const exp of inExports.exports) {
exports += `let ${exp}$softarc = ${defaultName}.${exp};\n`;
exports += `export { ${exp}$softarc as ${exp} };\n`;
}

const target = outfile ?? entryPoint;
fs.appendFileSync(target, exports, 'utf-8');
}
// TODO: Unused, to delete?
// function compensateExports(entryPoint: string, outfile?: string): void {
// const inExports = collectExports(entryPoint);
// const outExports = outfile ? collectExports(outfile) : inExports;
//
// if (!outExports.hasDefaultExport || outExports.hasFurtherExports) {
// return;
// }
// const defaultName = outExports.defaultExportName;
//
// let exports = '/*Try to compensate missing exports*/\n\n';
// for (const exp of inExports.exports) {
// exports += `let ${exp}$softarc = ${defaultName}.${exp};\n`;
// exports += `export { ${exp}$softarc as ${exp} };\n`;
// }
//
// const target = outfile ?? entryPoint;
// fs.appendFileSync(target, exports, 'utf-8');
// }

async function prepareNodePackage(
entryPoint: string,
Expand Down
Loading