Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: 在 Module Federation 2.0 编译时场景用例中 RSPack 打包速度极慢,慢到难以置信 #6564

Open
cheng4kn opened this issue Nov 25, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@cheng4kn
Copy link

版本信息

System:
    OS: macOS 15.1
    CPU: (8) arm64 Apple M2
    Memory: 81.92 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Browsers:
    Chrome: 131.0.6778.86
    Safari: 18.1
  npmPackages:
    @modern-js/app-tools: 2.60.1 => 2.60.1 
    @modern-js/plugin-tailwindcss: 2.60.1 => 2.60.1 
    @modern-js/runtime: 2.60.1 => 2.60.1 
    @modern-js/tsconfig: 2.60.1 => 2.60.1

问题详情

工程简介

我们使用 Modernjs 的 MF 2.0 加 mono-repo 实现了这套架构,工程架构如下:

Image

现有的工程目录如下所示:

❯ tree . -L 2 
.
├── README.md
├── TODO.md
├── apps
│   ├── admin - 子应用
│   └── shell - 主运行时
├── biome.json
├── docker-compose.yml
├── package.json
├── packages
│   ├── runtime - 共享的运行时依赖
│   └── shared - 共享的编译时依赖
├── pnpm-lock.yaml
└── pnpm-workspace.yaml

我们提供了两种打包方式:
一种是在工程的根目录下启动 "pnpm --parallel --filter @app/* run dev",一种是 cd apps/admin 进入子应用开发。

我们的 MF 依赖关系如下:

app-shell

主应用(消费者 Consumer),负责提供基础的 UI 组件和基础的路由功能。在运行时动态加载子应用。

app-admin

子应用(提供者 Provider),负责提供具体的业务功能和视图,在运行时被 shell 应用动态加载。

问题描述

我们遇到了一些前端工程化上比较棘手的问题,有两种情况:

  1. 同时启动多个应用时,shell 的 HMR(Hot-Module Reload) 只需要 2~3s 符合 Rspack 的正常速度,但是当我们更新子应用时,比如说修改了 admin 中的代码,更新一般需要 8~16s 左右,是 shell HRM 热更新时间的 4~6x。这导致开发体验比较差,开发效率降低。

启动:

~/Development/WorkSpace/fox/fox-admin-ui master
❯ pnpm run start

