Code Monkey home page Code Monkey logo

vite's Introduction

Vite/Rollup plugin for Module Federation

Reason why ๐Ÿค”

Microservices nowadays is a well-known concept and maybe you are using it in your current company. Do you know that now you can apply similar ideas on the Frontend? With Module Federation you can load separately compiled and deployed code into a unique application. This plugin makes Module Federation work together with Vite.

Working implementations

Getting started ๐Ÿš€

This plugin is based on top of native-federation so this library is a peer dependency.

You need to extend the Vite configuration with this plugin:

import { defineConfig } from 'vite';
import { federation } from '@module-federation/vite';
import { createEsBuildAdapter } from '@softarc/native-federation-esbuild';

// https://vitejs.dev/config/
export default defineConfig(async ({ command }) => ({
  server: {
    fs: {
      allow: ['.', '../shared'],
    },
  },
  plugins: [
    await federation({
      options: {
        workspaceRoot: __dirname,
        outputPath: 'dist',
        tsConfig: 'tsconfig.json',
        federationConfig: 'module-federation/federation.config.cjs',
        verbose: false,
        dev: command === 'serve',
      },
      adapter: createEsBuildAdapter({ plugins: [...], }),
    }),
    [...]
  ],
}));

Define configs

You need to define two different configurations in the federationConfig property.
Here are two examples:

So far so good ๐ŸŽ‰

Now you are ready to use Module Federation in Vite!

Thanks ๐Ÿค

Big thanks to:

Manfred Steyer, Speaker, Trainer, Consultant and Author with focus on Angular. Google Developer Expert (GDE) and Microsoft MVP.

who collaborate with me to make this possible.

vite's People

Contributors

gioboa avatar he110te4m avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vite's Issues

Dynamic remotes

I was wondering if this plugin supports dynamic remote paths loaded from an api.

Can the library provide an uncompressed code version in the build product?

When I need to debug the plugin code, it's hard to modify dist directly to debug because the code is compressed and hard to read.

I have to go through the following steps:

  1. Download the latest code for the plugin
  2. Build using the watch pattern
  3. Insert my debugging code into the source code
  4. Replace the built product with my project

If the library provides an uncompressed version, I can replace it directly in the project dist, which is much more convenient and efficient.

Can somebody provide an example of the Vite + Vue 2 + Composition Api

I am preparing to use this project to build the Vite + Vue 2.6 + Composition API project.
But what you see in Vue Example are all Vue3 use cases.
I have to say, the actual application should be more Vue2 projects. Because governance of old code can be trickier, we prefer to use the product directly.

I also tried using @originjs/vite-plugin-federation, but the project didn't work in Vite4. It seems that their maintainers are quite busy and have a lot of problems that are still not being addressed.

When I was ready to switch to this package, I was in trouble with the dependency package choice due to the lack of a corresponding example. For example: esbuild plug-in selection, configuration items to be opened.

Can anyone provide a simple example project?

Import images from remote

I tried importing images in a remote project with an import statement.

The final parsed image request is not taken over by es-module-polyfill, but by the browser.

Causes remote image resources to not be used properly.

So I need config remote base and host proxy to forward the request.

However, when I added the base configuration to remote, nothing worked.

e.g. remoteEntry.json can not be found and the shared deps import name has been changed.

Does this plugin support configuring base?

Or do I need to do something extra?

It should be noted that this functionality is normal for builds, and esbuild-plugin-inline-image is able to build images into base64, but does not take effect in Dev.

Adding dependency @adyen/adyen-web causes error in building shared package

I am build a remote component using this plugin. When I add as a dependency @adyen/adyen-web (which should be part of the bundle) I get the following issue:

> vite build

vite v4.4.11 building for production...
โœ“ 4 modules transformed.
../../dist/client/index.html                0.36 kB โ”‚ gzip: 0.25 kB
../../dist/client/assets/index-f6effac0.js  0.75 kB โ”‚ gzip: 0.42 kB
 INFO  Building federation artefacts
โœ“ built in 53ms
 INFO  Preparing shared npm packages
 NOTE  This only needs to be done once, as results are cached
 NOTE  Skip packages you don't want to share in your federation config
 ERR!  Error bundling shared npm package 
 ERR!  Invalid value for option "output.file" - when building multiple chunks, the "output.dir" option must be used, not "output.file". To inline dynamic imports, set the "inlineDynamicImports" option.
 ERR!  For more information, run in verbose mode
 NOTE  If you don't need this package, skip it in your federation.config.js!

