Skip to content

Comments

feat: enable esm cli runtime#8227

Merged
zllkjc merged 23 commits intoweb-infra-dev:mainfrom
sylingd:feat/esm
Jan 28, 2026
Merged

feat: enable esm cli runtime#8227
zllkjc merged 23 commits intoweb-infra-dev:mainfrom
sylingd:feat/esm

Conversation

@sylingd
Copy link
Contributor

@sylingd sylingd commented Jan 23, 2026

Summary

为modern.js常见包启用esm runtime。在运行modern-js相关cli命令时,于esm项目下默认运行esm产物,非esm项目仍然运行原cjs产物(通过项目package.json中的type判断)

主要修改:

  • solutions/app-tools/bin/modern.js中增加项目类型判断,执行不同入口文件
  • 增加部分包的package.json exports,指向esm产物
  • 修改部分require require.resolve __dirname的使用,以兼容esm运行时
  • 为prebundle引入esm打包逻辑,并重新打包nanoid js-yaml
  • commander lodash tsconfig-paths 包增加esm入口,以兼容相关import语法
  • 重构toolkit/utils/src/cli/require.ts中的逻辑,增加esm运行时环境下的支持
  • 引入新环境变量MODERN_LIB_FORMAT,该环境变量仅用于编译时(不用于运行时),区分打包目标产物是esm还是cjs,以进行适当的tree shaking

Enables ESM runtime for some modern.js packages. When running modern-js CLI commands, ESM artifacts will be run by default in ESM projects, while non-ESM projects will still run the original CJS artifacts (determined by the type in the project's package.json).

Main modifications:

  • Added project type detection in solutions/app-tools/bin/modern.js to execute different entry files.
  • Added exports to the package.json of some packages, pointing to ESM artifacts.
  • Modified the use of require, require.resolve, and __dirname to ensure compatibility with the ESM runtime.
  • Imported ESM bundling logic into prebundles and repackaged the nanoid and js-yaml packages.
  • Added ESM entry points to the commander, lodash, and tsconfig-paths packages to ensure compatibility with related import syntax.
  • Refactored the logic in toolkit/utils/src/cli/require.ts to add support for the ESM runtime environment.
  • A new environment variable MODERN_LIB_FORMAT is introduced. This environment variable is only used at compile time (not at runtime) to distinguish between the packaged target artifacts, e.g., esm or cjs, in order to perform appropriate tree shaking.

Related Links

拆分自 #8097

Checklist

  • I have added changeset via pnpm run change.
  • I have updated the documentation.
  • I have added tests to cover my changes.

@changeset-bot
Copy link

changeset-bot bot commented Jan 23, 2026

🦋 Changeset detected

Latest commit: 2db4bb7

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 110 packages
Name Type
@modern-js/runtime Minor
@modern-js/runtime-utils Minor
@modern-js/plugin-i18n Minor
@modern-js/app-tools Minor
@modern-js/i18n-utils Minor
@modern-js/bff-core Minor
@modern-js/plugin-bff Minor
@modern-js/render Minor
@modern-js/plugin-styled-components Minor
@integration-test/alias-set Patch
app-document Patch
async-entry-test Patch
tmp Patch
bff-api-app Patch
bff-client-app Patch
bff-indep-client-app Patch
bff-hono Patch
integration-clean-dist-path Patch
integration-compatibility Patch
integration-custom-dist-path Patch
custom-file-system-entry Patch
integration-custom-template Patch
deploy Patch
deploy-server Patch
dev-server Patch
integration-disable-html Patch
app-custom-entries Patch
app-custom-routes-runtime Patch
app-custom Patch
app-entry Patch
app-route Patch
app-entry-server Patch
i18n-app-csr-html-lang Patch
i18n-app Patch
i18n-app-ssr-html-lang Patch
i18n-app-ssr Patch
i18n-custom-i18n-wrapper Patch
i18n-mf-app-provider Patch
i18n-mf-component-provider Patch
i18n-mf-consumer Patch
i18n-routes Patch
i18n-routes-ssr Patch
@integration-test/image-component Patch
main-entry-name Patch
nonce Patch
pure-esm-project Patch
routes-match Patch
routes Patch
app-rsbuild-hooks Patch
rsc-csr-app Patch
rsc-csr-routes Patch
rsc-ssr-app Patch
rsc-ssr-routes Patch
runtime-custom-plugin Patch
runtime-custom-config-plugin Patch
select-mul-entry-test Patch
select-one-entry-test Patch
server-config Patch
server-json-script Patch
server-monitors Patch
server-prod Patch
server-routes Patch
@source-code-build/app Patch
ssg-fixtures-mega-list-routes Patch
ssg-fixtures-nested-routes Patch
ssg-fixtures-simple Patch
ssg-fixtures-web-server Patch
ssr-base-async-entry-test Patch
ssr-base-json-test Patch
ssr-base-test Patch
ssr-base-fallback-test Patch
init Patch
ssr-base-loadable Patch
ssr-partial-test Patch
ssr-script-loading Patch
ssr-streaming-inline-test Patch
ssr-streaming-test Patch
styled-components-stream Patch
styled-components-string Patch
integration-tailwindcss-v2 Patch
integration-tailwindcss-v3 Patch
integration-tailwindcss-v4 Patch
tmp-dir Patch
write-to-dist Patch
@modern-js/bundle-diff-benchmark Minor
@modern-js/plugin-data-loader Minor
@modern-js/server-core Minor
@modern-js/create-request Minor
@modern-js/prod-server Minor
@modern-js/server-runtime Minor
@modern-js/server Minor
@modern-js/plugin Minor
@modern-js/plugin-ssg Minor
@modern-js/image Minor
@modern-js/plugin-polyfill Minor
entries-app-builder Patch
@modern-js/create Minor
@modern-js/server-utils Minor
@modern-js/main-doc Minor
@modern-js/tsconfig Minor
@modern-js/builder Minor
@modern-js/flight-server-transform-plugin Minor
@modern-js/bff-runtime Minor
@modern-js/sandpack-react Minor
@modern-js/types Minor
@modern-js/utils Minor
@modern-js/rslib Minor
@scripts/prebundle Patch
@scripts/rstest-config Patch
@scripts/release-node Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@netlify
Copy link

netlify bot commented Jan 23, 2026

Deploy Preview for modernjs-v3 ready!

Name Link
🔨 Latest commit 2db4bb7
🔍 Latest deploy log https://app.netlify.com/projects/modernjs-v3/deploys/6979fa2fe1a87200084ba938
😎 Deploy Preview https://deploy-preview-8227--modernjs-v3.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@zllkjc
Copy link
Member

zllkjc commented Jan 23, 2026

牛,我这两天会看下这个 PR,如果你准备好了可以直接艾特我们。

@zllkjc
Copy link
Member

zllkjc commented Jan 23, 2026

@yimingjfe 也关注一下

@sylingd
Copy link
Contributor Author

sylingd commented Jan 23, 2026

如果你准备好了可以直接艾特我们。

也没什么需要准备的,只是ut的问题还没解决(不太熟悉rstest,希望你们有经验的给点建议)

@zllkjc
Copy link
Member

zllkjc commented Jan 23, 2026

也没什么需要准备的,只是ut的问题还没解决(不太熟悉rstest,希望你们有经验的给点建议)

OK 我来看看,咱们也是最近才接上 rstest

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

我目前完成了整体的 review,这里有几个点我会去新建 PR 并且先合并到 main 中,后续可能需要你做一些冲突解决:

  1. 删除 BFF 包还有一些不需要的功能
  2. 解决 document 的别名问题
  3. builder 包应该迁移到 rslib 打包

另外我还会确认如何处理 Node ESM 和 bundle target node 导出的问题

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

这个 PR 最大的问题是 require.ts 对 import-meta-resolve 的引入,这是一个 ESM only 的模块,这导致项目无法在 Node 20 中启动(除非开启 esm enable)。

Modern.js 需要支持 Node 20,可以帮忙看下 import-meta-resolve 是否有双栈的版本

@sylingd
Copy link
Contributor Author

sylingd commented Jan 27, 2026

这是一个 ESM only 的模块,这导致项目无法在 Node 20 中启动

node 20 可以直接运行esm,不需要加参数吧。只有一个--experimental-require-module参数控制能不能require esm。

而且项目默认还是走cjs产物,只有esm项目会走esm产物。预期中cjs时也不需要去resolve esm,在cjs产物中直接去掉这个包应该就行

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

node 20 可以直接运行esm,不需要加参数吧。只有一个--experimental-require-module参数控制能不能require esm

我理解现在就是非 ESM 项目没法在 20 里启动了,如果不加这个参数的话

@sylingd
Copy link
Contributor Author

sylingd commented Jan 27, 2026

我理解现在就是非 ESM 项目没法在 20 里启动了,如果不加这个参数的话

在solution/app-tools中有判断,非esm项目默认还是走cjs产物,不会有影响吧

@sylingd
Copy link
Contributor Author

sylingd commented Jan 27, 2026

@zllkjc 另外很多packages.json相关的问题,我认为都可以通过合并esm/esm-node来解决。

原先拆分似乎是因为要关掉js redirect。但根据我实际测试,即使打开这个参数也不会影响走server.mjs或者不走的逻辑,因为配置了extensionAlias,有.mjs后缀的时候这个逻辑仍然是生效的。

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

@zllkjc 另外很多packages.json相关的问题,我认为都可以通过合并esm/esm-node来解决。

这个问题我看到了,明天我们讨论一下,评论里已经提到相关同学了

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

目前我已经 resolve 了大部分需要后续 PR 解决的 comment,包括:

  1. 统一 register 处理,不再处理 JS,移除 ESM
  2. esm-node 和 esm 是否可以使用统一产物
  3. 整体梳理一次 exports

其他的内容需要在这个 PR 里解决,例如 deploy 的问题可以帮忙确认一下具体原因。

我这边会着手来查看 rstest 测试 modern:source 的问题。

@sylingd
Copy link
Contributor Author

sylingd commented Jan 27, 2026

Comment里提到的问题我明天会一一确认处理。

例如 deploy 的问题可以帮忙确认一下具体原因。

这个指的是?

@zllkjc
Copy link
Member

zllkjc commented Jan 27, 2026

这个指的是?

一个是
image
一个是副作用的问题

这两个问题我还不是特别理解。

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

我理解现在就是非 ESM 项目没法在 20 里启动了,如果不加这个参数的话

在solution/app-tools中有判断,非esm项目默认还是走cjs产物,不会有影响吧

你试一下就看到了,切到 node 20 随便运行一下集测里的。和 app-tools 里没关系,就是因为走 cjs 了但是这个包是个 pure esm,所以报错了。node 20 不支持默认 require 加载 esm 模块。

image

@sylingd
Copy link
Contributor Author

sylingd commented Jan 28, 2026

image

我试了确实如此,但好像不是我引入的问题,这个是@rsbuild/core从2.0开始就是一个pure esm的包了。ref

image

另外使用较新的node 20(20.19+)是可以正常运行的

image

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

抱歉,我这里截图有误,我没有你的仓库的代码权限,你是否可以再拉取一下 main 分支,然后重新提交下,rsbuild 的问题我在其他 PR 已经修复了。这个分支之前存在一个由于 import-meta-resolve 导致的错误。

@sylingd
Copy link
Contributor Author

sylingd commented Jan 28, 2026

这个分支之前存在一个由于 import-meta-resolve 导致的错误。

可能是之前cjs产物没有去掉 import-meta-resolve 导致的,我在后面改了

image

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

这个分支之前存在一个由于 import-meta-resolve 导致的错误。

可能是之前cjs产物没有去掉 import-meta-resolve 导致的,我在后面改了

好的,我拉到本地再验证一下。

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

可以给我一个你仓库的权限吗,这样我可以直接修改一些因为其他 PR 导致的报错

@sylingd
Copy link
Contributor Author

sylingd commented Jan 28, 2026

可以给我一个你仓库的权限吗,这样我可以直接修改一些因为其他 PR 导致的报错

done

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

目前看起来没有其他问题了,我可以将它合入,你看还有其他需要改动的点吗~

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

辛苦把 PR Title 和 PR 的 Summary 重新整理一下,方便其他开发者理解~

@sylingd
Copy link
Contributor Author

sylingd commented Jan 28, 2026

目前看起来没有其他问题了,我可以将它合入,你看还有其他需要改动的点吗~

这个PR我没啥要改的了,你们觉得合适了可以随时merge

@zllkjc
Copy link
Member

zllkjc commented Jan 28, 2026

  1. 统一 register 处理,不再处理 JS,移除 ESM
  2. esm-node 和 esm 是否可以使用统一产物
  3. 整体梳理一次 exports

后续我将基于这个 PR 做上述这些优化~

再次感谢小伙伴对 Modern.js 的贡献!

@sylingd sylingd changed the title feat: esm runtime feat: enable esm cli runtime Jan 28, 2026
@zllkjc zllkjc merged commit ecd247c into web-infra-dev:main Jan 28, 2026
10 checks passed
This was referenced Jan 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants