Skip to content

[Bug]: loadShare virtual module contains top-level await, causing REQUIRE_TLA error with Rolldown when CJS packages require shared modules #659

@NewCoder798

Description

@NewCoder798

Describe the bug

在 @module-federation/vite 1.14.3+ 中,loadShare 虚拟模块包含 top-level await。当第三方 CJS 包(如 @vue-office/*、vue-demi)通过 require('vue') 引用时,在 Vite 8.0.9+(Rolldown 1.0.0-rc.16+)下会报 REQUIRE_TLA 错误

环境:Vite 8.0.10, Rolldown 1.0.0-rc.17, @module-federation/vite 1.14.5
临时解决:用 resolve.alias 强制指向 ESM 入口可以临时绕过

Describe the bug

Since @module-federation/vite 1.14.3 (which introduced a fix for "race
condition with missing await"), the virtual module generated for loadShare
contains a top-level await. When a third-party CJS package (e.g.
@vue-office/docx, vue-demi) uses require('vue') to load the shared
module, this triggers a REQUIRE_TLA error in Rolldown (Vite 8.0.9+ /
Rolldown 1.0.0-rc.16+).

This is not a Rolldown bug — Rolldown intentionally disallows require()
loading TLA modules
(rolldown/rolldown#9071).
However, it creates a compatibility issue where any CJS package depending on a
shared module will fail to build.

Reproduction

  1. Create a Vite 8 project with @module-federation/vite
  2. Share vue via shared: { vue: { singleton: true } }
  3. Install a CJS-only package that does require('vue') (e.g.
    @vue-office/docx@1.6.3)
  4. Run vite build

System Info

Vite: 8.0.10
Rolldown: 1.0.0-rc.17
@module-federation/vite: 1.14.5
Node: 20.x

Error output

[REQUIRE_TLA] Error: This require call is not allowed because the imported
file
"node_modules/__mf__virtual/__mfe_internal__xxx__loadShare__vue__loadShare__.m
js"
contains a top-level await

Expected behavior

CJS packages that require() a shared module should be able to build
successfully, or there should be a documented way to make shared modules
CJS-compatible in Rolldown builds.

Workaround

Force the CJS packages to use their ESM build via resolve.alias in
vite.config.ts:

resolve: {
  alias: [
    { find: /^@vue-office\/docx\/lib\/(.*)$/, replacement:
'@vue-office/docx/lib/v3/$1' },
    { find: /^@vue-office\/excel\/lib\/(.*)$/, replacement:
'@vue-office/excel/lib/v3/$1' },
    { find: /^@vue-office\/pdf\/lib\/(.*)$/, replacement:
'@vue-office/pdf/lib/v3/$1' },
    { find: '@vue-office/docx', replacement:
'@vue-office/docx/lib/v3/vue-office-docx.mjs' },
    { find: '@vue-office/excel', replacement:
'@vue-office/excel/lib/v3/vue-office-excel.mjs' },
    { find: '@vue-office/pdf', replacement:
'@vue-office/pdf/lib/v3/vue-office-pdf.mjs' },
  ]
}

EOF)
⎿  ### Describe the bug

 Since `@module-federation/vite 1.14.3` (which introduced a fix for "race
 condition with missing await"), the virtual module generated for
 `loadShare` contains a top-level await. When a third-party CJS package
 (e.g. `@vue-office/docx`, `vue-demi`) uses `require('vue')` to load the
 shared module, this triggers a `REQUIRE_TLA` error in Rolldown (Vite 8.0.9+
  / Rolldown 1.0.0-rc.16+).

 This is not a Rolldown bug — Rolldown intentionally disallows `require()`
 loading TLA modules
 ([rolldown/rolldown#9071](https://github.com/rolldown/rolldown/pull/9071)).
  However, it creates a compatibility issue where any CJS package depending
 on a shared module will fail to build.

 ### Reproduction

 1. Create a Vite 8 project with `@module-federation/vite`
 2. Share `vue` via `shared: { vue: { singleton: true } }`
 3. Install a CJS-only package that does `require('vue')` (e.g.
 `@vue-office/docx@1.6.3`)
 4. Run `vite build`

 ### System Info

 ```
 Vite: 8.0.10
 Rolldown: 1.0.0-rc.17
 @module-federation/vite: 1.14.5
 Node: 20.x
 ```

 ### Error output

 ```
 [REQUIRE_TLA] Error: This require call is not allowed because the imported
 file
 "node_modules/__mf__virtual/__mfe_internal__xxx__loadShare__vue__loadShare_
 _.mjs"
 contains a top-level await
 ```

 ### Expected behavior

 CJS packages that `require()` a shared module should be able to build
 successfully, or there should be a documented way to make shared modules
 CJS-compatible in Rolldown builds.

 ### Workaround

 Force the CJS packages to use their ESM build via `resolve.alias` in
 `vite.config.ts`:

 ```ts
 resolve: {
   alias: [
     { find: /^@vue-office\/docx\/lib\/(.*)$/, replacement:
 '@vue-office/docx/lib/v3/$1' },
     { find: /^@vue-office\/excel\/lib\/(.*)$/, replacement:
 '@vue-office/excel/lib/v3/$1' },
     { find: /^@vue-office\/pdf\/lib\/(.*)$/, replacement:
 '@vue-office/pdf/lib/v3/$1' },
     { find: '@vue-office/docx', replacement:
 '@vue-office/docx/lib/v3/vue-office-docx.mjs' },
     { find: '@vue-office/excel', replacement:
 '@vue-office/excel/lib/v3/vue-office-excel.mjs' },
     { find: '@vue-office/pdf', replacement:
 '@vue-office/pdf/lib/v3/vue-office-pdf.mjs' },
   ]
 }
 ```

Version

1.14.5

Reproduction

暂无

Relevant log output

Validations

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions