[英]How to start next.js app with pm2 in cluster mode using Yarn?
[英]Using next.js with yarn workspaces
今天遇到了这样的项目结构的复杂问题
packages
/app
pages/
package.json
/ui-kit
pages/
package.json
/shared
.babelrc
package.json
root lvl package json 定义了workspaces: [packages/*]
其中app
和ui-kit
都是 nextjs 应用程序。
我在 root lvl package.json 中有以下脚本
"dev:app": "next packages/app",
"dev:ui-kit": "next packages/ui-kit"
在我引入shared
文件夹之前,这两个都运行良好, shared
文件夹本质上包含一些功能/组件等......在包之间重复使用。 一旦我将它包含到app
或ui-kit
我就会收到这样的错误
在 ./packages/shared/index.js
模块解析失败:意外标记 (4:21) 您可能需要一个合适的加载程序来处理此文件类型。 | 从“反应”导入反应 | | export default () => 你好,共享! |
所以看起来 nextjs 没有将任何加载器应用于它指向的文件夹之外的任何东西。 有没有办法以某种方式解决这个问题? 即从根文件夹开始,但根据不同的脚本命令以某种方式将其指向不同的入口文件?
问题是下一个文件夹之外的代码没有被 Babel 转译。 这是因为.babelrc
文件没有被考虑在内,即使它位于代码的根目录。
但是,如果您改为使用babel.config.js
文件(从 Babel 版本 7 开始推荐)并将其放在代码的根目录(有效替换.babelrc
文件),您可以使用此插件:
https://github.com/josephluck/next-plugin-custom-babel-config
我已经做到了,而且效果很好!
对于 Next.js 9.2+, 这个其他答案对我不起作用。 我不得不使用一个名为next-transpile-modules的分叉包。
你真正需要做的就是yarn add next-transpile-modules
到每个包中,然后添加/编辑next.config.js
,如下所示:
// next.config.js
const withTM = require('next-transpile-modules')(['somemodule', 'and-another']); // pass the modules you would like to see transpiled
module.exports = withTM();
如果您想使用 Next.js 默认值,您甚至可能不再需要将babel.config.js
放入根目录。
包的工作方式是通过实现自定义 Webpack 配置, 如官方文档中所述,告诉 webpack 监视您在上面的next.config.js
定义的模块的目录。
尝试将其添加到 next.config.js 以启用下一个根文件夹之外的编译打字稿文件:
module.exports = {
// ... other settings
experimental: {
externalDir: true,
},
}
归功于: https : //github.com/belgattitude/nextjs-monorepo-example#step-33-next-config
从NextJs 11 开始,有一个名为externalDir的新实验选项,它运行良好并且不需要使用 next-transpile-modules。
为了清楚起见,让我们一步一步地说明,这可能看起来是一个漫长的过程,但是一旦你掌握了它,它就非常简单(实际上 3 个步骤)
为了改善体验,我建议将yarn升级到 v3+ ( yarn set version 3.0.2 && yarn plugin import workspace-tools
)并编辑生成的配置.yarnrc.yml
类似于这个:
# Yarn 2+ supports pnp or regular node_modules installs. Use node-modules one.
nodeLinker: node-modules
nmMode: hardlinks-local
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs
spec: "@yarnpkg/plugin-workspace-tools"
yarnPath: .yarn/releases/yarn-3.0.2.cjs
PS:您可能也想将此添加到.gitignore
.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*
为什么 ? 因为您将有可能使用工作区:别名协议。 (也可在 pnpm 中使用)
我建议严格限制包依赖的内容(要有明确的界限)。 这不是一个绝对的要求,而是一个很好的做法,可以避免难以调试的情况。
为了帮助包管理器,我建议正确声明每个应用程序/包的依赖项及其边界。
换句话说,每个包/应用程序都有自己的 package.json,您可以在其中明确添加他们需要的 deps(不在根 package.json 中)
按照你的例子,
apps/
packages
/app
package.json (app depend on ui-kit through yarn workspace: alias)
tsconfig.json (we will add typescript path aliases there too)
next.config.js
/ui-kit
package.json
package.json (do not put nextjs as dep here, only in app)
根package.json
的示例
{
"name": "monorepo",
"private": true,
"workspaces": [
"packages/*" // Enable package discovery in packages/* directory.
],
"devDependencies": {
"husky": "7.0.2", // Only what's needed for monorepo management
}
packages/app/package.json
的示例
{
"name": "my-app",
"devDependencies": {
"@types/node": "16.10.1",
"@types/react": "17.0.29",
"@types/react-dom": "17.0.9",
"typescript": "4.4.4"
},
"dependencies": {
// Assuming the name of packages/ui-kit is ui-kit,
// we explicitly declare the dependency on it through
// workspace: alias (package-manager perspective)
"ui-kit": "workspace:*",
"next": "11.1.2",
"react": "17.0.2",
"react-dom": "17.0.2",
}
}
为什么 ? 这样你就不会陷入与 deps 冲突的奇怪问题。
即使你没有使用 typescript,NextJs 也会读取tsconfig.json
并寻找tsconfig.json
路径映射配置。 如果您不知道它是什么......它只是一种配置,您可以在其中声明(再一次)您的 deps。 Nextjs 会将它们转换为它在引擎盖下使用的内容来编译 deps(即: babel-plugin-module-resolver和可能后来的 swc)。
按照您的示例,只需以这种方式编辑./packages/app/tsconfig.json
{
"compilerOptions": {
// here baseUrl is set at ./src (good practive), can
// be set to '.'
"baseUrl": "./src",
"paths": {
// Declare deps here (keep them in sync with what
// you defined in the package.json)
// PS: path are relative to baseUrl
"ui-kit/*": ["../../ui-kit/src/*"],
// if you have a barrel in ui-lib
"ui-kit": ["../../ui-kit/src/index"],
}
},
}
为什么 ? 更多工具之间的限制(包管理器和路径有不同的观点)
在packages/app/nextjs.config.js
,启用externalDir配置(目前处于实验阶段但效果很好,反馈线程在这里)
const nextConfig = {
experimental: {
// this will allow nextjs to resolve files (js, ts, css)
// outside packages/app directory.
externalDir: true,
},
};
export default nextConfig;
PS:对于旧的 nextjs 版本,完全可以通过自定义 webpack 配置来做同样的事情。 问你是否需要一个例子。
在您的应用程序中,您应该能够像这样导入您的 ui-kit:
import { Button } from 'ui-kit';
// or
import Avatar from 'ui-kit/components/Avatar'
它的美妙之处在于快速刷新将开箱即用(无需构建)。 它很快,你不需要 NX(+ 昂贵的 nx.cloud)、匆忙或任何东西......
Nextjs 将简单地导入文件,按需构建它们,甚至将它们缓存在它自己优化的缓存中(尤其是在 webpack 5 中速度更快,也可以在 CI 上启用)...
如果您想了解更多信息,我会在此存储库上维护一个示例存储库,该存储库将提供完整的生命周期透视图(ci、github 操作、linters、部署...): https : //github.com/belgattitude/nextjs-monorepo-example 。
PS:在这里也关注 yarn 3+ 的开发和版本,他们现在做得很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.