How to Implement Type in Module Federation (Poly repo)

ilumin

Lumin

Posted on October 7, 2022

How to Implement Type in Module Federation (Poly repo)

When you're building a Typscript micro-frontend project with Webpack Module Federation, you might have type problems (no type support when import package from remote). But it's depend on what type of git repository of the project.

If it's a mono repo ... no problem, just import type from other package (in the same repo!)

If it's a poly repo ... you might have to import type from remote, but how?

use @module-federation/typescript


Prepare project

# setup pnpm project 
mkdir remote-typesafe && cd remote-typesafe/
pnpm init -y

# setup workspace
cat >> package-workspace.yml << 'END'
packages:
  - host 
  - remote
END

# create host
npx create-mf-app
# name: host
# type: Application
# port: 8080
# framework: react 
# language: typescript 

# create remote
npx create-mf-app
# name: remote
# type: Application
# port: 8080
# framework: react 
# language: typescript 

# install packages 
pnpm i 

# then, we will have folder structure like these
# |- /remote-typesafe
# |  |- host/
# |  |- remote/
Enter fullscreen mode Exit fullscreen mode

Installation

You need to install @module-federation/typescript both host app and remote app

# when I'm writing this blog 0.2.2 is the most stable version
pnpm i -D @module-federation/typescript@0.2.2
Enter fullscreen mode Exit fullscreen mode

Configuration

Add the plugin both host app and remote app

const FederatedTypesPlugin = require('@module-federation/typescript')

module.exports = {
  // ...weboack config 
  plugins: [
    new ModuleFederationPlugin(), // module federation main config 
    new FederatedTypePlugin(), // remote typesafe plugin
  ]
}
Enter fullscreen mode Exit fullscreen mode

Development flow

We need to published the remote app first

Here, I add a simple src/Button.tsx component and expose it

export interface ButtonProps {
  title: string
  onClick?: () => void
}

const Button = (props: ButtonProps) => {
  const onClick = () => props?.onClick && props?.onClick()
  return <button onClick={onClick}>{props.title}</button>
}

export default Button
Enter fullscreen mode Exit fullscreen mode

Then, build it!

pnpm build
Enter fullscreen mode Exit fullscreen mode

We will have dist/ that store our remoteEntry.js and dist/@mf-typescript that store our type as Button.d.ts

Then serve it!

pnpm build:start # it's just enter dist and serve this folder 
Enter fullscreen mode Exit fullscreen mode

Now, we move to host app.

We need to start Webpack devServer first (because we're about to dev it!)

pnpm start:live
Enter fullscreen mode Exit fullscreen mode

Webpack will generate @mf-typescript in out root project

All we have to do is import the type and use it! like these

import { ButtonProps } from '../@mf-typesript/remote/Button'

const Button = React.lazy(() => import('remote/Button')) 
  as unknown 
  as React.FC<ButtonProps>
Enter fullscreen mode Exit fullscreen mode

And now, our Button will have type and it will show us some warning when we use invalid type.

💖 💪 🙅 🚩
ilumin
Lumin

Posted on October 7, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related