> [email protected] start /Users/cheng/Development/WorkSpace/fox/fox-admin-ui
> pnpm --parallel --filter @app/* run start

Scope: 2 of 5 workspace projects
apps/admin start$ modern start
apps/shell start$ modern start
apps/admin start:   Modern.js Framework v2.60.1
apps/admin start: process.env.ADMIN_MF_URL =======>  http://localhost:3001
apps/admin start: process.env.API_BASE_URL =======>  undefined
apps/admin start: process.env.NODE_ENV ------>  development
apps/admin start: process.env.ADMIN_MF_URL =======>  http://localhost:3001
apps/admin start: process.env.API_BASE_URL =======>  undefined
apps/admin start: process.env.NODE_ENV ------>  development
apps/shell start:   Modern.js Framework v2.60.1
apps/shell start: process.env.ADMIN_MF_URL =======>  http://localhost:3001
apps/shell start: process.env.API_BASE_URL =======>  undefined
apps/shell start: process.env.NODE_ENV ------>  development
apps/admin start: <<<<<<<<<<<<< default bridgeRouterAlias >>>>>>>>>>>>> {
apps/admin start:   'react-router-dom$': '@module-federation/bridge-react/dist/router-v6.es.js'
apps/admin start: }
apps/admin start: start   Compiling...
apps/shell start: <<<<<<<<<<<<< default bridgeRouterAlias >>>>>>>>>>>>> {
apps/shell start:   'react-router-dom$': '@module-federation/bridge-react/dist/router-v6.es.js'
apps/shell start: }
apps/shell start: start   Compiling...
apps/shell start: [ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3000/mf-manifest.json
apps/shell start: ready   Compiled in 5.47 s (web)
apps/shell start:   > Local:    http://localhost:3000/
apps/shell start:   > Network:  http://172.16.39.172:3000/
apps/admin start: Unable to compile federated types, Error: compile TS failed, the original command is 'npx tsc --project /Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/node_modules/.federation/tsconfig.b7d6233d2c0495b724d79c9d613a94f8.json'
apps/admin start: Error: ENOENT: no such file or directory, open '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start:     at Object.openSync (node:fs:573:18)
apps/admin start:     at Object.readFileSync (node:fs:452:35)
apps/admin start:     at _GenerateTypesPlugin.<anonymous> (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:2525:140)
apps/admin start:     at Generator.next (<anonymous>)
apps/admin start:     at fulfilled (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:66:24)
apps/admin start:     at processTicksAndRejections (node:internal/process/task_queues:95:5) {
apps/admin start:   errno: -2,
apps/admin start:   code: 'ENOENT',
apps/admin start:   syscall: 'open',
apps/admin start:   path: '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start: }
apps/admin start: [ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3001/mf-manifest.json
apps/admin start: ready   Compiled in 14.4 s (web)
apps/admin start:   > Local:    http://localhost:3001/
apps/admin start:   > Network:  http://172.16.39.172:3001/
apps/shell start: Federated types extraction completed

更新 admin 应用代码之后的 Log,我只是做了个删除操作,热更新用了 7s+:

apps/admin start: start   Compiling...
apps/admin start: Unable to compile federated types, Error: compile TS failed, the original command is 'npx tsc --project /Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/node_modules/.federation/tsconfig.b7d6233d2c0495b724d79c9d613a94f8.json'
apps/admin start: Error: ENOENT: no such file or directory, open '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start:     at Object.openSync (node:fs:573:18)
apps/admin start:     at Object.readFileSync (node:fs:452:35)
apps/admin start:     at _GenerateTypesPlugin.<anonymous> (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:2525:140)
apps/admin start:     at Generator.next (<anonymous>)
apps/admin start:     at fulfilled (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:66:24)
apps/admin start:     at processTicksAndRejections (node:internal/process/task_queues:95:5) {
apps/admin start:   errno: -2,
apps/admin start:   code: 'ENOENT',
apps/admin start:   syscall: 'open',
apps/admin start:   path: '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start: }
apps/admin start: [ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3001/mf-manifest.json
apps/admin start: ready   Compiled in 6.69 s (web)
apps/admin start: start   Compiling...
apps/admin start: Unable to compile federated types, Error: compile TS failed, the original command is 'npx tsc --project /Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/node_modules/.federation/tsconfig.b7d6233d2c0495b724d79c9d613a94f8.json'
apps/admin start: Error: ENOENT: no such file or directory, open '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start:     at Object.openSync (node:fs:573:18)
apps/admin start:     at Object.readFileSync (node:fs:452:35)
apps/admin start:     at _GenerateTypesPlugin.<anonymous> (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:2525:140)
apps/admin start:     at Generator.next (<anonymous>)
apps/admin start:     at fulfilled (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:66:24)
apps/admin start:     at processTicksAndRejections (node:internal/process/task_queues:95:5) {
apps/admin start:   errno: -2,
apps/admin start:   code: 'ENOENT',
apps/admin start:   syscall: 'open',
apps/admin start:   path: '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
apps/admin start: }
apps/admin start: [ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3001/mf-manifest.json
apps/admin start: ready   Compiled in 7.05 s (web)
  1. 我以为 cd apps/admin 进入 admin 子应用单独启动开发 modern dev 会恢复正常体验变得比较快,但事实上并没有。甚至在启动时 sealing asset processing 这一步骤会花费数分钟才能正常启动。

请看以第二种方式 cd 进去 apps/admin 后 run dev 的 bash 执行日志:

~/Development/WorkSpace/fox/fox-admin-ui/apps/admin feature_exe_data_20241122* 8s
❯ yarn run dev
yarn run v1.22.22
$ modern dev
  Modern.js Framework v2.60.1

process.env.ADMIN_MF_URL =======>  http://localhost:3001
process.env.API_BASE_URL =======>  undefined
process.env.NODE_ENV ------>  development
process.env.ADMIN_MF_URL =======>  http://localhost:3001
process.env.API_BASE_URL =======>  undefined
process.env.NODE_ENV ------>  development
<<<<<<<<<<<<< default bridgeRouterAlias >>>>>>>>>>>>> {
  'react-router-dom$': '@module-federation/bridge-react/dist/router-v6.es.js'
}
start   Compiling...
● web ━━━━━━━━━━━━━━━━━━━━━━━━━ (70%) sealing asset processing

sealing asset processing 这个步骤执行了很久 7 分钟以后报下列错误后才正常启动:

Unable to compile federated types, Error: compile TS failed, the original command is 'npx tsc --project /Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/node_modules/.federation/tsconfig.b7d6233d2c0495b724d79c9d613a94f8.json'
Error: ENOENT: no such file or directory, open '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
    at Object.openSync (node:fs:573:18)
    at Object.readFileSync (node:fs:452:35)
    at _GenerateTypesPlugin.<anonymous> (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:2525:140)
    at Generator.next (<anonymous>)
    at fulfilled (/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/node_modules/.pnpm/@[email protected][email protected]/node_modules/@module-federation/dts-plugin/dist/index.js:66:24)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  errno: -2,
  code: 'ENOENT',
  syscall: 'open',
  path: '/Users/cheng/Development/WorkSpace/fox/fox-admin-ui/apps/admin/dist/@mf-types.zip'
}
[ Module Federation Manifest Plugin ] Manifest Link: http://localhost:3001/mf-manifest.json
● web ━━━━━━━━━━━━━━━━━━━━━━━━━ (100%) emitting after emit                                                                                                   ready   Compiled in 7.46 m (web)

  > Local:    http://localhost:3001/
  > Network:  http://172.16.39.172:3001/

MF 配置

shell:

import { createModuleFederationConfig } from '@module-federation/modern-js';
/* import {
  NAME as appAdminName,
  REMOTE_URL as appAdminUrl,
} from '../admin_3001/modern.config'; */
import { dependencies } from './package.json';

