首页 > 解决方案 > 对于 next.js proejct 的纱线工作区子包,我应该使用 commonjs 还是 es 模块?

问题描述

我正在使用 TS、yarn 工作区构建 Next.js monorepo 项目。

例如,我在 yarn 工作区中有两个包,/web并且/api. /web是一个 next.js 项目,/api是一个由/web.

/my-project  <-- project root
  package.json
  /web
    src/
    package.json
    tsconfig.json
    next.config.js
  /api
    src/  <-- rootDir 
    dist/  <--  outDir
    package.json
    tsconfig.json
  ...
// /my-project/package.json
{
  "private": true,
  "workspaces": [
    "web",
    "api"
  ],
}
// /web/packcage.json
{
  "dependencies": {
    "@api": "workspace:*"
  }
}
// /api/packcage.json
{ 
  "name": "@api"
  "version": "1.0.0",
  "main": "dist/index.js",
  "types": "dist/index.d.ts",
}
// /api/tsconfing.json
{
  "compilerOptions": {
    "outDir": "dist",
    "rootDir": "src",
    "module": "ES6",
    "moduleResolution": "node",
    "target": "ES6",
  },
}

/api的 tsconfig 中,TS 创建具有 es6 模块系统的转译结果。( "module": "ES6")

由于 nextjs 不支持使用 ES 模块构建的外部包,我预计该包在项目/api中不起作用。/web但是,它运作良好。

为什么这可能?

当我尝试使用一些使用 ES 模块的包(仅为浏览器构建)时,我遇到了一些类似unexpected token: export. 当时,我必须通过使用手动转换它们next-transpile-modules,然后它解决了这个问题。但是,在这种情况下,nextjs 与 es 模块包一起使用没有任何问题。我对这件事有误解吗?

标签: node.jstypescriptnext.jsyarn-workspaces

解决方案


NextJs 11.1+ 有一个支持 esm 的实验选项。反馈线程可在此处获得。

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  experimental: {
    // Prefer loading of ES Modules over CommonJS
    // @link {https://nextjs.org/blog/next-11-1#es-modules-support|Blog 11.1.0}
    // @link {https://github.com/vercel/next.js/discussions/27876|Discussion}
    esmExternals: true,
    // Experimental monorepo support
    // @link {https://github.com/vercel/next.js/pull/22867|Original PR}
    // @link {https://github.com/vercel/next.js/discussions/26420|Discussion}
    externalDir: true,
  }
}
export default nextConfig;

ESM 通常需要的不仅仅是配置中的“模块”:“es6”......但正如你所注意到的,我意识到一些像“@sindrehorsus”这样的 esm 包在没有实验标志的情况下工作。

也就是说,将 experimental.esmExternals 设置为 true 将解决大多数边缘情况,并且应该使 next-transpile-modules 过时。

请注意,通常我倾向于将“模块”设置为“esnext”而不是“es6”,以便与 nextjs 推荐的内容内联。

PS:如果有帮助,您可以查看以下评论​​:https ://stackoverflow.com/a/69554480/5490184或https://github.com/belgattitude/nextjs-monorepo-example


推荐阅读