我应该使用commonjs或es模块为yarn工作空间子包next.js项目?



我正在用TS, yarn工作空间构建Next.js单线程项目。

例如,我在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模块包一起工作没有任何问题。我是不是误解了什么?

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"在配置…但是正如你注意到的,我意识到一些esm包,比如"@sindrehorsus",在没有实验标志的情况下工作。

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

请注意,通常我倾向于设置"模块";esnext"而不是&;es6&;

PS:如果它有帮助,你可以看看这个评论:https://stackoverflow.com/a/69554480/5490184或https://github.com/belgattitude/nextjs-monorepo-example。

相关内容

  • 没有找到相关文章

最新更新