module-federation / core

Module Federation is a concept that allows developers to share code and resources across multiple JavaScript applications
https://module-federation.io/
MIT License
1.44k stars 215 forks source link

@module-federation/native-federation-typescript - support destination folder, loadRemote typings and other improvements #2606

Closed crutch12 closed 1 month ago

crutch12 commented 3 months ago

Clear and concise description of the problem

Hi @ilteoood 👋

It would be great to have more flexibility in @module-federation/native-federation-typescript plugin

Here are my comments:

NativeFederationTypeScriptRemote

  1. typesFolder: './types/@my-mf-types' (nested) generates empty ./dist/types folder
  2. When using with @module-federation/enhanced/webpack (or @module-federation/manifest), this plugin doesn't change mf-manifest.json file. Example:
    
    // webpack.config.js
    const { ModuleFederationPlugin } = require('@module-federation/enhanced/webpack')
    const { NativeFederationTypeScriptRemote } = require('@module-federation/native-federation-typescript/webpack')

plugins: [ new ModuleFederationPlugin({ ...federationConfig, dts: false, // disable to generate with NativeFederationTypeScriptRemote }), NativeFederationTypeScriptRemote({ moduleFederationConfig: federationConfig, typesFolder: './types/@my-mf-types', }), ],

// generated mf-manifest.json // ... "metaData": { // ... "types": { "path": "", "name": "", "zip": "", "api": "" }, }, // ...


### NativeFederationTypeScriptHost
1. `typesFolder` is also used as link to remote (example: `https://.../${typesFolder}.zip`). So I can't change this parameter at all
(source: https://github.com/module-federation/core/blob/main/packages/native-federation-typescript/src/configurations/hostPlugin.ts#L22)

2. `deleteTypesFolder` deletes `@mf-types/@example/app` before `@mf-types.zip` is successfully downloaded. If server is down - plugin removes your types
(source: https://github.com/module-federation/core/blob/main/packages/native-federation-typescript/src/lib/archiveHandler.ts#L74)

3. HostPlugin doesn't generates `./@mf-types/index.d.ts` with `loadRemote` typings (unlike `@module-federation/dts-plugin`)

4. You can't set `@mf-types.zip` path for every remote separately

### Suggested solution

### NativeFederationTypeScriptRemote
1. Allow nested `typesFolder`
2. Implement integration with `@module-federation/manifest` (maybe using additional props or plugins)

### NativeFederationTypeScriptHost
1. `typesFolder` should be used only as download destination directory path

2. `deleteTypesFolder` shouldn't delete types on error (if server is not available)

3. Implement  `./@mf-types/index.d.ts` generation for `loadRemote` function, just like in `@module-federation/dts-plugin`
(source: https://github.com/module-federation/core/blob/main/packages/dts-plugin/src/core/lib/DTSManager.ts#L290)
(example: https://github.com/module-federation/module-federation-examples/blob/11dcb0d6d28c26733da82e3805d7c2e3c9f4c65d/rspack_hmr/host/%40mf-types/index.d.ts)

4.
Allow additional parameters in `remotes` section. Example:
```js
// plugin config
remotes: [
  {
    entry: 'https://.../remoteEntry.js',
    typesZip: '@my-mf-types.zip' // or 'https://.../@my-mf-types.zip'
    // also add .zip automatically, if value has no `.zip` substring
  }
]

OR/AND

Take @mf-types.zip path from mf-manifest.json (types section`). Example:

// plugin config
remotes: [
  {
    entry: 'https://.../mf-manifest.json',
  }
]
// mf-manifest.json
metaData: {
  types: {
    zip: './@my-mf-types.zip'
  }
}

Alternative

No response

Additional context

No response

Validations

ScriptedAlchemy commented 3 months ago

I still do not understand why not use the built in type system?

crutch12 commented 3 months ago

@ScriptedAlchemy how can I use built in type system with vite?

It supports only rspack/webpack, doesn't it?

So I use vite-plugin-federation + @module-federation/native-federation-typescript

ScriptedAlchemy commented 3 months ago

Once esbuild is merged i will be moving onto vite/rolldown integration. Esbuild we will include type since and pretty much everything else we can support on weaker bundler tech. But yes i understand the issue now

crutch12 commented 3 months ago

Okay, waiting for esbuild implementation (https://github.com/module-federation/core/pull/2473)

But @module-federation/native-federation-typescript is great, could be cool if we could use it as CLI/programmatically

# CLI
$ npx @module-federation/native-federation-typescript generate-host

or/and

// programmatically
import { generateHost } from '@module-federation/native-federation-typescript'

await generateHost({ /* ... */ })

Now, for programming usage, I use esbuild plugin :D

const esbuild = require('esbuild');
const { NativeFederationTypeScriptHost } = require('@module-federation/native-federation-typescript/esbuild');

const generate = () => esbuild.build({
  plugins: [
    NativeFederationTypeScriptHost({
      /* ... */
    }),
  ],
});

module.exports.generate = generate
ilteoood commented 3 months ago

@ScriptedAlchemy I'll wait for your feedback here. If it's something that is worth to be implemented I can do it, but if it will be thrown away shortly maybe it's just better to wait

ilteoood commented 3 months ago

About the requested features, atm the plugin is made to be compatible with the "standard" module federation (e.g. the one embedded with Webpack) so I would avoid inserting the support for the manifest because as Zack said it will be available in the near feature officially. But I can work on make it available without it. I'll wait for Zack's feedback first.

ScriptedAlchemy commented 3 months ago

Im unsure on timeline on supporting esbuild but i know this is the intention once others work, to try and make them work with other implementations as well. If we want at least a mid term solution - it might be updating the plugin.

@ilteoood have you looked at our TS impl in DTS manager? im wondering if we could hook into the internals of it like dts or the broker? I wonder if we are able to use some of the lower parts of the system to share capabilites

github-actions[bot] commented 1 month ago

Stale issue message