const singleton = { singleton: true };

export default createModuleFederationConfig({
  name: 'app_shell',
  remotes: {
    app_admin: `app_admin@${process.env.ADMIN_MF_URL}/mf-manifest.json`,
  },
  shared: {
    '@fox-ui/shared': singleton,
    '@fox-ui/runtime': singleton,
    react: { ...singleton, requiredVersion: dependencies.react },
    'react-dom': { ...singleton, requiredVersion: dependencies['react-dom'] },
    i18next: singleton,
    'react-i18next': singleton,
    dayjs: { ...singleton, requiredVersion: dependencies.dayjs },
    antd: { ...singleton, requiredVersion: dependencies.antd },
    '@ant-design/icons': {
      ...singleton,
      requiredVersion: dependencies['@ant-design/icons'],
    },
    '@ant-design/pro-components': singleton,
  },
});

admin:

import { createModuleFederationConfig } from '@module-federation/modern-js';
/* import {
  NAME as appName,
  REMOTE_URL as appRemoteUrl,
} from '../shell_3000/modern.config'; */
import { NAME } from './modern.config';
import { dependencies } from './package.json';

const singleton = { singleton: true };

export default createModuleFederationConfig({
  name: NAME,
  exposes: {
    './MicroApp': './src/MicroApp.tsx',
  },
  /* remotes: {
    [appName]: `${appName}@${appRemoteUrl}/mf-manifest.json`,
  }, */
  shared: {
    '@fox-ui/shared': singleton,
    '@fox-ui/runtime': singleton,
    react: { ...singleton, requiredVersion: dependencies.react },
    'react-dom': { ...singleton, requiredVersion: dependencies['react-dom'] },
    i18next: singleton,
    'react-i18next': singleton,
    // dayjs: { ...singleton, requiredVersion: dependencies.dayjs },
    antd: singleton,
    '@ant-design/icons': {
      ...singleton,
      requiredVersion: dependencies['@ant-design/icons'],
    },
    '@ant-design/pro-components': singleton,
  },
});

复现链接

暂无

复现步骤

我猜想这跟 MF Server 的模块类型下载有关,但并未深入查看源码。当然,我期望是它能跟 native RSPack 甚至 Boundless-like 的 Vite dev server 一样快。

如此的话,Modern.js 便是真的 Modern JavaScript 了。

谢谢,有时间的话,我会看一下相关源码的。

@cheng4kn cheng4kn added the bug Something isn't working label Nov 25, 2024
@KyrieLii
Copy link
Member

KyrieLii commented Dec 4, 2024

@cheng4kn 需要给个 demo 项目复现下,应该先看下类型编译报错的问题

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants