GithubHelp home page GithubHelp logo

originjs / vite-plugin-federation Goto Github PK

View Code? Open in Web Editor NEW
2.0K 23.0 216.0 2.74 MB

Module Federation for vite & rollup

License: Other

JavaScript 20.76% TypeScript 57.42% HTML 4.33% Vue 14.56% CSS 2.82% EJS 0.08% Shell 0.02%
rollup vite vue microfront-end

vite-plugin-federation's Introduction

originjs

slogan:originjs is origin;

origin 中文名称 => "元";你也可以理解为源或原;意义为最原始的状态;类似混沌。

originjs is origin 翻译成中文 元本是元 ;见路不走,即见因果;见相非相,即见如来;

本着不拘泥于经验教条,同时又吸收前人成熟的方法,赋能开发者。

Originjs 的理念是一套基于原生Javascript 的轻量级的JavaScript框架,用于数据、方法的处理;

多数程序员在使用前端框架的时候可能会使用vue、react、ng等,虽然他们会以轻量高效著称,但是是否如他们讲的那样只有开发者有发言权。Originjs的出现并非是替代或颠覆而是完善,也就是说无论你是使用vue或react开发的项目您都可以使用Orgingjs加入到您的项目当中;

当然Originjs 不仅仅是为了迎合市场,更迎合我们开发者; 有些相对体量较小而且多是逻辑处理的项目,boss最求的高效&迅速完成开发,这时如果您再去用vue或react还是有一些的笨重。

这个时候就需要用到originjs协助您开发。

在语法上originjs基于原生的JavaScript开发,支持原生JavaScript ES6/7/8/9...,所以您不必为语法上做过多的纠结,只需按照我们的约定方式。

OriginJS

Help developers complete tasks faster

Requirement

  • google analytics installed

Getting started

From bower

bower install cn-originjs --save

From npm

npm install cn-originjs 

How it works

(1)originAjax(a,b,c,d,e);
	//=>ajax 
	Parameters you have to pass!!!
	a:url 
	b:type(post/get/put...) 
	c:cookie save true or false 
	d:callback 
	e:params
(2)originFor
	First step :Preparation data and target DOM Node
	arr: Data to process 
	domNode: Insertion node
	The second step: Call it
	originFor(arr,domNode,function(data){
		//Your code...
	})
	The third step: insert to target DOM Node


origin.post.Ajax(); //=> ajax post 
origin.getParams() //=> return url params in object type
origin.forData();//=> for data
origin.getSource() //=> return utm_source
origin.getMedium() //=> return utm_medium
origin.getContent() //=> return utm_content
origin.getCampaign() //=> return utm_campaign
origin.getTerm() //=> return utm_term

Contributing

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Added some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

Licence

CSHANS.CN | CN-OriginJs

vite-plugin-federation's People

Contributors

aboyl avatar adolph-wsy avatar amazingywk avatar bustexz avatar charlesbweez avatar chelestewang avatar dependabot[bot] avatar drzhbe avatar flyfishzy avatar genffy avatar includeios avatar jiawulin001 avatar mauriceayasse avatar mcenkar avatar meduzen avatar nefayran avatar nicktomlin avatar oleglustenko avatar picoi2 avatar rjz-avaleo avatar ruleeeer avatar timehello avatar tky753 avatar tzachbon avatar unformalized avatar wangsongc avatar ygj6 avatar zgid123 avatar zhtyytg avatar zwstar 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vite-plugin-federation's Issues

React TypeError: Cannot read properties of undefined (reading 'exports')

Thanks for spending the time to read this issue.

I have read and attempted fixes listed here:

Both host and remote are Vite projects

Versions

"@originjs/vite-plugin-federation": "1.1.4",

Reproduction

Clone this repo https://github.com/philals/reading-exports-issue/

cd into each directory and run npm install && npm run watch. This will run the container in dev mode (localhost:3000) and the remote served statically on localhost:3001

Confirm working

Uncomment this line: https://github.com/philals/reading-exports-issue/blob/master/app/src/App.tsx#L6

Refresh browser, issue encountered.

Additional Details

Steps to reproduce

Above

What is Expected?

All working

What is actually happening?

Error: Uncaught TypeError: Cannot read properties of undefined (reading 'exports')

image

image

variables are renamed when shared exported

use of the shared must ensure that the output.minifyInternalExports configuration of each application is consistent,but if the forced designation is too intrusive, find a reasonable way to enable shared to enable this function, but it will not affect the user's configuration

output: {
    format: 'esm',
    dir: pkg.main,
    minifyInternalExports:false
  },

[vite]: Rollup failed to resolve import "semver" from "virtual:__federation_fn_import"

Versions

  • originjs: v1.0.6
  • node: v16.7.0

Detail

[vite]: Rollup failed to resolve import "semver" from "virtual:__federation_fn_import".
  This is most likely unintended because it can break your application at runtime.
  If you do want to externalize this module explicitly add it to
  `build.rollupOptions.external`
  error during build:
  Error: [vite]: Rollup failed to resolve import "semver" from "virtual:__federation_fn_import".
  This is most likely unintended because it can break your application at runtime.
  If you do want to externalize this module explicitly add it to
  `build.rollupOptions.external`
      at onRollupWarning (/Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-e0fe87f8.js:43253:19)
      at onwarn (/Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/vite/dist/node/chunks/dep-e0fe87f8.js:43037:13)
      at Object.onwarn (/Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:23003:13)
      at ModuleLoader.handleResolveId (/Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22347:26)
      at ModuleLoader.resolveDynamicImport (/Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22401:26)
      at processTicksAndRejections (node:internal/process/task_queues:96:5)
      at async /Users/alpha/Alpha/test-app/node_modules/.pnpm/[email protected]/node_modules/rollup/dist/shared/rollup.js:22305:32

I am using pnpm workspace to create two apps. Here the vite.config.ts

  • app with error when building
import { resolve } from 'path';
import { readdirSync } from 'fs';
import detect from 'detect-port';
import { defineConfig, UserConfigExport } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
import federation from '@originjs/vite-plugin-federation';

import pkg from './package.json';

export default async function config(): Promise<UserConfigExport> {
  const port = await detect(8000);

  const items = readdirSync(resolve(__dirname, 'src'));

  return defineConfig({
    server: {
      port,
    },
    plugins: [
      reactRefresh(),
      federation({
        name: 'cryptocurrencyApp',
        filename: 'remoteEntry.js',
        exposes: {
          './App': './src/App',
        },
        shared: {
          react: {
            eager: true,
            requiredVersion: pkg.dependencies.react,
          },
          'react-dom': {
            eager: true,
            import: false,
            requiredVersion: pkg.dependencies['react-dom'],
          },
          'react-router-dom': {
            eager: true,
            import: false,
            requiredVersion: pkg.dependencies['react-router-dom'],
          },
          '@chakra-ui/react': {
            eager: true,
            import: false,
            requiredVersion: pkg.dependencies['@chakra-ui/react'],
          },
        },
      }),
    ],
    resolve: {
      alias: items.map((item) => {
        if (/\.(t|j)sx?$/.test(item)) {
          const name = item.replace(/\.(t|j)sx?$/, '');

          return {
            find: name,
            replacement: `/src/${name}`,
          };
        } else {
          return {
            find: item,
            replacement: `/src/${item}`,
          };
        }
      }),
    },
    build: {
      target: 'esnext',
    },
  });
}
{
  "name": "@apps/microapp",
  "version": "0.0.0",
  "license": "MIT",
  "main": "dist",
  "scripts": {
    "start": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview --port 8000 --strictPort"
  },
  "dependencies": {
    "@chakra-ui/react": "^1.7.2",
    "@emotion/react": "^11.7.0",
    "@emotion/styled": "^11.6.0",
    "@libs/rc-component": "workspace:^0.0.1",
    "@libs/rc-utils": "workspace:^0.0.1",
    "framer-motion": "^5.3.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-router-dom": "^6.0.2"
  },
  "devDependencies": {
    "@originjs/vite-plugin-federation": "^1.0.6",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "@vitejs/plugin-react-refresh": "^1.3.6",
    "eslint-config-react-app": "^6.0.0",
    "eslint-plugin-flowtype": "^8.0.3",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.27.1",
    "eslint-plugin-react-hooks": "^4.3.0",
    "vite": "^2.6.14"
  }
}
  • app without error
import { resolve } from 'path';
import { readdirSync } from 'fs';
import detect from 'detect-port';
import { defineConfig, UserConfigExport } from 'vite';
import reactRefresh from '@vitejs/plugin-react-refresh';
import federation from '@originjs/vite-plugin-federation';

import pkg from './package.json';

