Conceptos de monoreo, consejos y trucos orientados alrededor de Nextjs
Howtos para Monorepo. ¿Nuevo en Monorepos? Revise estas preguntas frecuentes. Este ejemplo se gestiona por Turborepo e Yarn 4 con un enfoque de alias de ruta A / TypeScript. No es la única forma de hacerlo.
Útil para
Si está disfrutando de algunos de mis trabajos de OSS en su empresa, realmente agradecería un patrocinio, un café o una estrella caída. Eso me da más tiempo para mejorarlo al siguiente nivel.
| Rejilla | Embie.be | Velo |
corepack enable
yarn install .
├── apps
│ ├── nextjs-app (i18n, ssr, api, vitest)
│ └── vite-app
└── packages
├── common-i18n (locales...)
├── core-lib
├── db-main-prisma
├── eslint-config-bases (to shared eslint configs)
└── ui-lib (emotion, storybook)
Las aplicaciones no deben depender de las aplicaciones, pueden depender de los paquetes
Las aplicaciones pueden depender de los paquetes, los paquetes pueden depender de los demás ...
.
├── apps
│ ├── vite-app (Vite app as an example)
│ │ ├── src/
│ │ ├── package.json (define package workspace:package deps)
│ │ └── tsconfig.json (define path to packages)
│ │
│ └── nextjs-app (NextJS app with api-routes)
│ ├── e2e/ (E2E tests with playwright)
│ ├── public/
│ ├── src/
│ │ └── pages/api (api routes)
│ ├── CHANGELOG.md
│ ├── next.config.mjs
│ ├── package.json (define package workspace:package deps)
│ ├── tsconfig.json (define path to packages)
│ └── vitest.config.ts
│
├── packages
│ ├── core-lib (basic ts libs)
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── db-main-prisma (basic db layer with prisma)
│ │ ├── e2e/ (E2E tests)
│ │ ├── prisma/
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ ├── eslint-config-bases
│ │ ├── src/
│ │ ├── CHANGELOG.md
│ │ ├── package.json
│ │ └── tsconfig.json
│ │
│ └── ui-lib (basic design-system in react)
│ ├── src/
│ ├── CHANGELOG.md
│ ├── package.json
│ └── tsconfig.json
│
├── static (no code: images, json, locales,...)
│ ├── assets
│ └── locales
├── docker (docker...)
│ ├── .dockerignore
│ ├── docker-compose.yml (compose specific for nextjs-app)
│ ├── docker-compose.db.yml (general services like postgresql...)
│ └── Dockerfile (multistage build for nextjs-app)
├── .yarnrc.yml
├── package.json (the workspace config)
└── tsconfig.base.json (base typescript config)
{
"name" : "nextjs-monorepo-example" ,
// Set the directories where your apps, packages will be placed
"workspaces" : [ "apps/*" , "packages/*" ] ,
//...
} El Administrador de paquetes escaneará esos directorios y buscará package.json para niños. Su contenido se utiliza para definir la topología del espacio de trabajo (aplicaciones, libs, dependencias ...).
Cree una carpeta en ./Packages/ Directorio con el nombre de su paquete.
mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poneyInicialice un paquete.json con el nombre de su paquete.
En lugar de escribir
yarn init, prefiero tomar el ./packages/ui-lib/package.json como ejemplo de trabajo y editar sus valores.
{
"name" : "@your-org/magnificent-poney" ,
"version" : "0.0.0" ,
"private" : true ,
"scripts" : {
"clean" : "rimraf ./tsconfig.tsbuildinfo" ,
"lint" : "eslint . --ext .ts,.tsx,.js,.jsx" ,
"typecheck" : "tsc --project ./tsconfig.json --noEmit" ,
"test" : "run-s 'test:*'" ,
"test:unit" : "echo "No tests yet"" ,
"fix:staged-files" : "lint-staged --allow-empty" ,
"fix:all-files" : "eslint . --ext .ts,.tsx,.js,.jsx --fix" ,
} ,
"devDependencies" : {
"@your-org/eslint-config-bases" : "workspace:^" ,
} ,
}Primero agregue el paquete al paquete de aplicaciones.json. La forma recomendada es utilizar el protocolo de espacio de trabajo compatible con HILA y PNPM.
cd apps/my-app
yarn add @your-org/magnificent-poney@ ' workspace:^ 'La inspiración se puede encontrar en Apps/NextJS-App/Package.json.
{
"name" : "my-app" ,
"dependencies" : {
"@your-org/magnificient-poney" : "workspace:^" ,
} ,
} Luego agregue un alias de ruta TypeScript en la aplicación tsconfig.json. Esto le permitirá importarlo directamente (no se necesita compilación)
La inspiración se puede encontrar en Apps/NextJS-App/tsconfig.json.
{
"compilerOptions" : {
"baseUrl" : "./src" ,
"paths" : {
// regular app aliases
"@/components/*" : [ "./components/*" ] ,
// packages aliases, relative to app_directory/baseUrl
"@your-org/magnificent-poney/*" : [
"../../../packages/magnificent-poney/src/*" ,
] ,
"@your-org/magnificent-poney" : [
"../../../packages/magnificent-poney/src/index" ,
] ,
} ,
} ,
}PD:
- No intente establecer alias en el global tsonfig.base.json para mantenerse estricto con las dependencias de gráficos.
- La estrella en
@your-org/magnificent-poney/*le permite importar subcarpetas. Si usa un archivo de barril (index.ts), se puede eliminar el alias con STAR.
Edite su next.config.mjs y habilite la opción Experimental.Externaldir. Comentarios aquí.
const nextConfig = {
experimental : {
externalDir : true ,
} ,
} ;Si está utilizando una versión NextJS anterior y no tiene el indicador experimental, simplemente puede anular su configuración de Webpack.
const nextConfig = {
webpack : ( config , { defaultLoaders } ) => {
// Will allow transpilation of shared packages through tsonfig paths
// @link https://github.com/vercel/next.js/pull/13542
const resolvedBaseUrl = path . resolve ( config . context , "../../" ) ;
config . module . rules = [
... config . module . rules ,
{
test : / .(tsx|ts|js|jsx|json)$ / ,
include : [ resolvedBaseUrl ] ,
use : defaultLoaders . babel ,
exclude : ( excludePath ) => {
return / node_modules / . test ( excludePath ) ;
} ,
} ,
] ;
return config ;
} ,
} ;PD: Si su paquete compartido hace uso de SCSS Bundler ... una configuración de Webpack personalizada será necesaria o usará los próximos modules de transpiles, consulte las preguntas frecuentes a continuación.
Los paquetes ahora están vinculados a su aplicación, solo importarlos como paquetes regulares: import { poney } from '@your-org/magnificent-poney' .
Opcional
Si necesita compartir algunos paquetes fuera del Monorepo, puede publicarlos en NPM o repositorios privados. Un ejemplo basado en Microbundle está presente en cada paquete. El verso y la publicación se pueden hacer con Atlassian/Changset, y es simple como escribir:
$ yarn g:changesetSiga las instrucciones ... y confirme el archivo ChogingET. Aparecerá un "paquetes de versión" P/R después de las verificaciones de CI. Al fusionarlo, una acción de GitHub publicará los paquetes con la versión de Semver resultante y generará Changelogs para usted.
PD:
- Incluso si no necesita publicar, ChangesET puede mantener un cambio de cambio automatizado para sus aplicaciones. Lindo !
- Para deshabilitar la publicación automática de algunos paquetes, simplemente establezca
"private": "true"en su paquete.json.- Quiere sintonizar el comportamiento, ver .Changeset/config.json.
Algunos scripts de conveniencia se pueden ejecutar en cualquier carpeta de este repositorio y llamarán a sus homólogos definidos en paquetes y aplicaciones.
| Nombre | Descripción |
|---|---|
yarn g:changeset | Agregue un conjunto de cambios para declarar una nueva versión |
yarn g:codegen | Ejecutar Codegen en todos los espacios de trabajo |
yarn g:typecheck | Ejecutar typechecks en todos los espacios de trabajo |
yarn g:lint | Mostrar problemas de los deladores en todos los espacios de trabajo |
yarn g:lint --fix | Intente ejecutar el servicio automático de Linter en todos los espacios de trabajo |
yarn g:lint-styles | Mostrar problemas de CSS Stylelint en todos los espacios de trabajo |
yarn g:lint-styles --fix | Intente ejecutar problemas de stylelint auto-fijado en todos los espacios de trabajo |
yarn g:test | Ejecutar pruebas de unidad y E2E en todos los espacios de trabajo |
yarn g:test-unit | Ejecutar pruebas unitarias en todos los espacios de trabajo |
yarn g:test-e2e | Ejecutar pruebas E2E en todos los espacios de trabajo |
yarn g:build | Ejecutar la construcción en todos los espacios de trabajo |
yarn g:clean | Clean Builds en todos los espacios de trabajo |
yarn g:check-dist | Asegúrese de que los archivos DIST de Build pasen ES2017 (ejecute g:build primero). |
yarn g:check-size | Asegúrese de que los archivos DIST del navegador estén dentro del límite de tamaño (ejecute g:build primero). |
yarn clean:global-cache | Limpiar en cachés de herramientas (eslint, broma ...) |
yarn deps:check --dep dev | Imprimirá qué paquetes se pueden actualizar a nivel mundial (ver también .ncurc.yml) |
yarn deps:update --dep dev | Aplicar posibles actualizaciones (ejecutar yarn install && yarn dedupe después) |
yarn install:playwright | Instalar dramaturgo para e2e |
yarn dedupe | Deduplicación del hilo incorporado del archivo de bloqueo |
¿Por qué usar
:para prefijo los nombres de scripts? Es conveniente en el hilo 3+, podemos llamar a esos scripts desde cualquier carpeta del monorepo.g:es un atajo paraglobal:. Vea la lista completa en Root Package.json.
El Global Commands yarn deps:check and yarn deps:update ayudará a mantener las mismas versiones en todo el Monorepo. Se basan en las excelentes actualizaciones de NPM-Check (ver opciones, es decir: yarn check:deps -t minor ).
Después de ejecutar
yarn deps:update, se requiere unayarn install. Para evitar tener duplicados en el yarn.lock, puede ejecutaryarn dedupe --checkyyarn dedupepara aplicar la deduplicación. La verificación duplicada se aplica en el ejemplo de las acciones de GitHub.
Vea un ejemplo en ./apps/nextjs-app/.eslintrc.js y nuestros bases de config eslint.
Verifique el contenido de la carpeta .husky para ver qué ganchos están habilitados. La pelusa se utiliza para garantizar que la pelusa y los más bonitos se aplican automáticamente en confirmación y/o empujes.
Las pruebas se basan en TS-Jest o Vitest dependiendo de la aplicación. Todas las configuraciones admiten alias de ruta de mecanografiado. React-testing-bibrary está habilitado cuando React está involucrado.
La configuración vive en la carpeta raíz de cada aplicaciones/paquetes. Como ejemplo ver
Encontrará algunos flujos de trabajo de ejemplo para la acción de GitHub en .github/flujos de trabajo. Por defecto, se asegurarán de que
Cada uno de esos pasos se puede excluir.
Para garantizar un rendimiento decente, esas características están presentes en las acciones de ejemplo:
Almacenamiento en caché de paquetes (node_modules ...) - Instale alrededor de 25s
Almacenamiento en caché de la construcción anterior de NextJS - construido alrededor de los 20 años
Desencadenado cuando se cambia usando rutas de acciones, es decir:
paths: - "apps/nextjs-app/**" - "packages/**" - "package.json" - "tsconfig.base.json" - "yarn.lock" - ".yarnrc.yml" - ".github/workflows/**" - ".eslintrc.base.json" - ".eslintignore"
El complemento de Eslint requiere que se establezca la configuración eslint.workingDirectories .
"eslint.workingDirectories": [
{
"pattern": "./apps/*/"
},
{
"pattern": "./packages/*/"
}
],
Más información aquí
VIRCE Support Native Monorepos, consulte el documento VERCEL-MONOREPO-Deploy.
Hay un ejemplo básico para construir una imagen de Docker, lea el docker Doc.
Las recetas de Netlify, AWS-Amplify, K8s-Docker, Serverless-NextJS podrían agregarse en el futuro. Las relaciones públicas también son bienvenidas.
Las dependencias de aplicaciones y las Devdependencias están fijadas a versiones exactas. Paquetes Deps utilizará los compatibles con Semver. Para obtener más información sobre este cambio, consulte el razonamiento aquí y nuestro archivo de configuración Renovabot.json5.
Para ayudar a mantener los Deps actualizados, consulte los yarn deps:check && yarn deps:update los scripts y / o use el RenovateBot.
Al agregar un DEP a través de la CLI del hilo (es decir, el hilo, agregue algo), es posible establecer el comportamiento de ahorro-exacto automáticamente configurando
defaultSemverRangePrefix: ""en yarnrc.yml. Pero esto también sería el valor predeterminado de los paquetes/*. Es mejor manejaryarn add something --exactpor caso.