core icon indicating copy to clipboard operation
core copied to clipboard

Script to generate types with @module-federation/enhanced

Open ATakaSKY opened this issue 1 year ago • 12 comments

Describe the bug

I've a webpack project with react which has 2 command under scripts, one to build the project with mode production and other one is to start the dev server in development mode:

"start": "webpack-dev-server --mode development",
"build": "webpack --mode production"

Now I am generating remote types with @module-federation/enhanced package. The problem is every time I run either of these two commands, the package always ends up regenerating the types for me. Since I just want types to be generated once before local dev/build, I turned off type generation in that common config by this option dts: { consumeTypes: false }.

To achieve type generation beforehand, I ended up creating a separate webpack config to just fetch the remote types. I have added a script in package json which basically runs this config file: "microfrontend-types:codegen": "webpack --mode none --config webpack.mf.types.js"

webpack.mf.types.js

const path = require("path");
const { ModuleFederationPlugin } = require("@module-federation/enhanced");

// remote to fetch types from
const TYPES_URL = "http://localhost:3001";

const config = {
  entry: {
    testApp: ["react-hot-loader/patch", path.join(__dirname, "dev/index.tsx")],
  },
  module: {
    rules: [
      {
        test: /\.ts(x?)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: "ts-loader",
          },
        ],
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "test",
      filename: "remoteEntry.js",
      remotes: {
        testProj: `testMF@${TYPES_URL}/ui/remoteEntry.js?v=${Date.now()}`,
      },
    }),
  ],
  resolve: {
    extensions: [".tsx", ".ts", ".js"],
  },
};

// To exit process after fetching federation types
config.plugins.push({
  apply: (compiler) => {
    compiler.hooks.done.tap("ModuleFederationPlugin", () => {
      console.log("\x1b[32m", "Federation types fetched. Exiting...");
      process.exit(1);
    });
  },
});

module.exports = config;

If you look at the above config, you'll see I'm also exiting webpack process because if I don't do it, webpack starts complaining about the usage of types in components, reason being types getting regenerated here. Somehow the approach that I'm following doesn't look clean to me.

I expected the type generation thing to be one command which I could run separately irrespective whether I'm running the project or building it. Is there a way to achieve it ? I am thinking something similar to how apollo codegen works

Reproduction

NA

Used Package Manager

npm

System Info

NA

Validations

ATakaSKY avatar May 13 '24 12:05 ATakaSKY

Why do you need types generated beforehand? The build should pull the types ahead of time already, and re-pull them each time to sync it per build update (like hmr)

ScriptedAlchemy avatar May 14 '24 22:05 ScriptedAlchemy

I had to generate it this way because every time types was regenerating, I was getting below error:

Attaching a screenshot for the issue I'm facing:

image

I think the project also tries to compile at the same time types are being refetched and could be the reason why it's not able to comprehend in the usage file.

ATakaSKY avatar May 15 '24 03:05 ATakaSKY

Usually it should wait for type sync before attempting to build. Do you have a repo I can look at?

ScriptedAlchemy avatar May 15 '24 06:05 ScriptedAlchemy

@ScriptedAlchemy I made a reproduction in ts-loader-bug branch

dimohqa avatar Jun 04 '24 13:06 dimohqa

I am also facing a similar issue, but in Next.js. Seems to me that when I run npm run build in my Next.js host app - first it runs its lint stuff, and there it fails on imports from my remotes because the types has not been downloaded yet. Having a hard time figuring out how to solve this cleanly.

ulrichgreen avatar Jun 11 '24 18:06 ulrichgreen

Can you commit the types from dev server @ulrichgreen

ScriptedAlchemy avatar Jun 11 '24 22:06 ScriptedAlchemy

@dimohqa this looks like order of operations issue. Remotes need to be online for their host.

@2heal1 can we expose dts options so that type folder is not deleted on new build? This would partially resolve some issues of ordering as long as build has executed before

ScriptedAlchemy avatar Jun 11 '24 22:06 ScriptedAlchemy

Can you commit the types from dev server @ulrichgreen

I thought about that. I tried npm run dev to fetch the types locally, and verified the @mf-types folder was present afterwards. But build command fails the same way after that.

ulrichgreen avatar Jun 12 '24 06:06 ulrichgreen

Yes i think it should not delete the present types if the current remote type fetch failed , i will fix it in recent days

2heal1 avatar Jun 13 '24 02:06 2heal1

I think that an issue here could be also that it remove and replace types even if the remotes one are the same. In the native-federation-typescript this has been fixed, but while in the enhanced package is still happening.

ilteoood avatar Jun 13 '24 19:06 ilteoood

hey , try to upgrade @module-federation/[email protected] , the issue should be fixed in this version

2heal1 avatar Jun 20 '24 03:06 2heal1

hey @2heal1, thanks for fixing this 🎉. After upgrading to latest, I no longer see the issue of type regeneration on either build or local npm start. But now how do you suggest we generate types if remote changes. Does it make sense to keep the config that I have shared in the initial message in this thread or what's the ideal way to do it?

ATakaSKY avatar Aug 03 '24 05:08 ATakaSKY

Stale issue message

github-actions[bot] avatar Oct 02 '24 15:10 github-actions[bot]