export default async function config(): Promise<UserConfigExport> {
  const port = await detect(3000);

  const items = readdirSync(resolve(__dirname, 'src'));

  return defineConfig({
    server: {
      port,
    },
    optimizeDeps: {
      exclude: ['cryptocurrency'],
    },
    plugins: [
      reactRefresh(),
      federation({
        remotes: {
          cryptocurrency: 'http://localhost:8000/assets/remoteEntry.js',
        },
        shared: {
          react: {
            eager: true,
            singleton: true,
            requiredVersion: pkg.dependencies.react,
          },
          'react-dom': {
            eager: true,
            singleton: true,
            requiredVersion: pkg.dependencies['react-dom'],
          },
          'react-router-dom': {
            eager: true,
            singleton: true,
            requiredVersion: pkg.dependencies['react-router-dom'],
          },
          '@chakra-ui/react': {
            eager: true,
            singleton: true,
            requiredVersion: pkg.dependencies['@chakra-ui/react'],
          },
        },
      }),
    ],
    resolve: {
      alias: items.map((item) => {
        if (/\.(t|j)sx?$/.test(item)) {
          const name = item.replace(/\.(t|j)sx?$/, '');

          return {
            find: name,
            replacement: `/src/${name}`,
          };
        } else {
          return {
            find: item,
            replacement: `/src/${item}`,
          };
        }
      }),
    },
    build: {
      target: 'esnext',
    },
  });
}
{
  "name": "mainapp",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": {
    "start": "vite",
    "build": "tsc && vite build",
    "serve": "vite preview"
  },
  "dependencies": {
    "@chakra-ui/react": "^1.7.2",
    "@emotion/react": "^11.7.0",
    "@emotion/styled": "^11.6.0",
    "@libs/core-utils": "workspace:^0.0.1",
    "@libs/rc-component": "workspace:^0.0.1",
    "@libs/rc-utils": "workspace:^0.0.1",
    "eventemitter3": "^4.0.7",
    "framer-motion": "^5.3.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-hook-form": "^7.20.5",
    "react-router-dom": "^6.0.2"
  },
  "devDependencies": {
    "@originjs/vite-plugin-federation": "^1.0.6",
    "@types/react": "^17.0.37",
    "@types/react-dom": "^17.0.11",
    "@vitejs/plugin-react-refresh": "^1.3.6",
    "eslint-config-react-app": "^6.0.0",
    "eslint-plugin-flowtype": "^8.0.3",
    "eslint-plugin-import": "^2.25.3",
    "eslint-plugin-jsx-a11y": "^6.5.1",
    "eslint-plugin-react": "^7.27.1",
    "eslint-plugin-react-hooks": "^4.3.0",
    "vite": "^2.6.14"
  }
}
  • global package json
{
  "name": "test-app",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "nx-monorepo": "npx add-nx-to-monorepo",
    "affected:dep-graph": "nx affected:dep-graph",
    "prepare": "husky install",
    "storybook": "start-storybook -p 6006",
    "build-storybook": "build-storybook"
  },
  "devDependencies": {
    "@nrwl/cli": "^13.2.3",
    "@nrwl/tao": "^13.2.3",
    "@nrwl/workspace": "^13.2.3",
    "@storybook/addon-actions": "^6.4.7",
    "@storybook/addon-controls": "^6.4.7",
    "@storybook/addon-docs": "^6.4.7",
    "@storybook/addon-essentials": "^6.4.7",
    "@storybook/addon-links": "^6.4.7",
    "@storybook/react": "^6.4.7",
    "@types/detect-port": "^1.3.1",
    "@typescript-eslint/eslint-plugin": "^5.5.0",
    "@typescript-eslint/parser": "^5.5.0",
    "detect-port": "^1.3.0",
    "eslint": "^8.4.0",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "husky": "^7.0.4",
    "lint-staged": "^12.1.2",
    "prettier": "^2.5.1",
    "storybook-addon-package-json": "^2.0.0",
    "tslib": "^2.3.1",
    "typescript": "^4.5.2"
  }
}

semver test case failed

@zgid123 I submitted a pr to add a build to semver, but there seems to be a problem with some of the unit tests, I skipped both test cases for now, can you re-initiate a pr to fix this and turn on the tests?
image

Support for Dynamic Remotes

Is your feature request related to a problem? Please describe.

For now we have to define the remotes in host at buildtime
Is there a way that remotes can be defined dynamically at run time instead?

Describe the solution you'd like

Would like a solution for dynamic import remote component from an remote url at runtime, no need define the remote in the vite plugin conifg.
like in wepack, can ref here: webpack/webpack#11033
will this feature be in the roadmap?

Describe alternatives you've considered

Additional context

basicly same as issue #121

run build, there is a issue, like Emitted chunks need to have a valid string id, received "undefined"

Versions

"@originjs/vite-plugin-federation": "^1.1.5",
"vue": "^3.2.6",

  • originjs:
  • node: v17.0.0

Reproduction

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import federation, {
VitePluginFederationOptions,
} from '@originjs/vite-plugin-federation'
const resolve = (dir: string) => path.resolve(__dirname, dir)
import viteCompression from 'vite-plugin-compression'

const Options: VitePluginFederationOptions = {
name: 'settings',
filename: 'remoteEntry.js',
exposes: {
'./Head': './src/components/Head.vue',
},
shared: ['vue'],
}
// https://vitejs.dev/config/
export default defineConfig({
plugins: [federation(Options), vue(), viteCompression()],
server: {
port: 4200,
fs: {
// Allow serving files from one level up to the project root
allow: [],
strict: false,
},
},
build: {
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true,
},
},
outDir: 'dist/frame',
minify: false,
},
resolve: {
alias: {
'@': resolve('src'),
},
},
})

Additional Details

Steps to reproduce

What is Expected?

build success

What is actually happening?

image

Mix exposes and remotes on the same module

Versions

  • originjs: 1.1.4
  • node: 14.17.0

Reproduction

go to: https://github.com/ChristPetitjean/BUG-vite-plugin-federation

1. Auth module

run npm run build. It should build fine
run npm run serve. It should serve the module on port 5002
you can navigate to http://localhost:5002 to confirm the site starts

2. Header module

run npm run build. It should build fine
run npm run serve. It should serve the module on port 5001
you can navigate to http://localhost:5001 to confirm the site starts

3. Portal module

run npm run dev. It should run the portal and the header should be displayed
Here you can notice a thing.
The vue-router is not shared (visible because no link are highlighted) whereas they were highlighted when runing http://localhost:5001 directly.
But that is not the major issue here.

Steps to reproduce

To reproduce switch to the branch: bug-remotes-exposes: https://github.com/ChristPetitjean/BUG-vite-plugin-federation/tree/bug-remotes-exposes
Or open the pull request to see differences: ChristPetitjean/BUG-vite-plugin-federation#1

What is Expected?

Header module is able to build

What is actually happening?

When activating auth module in header (so header have remotes and exposes configured), it will not build at all.

When only one remote, the style is missing

Versions

  • originjs: 0.0.2
  • node: v14.16.0
  • vue: 2.6.14

Reproduction

vue2-demo
remote's vite.config.js
plugins: [ createVuePlugin(), federation({ name: 'remote-simple', filename: 'remoteEntry.js', exposes: { './remote-simple-button': './src/components/Button.vue', }, shared: ['vue'] }) ]

Steps to reproduce

  1. Create 2 Vue2 project.
  2. Remote project only have one remote named './remote-simple-button'

What is Expected?

Host Project will show component without style.
image

What is actually happening?

No loading of the corresponding CSS file is provided

Is it possible to add a configuration to set the packaged result directory

Is your feature request related to a problem? Please describe.

Because my project packaging configuration distinguishes different files from being packaged into different file directories, not all of them are stored in the assets directory. Is it possible to add a configuration item to set the output directory of _federation and other files?

Describe the solution you'd like

Add a new configuration to the options of the federation function of index.ts to configure the name of the directory output after packaging, and then use the user-configured output directory first in the config function

image

Transpiling of scoped packages

Versions

  • originjs: last
  • node: last

Reproduction

TODO

Steps to reproduce

  1. You need a scoped dep (for example, @company/ui)
  2. You need to share this package (for example, shared: ['@company/ui'])
  3. You need to use remote/host bundled by webpack with same shared dep.

What is Expected?

In webpack and vite shared scope this package must be called as @company/ui

What is actually happening?

In webpack shared scope this package will be as it is - @company/ui
In vite shared scope this package will be formatted - @companyUi

When webpack is a remote and vite is a host, webpack tries to request a package with @company/ui name, but in the vite scope it is called differently: @companyUi. As i undestand, the problem into this place with removeNonLetter utility, that transpiles imports

use import_util in exposes

Because each exposes component will have the following piece of code for shared
image

these codes should be grouped into tool classes, and an import_util should be used instead,and then import A from 'B' => rf_import(B).A

Remote cannot provide a component based on element-plus to host in dev mode

Versions

  • originjs/vite-plugin-federation:
  • node:
  • element-plus:
  • vue:

Reproduction

dev mode + vite + vue + element-plus

Additional Details
`__x00__virtual:__federation__:17 GET http://localhost:5104/node_modules/.vite/element-plus.js?v=cc040915 net::ERR_ABORTED 404 (Not Found)

localhost/:1 Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:5104/node_modules/.vite/element-plus.js?v=cc040915
Promise.catch (async)
`

Steps to reproduce

  1. Create a project that uses vite + vue + element-plus. Create a el-button as a component to host.
    Host is only rendered
    <el-button></el-button>
  2. Use vite‘ dev mode to start the host service.

What is Expected?

Host renders a correct ElButton component

What is actually happening?

The Host does not use element-plus, so there is no corresponding element-plus dependency in the node_modules/.vite folder, and remote cannot call host's element-plus for rendering

Bug with `importShared`

Versions

Reproduction

I can add it, if u need)

Steps to reproduce

For example, we have remote vite app with config:

// vite.config.ts
const config = {
  build: {
    target: 'esnext',
  },
  plugins: [
    react(),
    federation({
      name: 'remote',
      filename: 'remoteEntry.js',
      exposes: {
        // IMPORTANT!!! Entry to `index`
        './Button': './src/components/Button/index.ts',
      },
      shared: [
        {
          react: {
            singleton: true,
            import: true,
          },
          'react-dom': {
            singleton: true,
            import: true,
          },
          'ui-components': {
            import: true,
          },
        },
      ],
    }),
  ],
}

And Button component:

// src/components/Button/index.ts
export * from './component';
// src/component/Button/component.tsx
import { type FC, useEffect, useState } from 'react';

import { type ButtonProps, Button as UIButton } from 'ui-components';

export const Button: FC<Omit<ButtonProps, 'children'>> = (props) => {
  const [text, setText] = useState('Init...');

  useEffect(() => {
    setText('Inited!');
  }, []);

  return <UIButton {...props}>{text}</UIButton>;
};

When is bundled i've got some code in __federation_expose_Button.js:

import{B as r}from"./component.81d3bf23.js";export{r as Button};

And in component.81d3bf23.js:

import { r as t } from './__federation_shared_react.js';
import { j as o, Button as n } from './[email protected]';
// code of Button

The problem is that in this case, the imports of shared modules are not wrapped in the importShared and, when using a remote, the assembled versions of the shared modules of the remote, not the host, are loaded.
If i change expose entry to './Button': './src/components/Button/component.tsx',, code in component.tsx transpiled fine with importShared:

import { importShared as e } from './__federation_fn_import.js';
const { r: t } = await e('react'),
  { j: s, Button: c } = await e('@platformecoUi-components'),
// code of Button

As I understand it, the logic for determining the need for import transpilation is here: https://github.com/originjs/vite-plugin-federation/blob/main/packages/lib/src/prod/shared-production.ts#L297.
Therefore two questions:

  1. will imports be transpiled in child chunks of the remote correctly?
  2. is there a way to get around this bug?

What is Expected?

importShared must be used for all shared-imports under the remoteEntry

What is actually happening?

See above

Dynamic/runtime remotes

Is your feature request related to a problem? Please describe.

We want to get a list of remotes at runtime from another api service. e.g. GET /api/services. From the examples here I can only see how to do this at build time by specifying the remotes in vite.config.js or rollup config.

Describe the solution you'd like

We would like to dynamically load remotes at runtime, here is an example of doing it w/ webpack and their "container" model:

https://github.com/module-federation/module-federation-examples/blob/master/dynamic-system-host/app1/src/App.js

I've had a bit of look into some of the code in expose-dev.ts but its still early for me.

Does this sound feasible?

Describe alternatives you've considered

Trying to use systemjs perhaps?

Issue with shared react dependency

We have this error when using shared dependencies react + react-dom:
Uncaught TypeError: application 'myRemoteApp' died in status LOADING_SOURCE_CODE: Cannot read properties of undefined (reading 'ReactCurrentOwner')

This error is not happening if we removed shared from the option of the plugin. (But react is loaded two times)

Versions

  • originjs: 1.1.3
  • node: 16.14

Reproduction

We will create a reproduction as soon as possible but maybe we are doing something wrong with our config.
We don't see any exemple that use react on both side.

Config on vite (host)

 federation({
      name: 'myApp',
      remotes:{
        myRemoteApp: {
          external: 'http://localhost:3001/remoteEntry.js',
          format: 'var',
        }
      },
      shared: {
        react: {
          version: '^17.0.1',
        },
        'react-dom': {
          version: '^17.0.1',
        }
      }
    }),

Config on Webpack (remote)

  new ModuleFederationPlugin({
            name: 'myRemoteApp',
            filename: 'remoteEntry.js',
            exposes: {
                './App': './src/App',
            },
            shared: [
                {
                    ...deps,
                    react: {
                        singleton: true,
                        requiredVersion: deps.react,
                    },
                    'react-dom': {
                        singleton: true,
                        requiredVersion: deps['react-dom'],
                    },
                },
            ],
        }),

This Webpack configuration for the remote is perfectly working with an other Webpack config as host.

Thank you for your help.
We will try to provide reproduction as soon as possible

styles in the dependencies of exposed component are not imported

problem:

  1. styles in the dependencies of exposed component are not imported
  2. the dependency of exposed component will extra import the shared lib if the denpendency in the single chunk

reproduce repo

Describe the solution you'd like

  • 1. the style of dependencies should be automatically imported

  • 2. shared libs should not be imported if the host app provides

Describe alternatives you've considered

for problem 1, try to add all css chunk of dependencies in generateBundle hook, the param of dynamicLoadingCss method is modified to array type, to support import multiple css chunks
for problem 2, if an app in exposes flag, use the importShared function instead of commonly refer the shared lib

I try to fix these 2 problems, here is a PR

If these is something i miss, please let me know :-)

Remote cannot provide a component based on element-plus to host

Versions

  • originjs/vite-plugin-federation:
  • node:
  • element-plus:
  • vue:

Reproduction

vite + vue + element-plus

Additional Details
No information is printed on the console

Steps to reproduce

Create a project that uses vite + vue + element-plus. Create a el-button as a component to host.
Host is only rendered
<el-button></el-button>

What is Expected?

Host renders a correct ElButton component

What is actually happening?

Host is only rendered
<el-button></el-button>

Images not showing

Versions

  • originjs: 1.1.2
  • node: v16.13.1

Reproduction

I create two projects using vite and react, the host is "empty" and the remote has the default react app with the counter.

Additional Details

Steps to reproduce

Build the remote (http:5000) and serve (http:3000) the host.

What is Expected?

Show the svg.

What is actually happening?

image

Is searching the svg in http://localhost:3000/assets/logo.ecc203fb.svg but is in localhost:5000

I think is a problem with relative paths, i found that this error occurs in Module federation

[Vite] Typescript build

When I run host in dev mode all works fine, but when I try to build got an error

 npm run build

> [email protected] build /home/imkarma/Projects/galileo/packages/stargate
> vue-tsc --noEmit && vite build

src/App.vue:7:16 - error TS2307: Cannot find module 'router-remote/HelloWorld' or its corresponding type declarations.

7   () => import("router-remote/HelloWorld")
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 1 error.

npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] build: `vue-tsc --noEmit && vite build`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the [email protected] build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/imkarma/.npm/_logs/2022-02-22T14_46_50_721Z-debug.log

Vue3 + Vite + TypeScript

Invalid VNode type: Symbol() error

<template> 
<div>
    **whats is this**
    <h1>Hello from exposed This is the HelloWorld vue from remote</h1> 
</div>
</template>

remote component from a host app some elements "whats is this" text is missing and the following error is on console
runtime-core.esm-bundler.js:38 [Vue warn]: Invalid VNode type: Symbol() (symbol)

image

but if the remote is run independently txt "what's is this" is properly rendered n no errors

image

Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: http://localhost:3000/node_modules/.vite/element-plus.js?v=undefined

[originjs:federation] Cannot read properties of undefined (reading 'entries')

Versions

  • originjs: 1.0.1
  • "vite": "^2.6.13",
  • "@vitejs/plugin-react": "^1.0.7",
  • node:
  • react latest
When i run vite buil i get this error // [originjs:federation] Cannot read properties of undefined (reading 'entries') // error during build: // TypeError: Cannot read properties of undefined (reading 'entries') // at Object.outputOptions (F:\intelprogramfiles\x\packages\home\node_modules\@originjs\vite-plugin-federation\dist\index.js:1953:62) // at Object.outputOptions (F:\intelprogramfiles\x\packages\home\node_modules\@originjs\vite-plugin-federation\dist\index.js:2277:89) // at PluginDriver.runHookSync (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:22688:25) // at PluginDriver.hookReduceArg0Sync (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:22605:33) // at getOutputOptions (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:23469:54) // at getOutputOptionsAndPluginDriver (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:23464:12) // at handleGenerateWrite (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:23441:74) // at Object.write (F:\intelprogramfiles\x\packages\home\node_modules\rollup\dist\shared\rollup.js:23408:20) // at generate (F:\intelprogramfiles\x\packages\home\node_modules\vite\dist\node\chunks\dep-85dbaaa7.js:43137:64) // at doBuild (F:\intelprogramfiles\x\packages\home\node_modules\vite\dist\node\chunks\dep-85dbaaa7.js:43150:26) Additional Details
import { defineConfig } from 'vite'; import federation from '@originjs/vite-plugin-federation'; import banner2 from 'rollup-plugin-banner2'; import react from '@vitejs/plugin-react'; import commonjs from '@rollup/plugin-commonjs'; import path from 'path';

const sharedModules = {
react: '',
'react-dom': '
',
'react-router-dom': '',
'@material-ui/core': '
',
'@material-ui/icons': '',
'@material-ui/styles': '
',
'@material-ui/lab': '',
'@material-ui/pickers': '
',
'@welldone-software/why-did-you-render': '*',
};

const exposesComponents = {
'./App': './src/App',
'./LeftSideMenu': './src/components/LeftSideMenu',
'./RightSideMenu': './src/components/RightSideMenu',
'./ModalNotifications': './src/components/Notification/ModalNotifications',
};

export default defineConfig({
publicDir: path.join(__dirname, 'public'),
server: {
host: 'localhost',
port: 3003,
},
build: {
sourcemap: true,
},
plugins: [
react(),
banner2(() => Ozey),
federation({
name: 'home',
library: { type: 'var', name: 'home' },
filename: 'remoteEntry.js',
exposes: exposesComponents,
shared: sharedModules,
}),
],
});

`remotes` replace error

Versions

  • vite-plugin-federation: v1.0.1

Reproduction

config remote

 plugins: [
    federation({
      remotes: {
        remote_app: "http://localhost:5001/remoteEntry.js",
      }
    }),
  ],

Suppose we have a file remote_application.js, and dynamic import it.

const lazyLoad = ()=> import("remote_application.js");

What is Expected?

import("remote_application.js")

What is actually happening?

const lazyLoad = ()=> __federation__.ensure("remote_app").then((remote) => remote.get(".lication.js"));

remote need to save shared info

Is your feature request related to a problem? Please describe.

Describe the solution you'd like

Describe alternatives you've considered

Additional context

在remote中使用vuex正常,但是把组件expose到 host中使用时有问题

image

remote
federation({
name: 'router-remote',
filename: 'remoteEntry.js',
exposes: {
'./TestButton': './src/federation/TestButton.vue',
'./Parent': './src/views/example/parent-children/Parent.vue',
'./VuexUse': './src/views/example/vuex-use/VuexUse.vue',
'./test': './src/store/modules/test.ts'
},
shared: ['vue','vuex']
}),

host
federation({
name: "router-host",
filename: "remoteEntry.js",
remotes: {
"router-remote": "http://localhost:5003/vue3-admin-ts/assets/remoteEntry.js",
},
shared: ["vue","vuex"]
}),

是不是 remote无法导出vuex到 host中使用,或者有什么出来办法能处理呢

"vue3-advanced-demo" not works well

image
element-plus components are not been rendered。 only simple component can work well. if a component contains another one, will not work.

Versions

  • node: v16.13.2
  • @originjs/vite-plugin-federatio: ^1.1.0
  • vue: ^3.2.0

another problem happened to me was when i use shared i got a wrong msg like that:

Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2019", "firefox78", "safari13.1")
1 | import {importShared} from './__federation_fn_import.js'
2 | import { _ as _export_sfc } from './plugin-vue_export-helper.21dcd24c.js';
3 | const {resolveComponent,openBlock,createElementBlock,createVNode,withCtx,Fragment,createTextVNode} = await importShared('vue')

vue3 host 与 remote vue 版本冲突的问题

Versions

  • originjs:
  • node:

Reproduction

Additional Details

Steps to reproduce

host 与 remote 都设置 shared: ["vue"]

在不引入其他库【例如:组件库】的时候,可以正常工作

但是一旦引入了组件库,或者使用了slot,就会报错如下

Cannot read property 'isCE' of null in remote component with slot using Module Federation

vuejs/core#4344

vite.config.js

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import federation from '@originjs/vite-plugin-federation'

import Components from 'unplugin-vue-components/vite'
import { PrimeVueResolver } from 'unplugin-vue-components/resolvers'

import path, { join } from 'path'
import { writeFileSync } from 'fs'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    Components({
      resolvers: [
        PrimeVueResolver()
      ]
    }),
    federation({
      name: 'home',
      filename: 'remoteEntry.js',
      exposes: {
        './Content': './src/components/HelloWorld.vue',
        './Container': './src/Container.vue',
        './Button': './src/components/Button.vue'
      },
      shared: ["vue"]
    })
  ],
  build: {
    assetsInlineLimit: 40960,
    target: 'esnext',
    minify: true,
    cssCodeSplit: false,
    rollupOptions: {
      output: {
        minifyInternalExports: false,
      },
    },
  },
})

请问应该如何正确配置

What is Expected?

What is actually happening?

TypeError: Cannot read properties of undefined (reading 'exports')

Versions

  • originjs: 1.1.0
  • node: 16.13.1

Reproduction

host vite.config and remote vite.config as below
...
build: {
target: 'esnext',
},
...
shared: {
react: { singleton: true },
'react-dom': {
singleton: true,
},
},

build remote & npm run preview

host refference remote component, display error info

TypeError: Cannot read properties of undefined (reading 'exports')

remove remote shared react-dom, it's works with normal element.
if the component refference other lib for eg. antd Header.
It's cause error with

https://reactjs.org/docs/error-decoder.html?invariant=321 

What is Expected?

add react-dom to shared works and work together with other lib

What is actually happening?

[Question] - about dev mode

This is not really an issue or something like that.

I just wanna help to build a dev mode. But I still not know how to do it and get lost while trying to research webpack module federation.

If can, can you provide me a vision about this feature of this project and some docs to research?

I will research and help to build the dev mode because this feature will be useful

System is not defined

Hi,

I'm trying to use with vue 2 webpack and vue-3 vite js. but after all, the settings is done vite gaves System is not defined error. This is my code.

Vue-2 + Webpack 5

  new ModuleFederationPlugin({
        name: 'core',
        filename: 'remoteEntry.js',
        library: { type: 'system' },
        exposes: {
            './sidebar': './src/layout/Sidebar.vue',
        },
        shared: ['vue'],
    }),

Vue-3 + Vite

in Vue 3 + Vite project I define the component this way

const sidebar = defineAsyncComponent(() => import("core/sidebar"));
app.component("sidebar", sidebar);
 plugins: [
            Vue({
                include: [/\.vue$/, /\.md$/],
            }),
            Pages(),
            Layouts(),
            federation({
                name: "new-lookup",
                filename: "remoteEntry.js",
                remotes: {
                    core: "http://localhost:3030/remoteEntry.js"
                },
            }),
        ],

and error is:

remoteEntry.js:9 Uncaught (in promise) ReferenceError: System is not defined at remoteEntry.js:9

line 9:

System.register([], function(__WEBPACK_DYNAMIC_EXPORT__, __system_context__) {....

Thanks for help

element-plus in dev mode error, because rollup changes the vue method name

Versions

  • originjs/vite-plugin-federation: v1.0.1
  • node: ex: v14.16.0
  • element-plus: ^1.1.0-beta.20
  • vue: 3.2.26

Reproduction

dev mode + vite + vue + element-plus

Additional Details
Uncaught (in promise) TypeError: createBaseVNode is not a function
at Proxy._sfc_render (ElementPlus.a10a5c5a.js:31)
at renderComponentRoot (chunk-GRYARPSM.js:1603)
at ReactiveEffect.componentUpdateFn [as fn] (chunk-GRYARPSM.js:4089)
at ReactiveEffect.run (chunk-GRYARPSM.js:1121)
at setupRenderEffect (chunk-GRYARPSM.js:4181)
at mountComponent (chunk-GRYARPSM.js:4019)
at processComponent (chunk-GRYARPSM.js:3984)
at patch (chunk-GRYARPSM.js:3700)
at ReactiveEffect.componentUpdateFn [as fn] (chunk-GRYARPSM.js:4150)
at ReactiveEffect.run (chunk-GRYARPSM.js:1121)</code></details>

Steps to reproduce

  1. Create a project that uses vite + vue + element-plus. Create a el-button as a component to host.
    Host is only rendered
    <el-button></el-button>
  2. Use vite‘ dev mode to start the host service.

What is Expected?

Host renders a correct ElButton component

What is actually happening?

Because rollup changes the vue method name, createBaseVNode export named createElementVNode

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.