This is the Vite configuration:

import { federation } from "@module-federation/vite";
import json from "@rollup/plugin-json";
import { createEsBuildAdapter } from "@softarc/native-federation-esbuild";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";
import { defineConfig } from "vite";

const path = dirname(fileURLToPath(new URL(import.meta.url)));
const root = resolve(path, "src/client");
const outDir = resolve(path, "dist/client");

export default defineConfig(async () => ({
  root,
  plugins: [
    await federation({
      options: {
        workspaceRoot: path,
        outputPath: 'dist/client',
        tsConfig: "tsconfig.json",
        federationConfig: "module-federation/federation.config.cjs",
        verbose: true,
        dev: true,
      },
      adapter: createEsBuildAdapter({ plugins: [] }),
    }),
    json(),
  ],
  build: {
    outDir,
  },
}));

This is the federation.config.cjs:

const {
  withNativeFederation,
  shareAll,
} = require("@softarc/native-federation/build");

module.exports = withNativeFederation({
  name: "mycomponent",

  exposes: {
    "./my-component": "./src/client/main.ts",
  },

  shared: shareAll(),
});

main.ts is just a simple function:

export function consoleLog(message: string) {
  console.log(message);
}

Whats different with originjs/vite-plugin-federation

Hi there!
Can you provide a detailed description of what your differences with https://github.com/originjs/vite-plugin-federation

Like this:

Feature MF Vite vite-plugin
Support Vite-Webpack yes yes
Support Webpack-Vite yes yes
feature 3 yes yes
feature 4 yes yes

My situation: in the remote host app I connected a lot of different types of apps (and webpack and vite). I have been using the federation module for a very long time in my application, so the migration will be very painful. Backward compatibility is just as important to me.

Support to expose sharable components to non-vite based projects built on webpack 5.

This module federation plugin works well when both remote and host apps are built using vite.
However, I didn't find a way to expose sharable components using module federation to non-vite applications and vice-a-versa.

Here are some scenarios:
Scenario 1:
A: I have a vite based react application that uses this vite module federation plugin to expose some sharable components.

B: I have a non-vite based react application that is built using webpack 5 (also supports module federation). This application needs to consume a shareable component built in A. How do I do that?

C: I have an angularjs app which wants to consume A. How is it possible?

Scenario 2:
A: I have a vite based react application that should consume a UI component built by another application B or C as explained below.

B: This is a non-vite based react application that uses webpack 5 which exposes some sharable components using module federation.

C: I have an angularjs app which has exposed shareable components using module federation.


Essentially, I want the module-federation should be framework agnostic.

Request you to please guide me with building above capabilities.

Appreciate your efforts in building this library.

How to troubleshoot build errors

I think this plugin looks very promising :-). However when I tried to use it on an larger existing code base I run into a number of errors and I'm not sure how to proceed with the troubleshooting. The code builds fine with regular vite.

This plugin uses the @softarc/native-federation which seems to do a lot of the work. I would like to dig into the code of that but I cannot find it anywhere. Do you know if that package is closed source? I did not find a license file in the installed directory for it.

Here is an example of the errors I run into:

 INFO  Preparing shared package styled-components
โœ˜ [ERROR] Could not resolve "stream"

    node_modules/.tmp/_styled_components_dist_styled_components.esm.js:2684:29:
      2684 โ”‚       var _require = require('stream');
           โ•ต                              ~~~~~~~~

  The package "stream" wasn't found on the file system but is built into node. Are you trying to
  bundle for node? You can use "platform: 'node'" to do that, which will remove this error.

 ERR!  Error bundling npm package styled-components
 ERR!  Build failed with 1 error:
 ERR!  node_modules/.tmp/_styled_components_dist_styled_components.esm.js:2684:29: ERROR: Could not resolve "stream"
 ERR!  For more information, run in verbose mode

I think somehow I need to augment the build process, but without the source for the build adapter stuff it is hard to know how to do it. Maybe it is related to fileReplacements but I'm not sure how to figure out how they work without digging into the missing source code.

Empty react in production build

I'm trying to create a simple react remote app that exposes 1 component. When I run Vite in dev mode it works, but when I run it in prod I get a blank page with the following error on the console:

Uncaught (in promise) SyntaxError: The requested module 'blob:http://127.0.0.1:3000/e5043e10-c7d6-4c8f-82a0-302742fc648d' does not provide an export named 'useState' (at bootstrap-b136d97a.js:1:144)
await (async)
(anonymous) @ index-dd854aaa.js:14

Checking the dist folder, some files from react are empty and reference development files instead of production.

I looked at #3 (specifically #3 (comment)) but downgrading doesn't solve the issue, downgrading breaks dev mode.

Also, the react example referenced on README.md doesn't work. It uses the 1.1.0 from @softarc/native-federation which doesn't work in dev or prod mode.

Reproduction repo

Support CommonJS/UMD modules in dev mode

Hello and thank you again for this plugin.
We spoke a bit in this issue and I am working on implementing the plugin for both host and remote (no webpack). Everything seems to work quite well with vite build and vite preview but I am unable to use vite dev mode (vite). It seems that once I add the plugin, pre-bundling of Common JS/UMD to ESM, which as I understand it is standard behavior for Vite, no longer happens? Or is happening incorrectly?
I understand I could alias to the ESM distribution for dev mode but we are still on Vue 2 and have some older packages that do not distribute an ESM version of the module so we would be blocked from using the plugin by this issue.

Relevant packages:
"vue": "2.7.14",
"@module-federation/vite": "^0.2.8",
"@softarc/native-federation": "^2.0.4",
"@softarc/native-federation-esbuild": "^2.0.4",
"@vitejs/plugin-vue2": "1.1.2",

Host config

    await federation({
      options: {
        workspaceRoot: __dirname,
        outputPath: 'dist',
        tsConfig: 'tsconfig.json',
        federationConfig: 'federation.config.ts',
        verbose: true,
        dev: command === 'serve',
      },
      adapter: createEsBuildAdapter({ plugins: [] }),
    }),

Remote config

    await federation({
      options: {
        workspaceRoot: __dirname,
        outputPath: 'dist',
        tsConfig: 'tsconfig.json',
        federationConfig: 'federation.config.ts',
        verbose: true,
        dev: command === 'serve',
      },
      adapter: createEsBuildAdapter({
        plugins: [pluginVue()],
      }),
    }),

Example error for package with no esm distribution:
Screenshot 2023-11-21 at 12 32 35 PM

There are problems when using the `@vue/composition-api`.

When I ran the sample repo, I noticed a bit of a problem.

When I modify Count.vue to the following code:

<script lang="ts">
import { defineComponent, ref } from "@vue/composition-api";

export default defineComponent({
  // change to setup syntax
  setup: () => {
    const count = ref(0);

    return {
      count,
    };
  },
});
</script>

<template>
  <button style="
        border: 0 solid #e2e8f0;
        margin-top: 10px;
        background-color: rgb(246, 179, 82);
        border-radius: 0.25rem;
        font-weight: 700;
        padding: 0.5rem 1rem 0.5rem 1rem;
        color: rgb(24, 24, 24);
      " @click="count++">
    Remote counter: {{ count }}
  </button>
</template>

This is the result of the run:

image

As we can see, the remote project is missing data.

I got the following misinformation from console: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function.

In fact, the @vue/composition-api needs to be initialize ( Vue.use ), then it can be used.

This error occurs because the @vue/composition-api is not shared and the initialization process is lost.

I still get an error when I try to share the @vue/composition-api:

image

Seems to be dependent on the loading order of the problem, can someone give me some advice?

Whether the shared chunk can be merged ?

When shared has too many dependencies, it causes too many network requests.

Is it possible to let users merge dependencies themselves?

I know this affects the dependent version rollback problem.

But in many cases, the user will be their own convention dependent version.

Let the user set it to not merge for dependencies that will differ.

There should be at least one option for the user to select.

PS: I Can't find the github repository for @softarc/native-federation, so I'll just have to ship it here first. I would appreciate it if someone could give me the warehouse address for this project

Question : it supports singleton?

I believe so many libraries do not support singleton by itself, while we need to ensure the isolation between the remotes and host.
if MF supports singleton will be good news.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.