Coder Social home page Coder Social logo

belgattitude / nextjs-monorepo-example Goto Github PK

View Code? Open in Web Editor NEW
1.5K 7.0 202.0 289.75 MB

Collection of monorepo tips & tricks

License: MIT License

JavaScript 22.77% TypeScript 72.21% Shell 0.22% Dockerfile 1.31% HTML 0.12% CSS 1.15% Prolog 0.37% MDX 1.85%
monorepo vercel nextjs typescript example tutorial workspace workspaces yarn vite

nextjs-monorepo-example's Introduction

Monorepo concepts, tips and tricks oriented around NextJs

GitHub branch checks state Codefactor Maintainability Techdebt Codacy grade LoC GitHub top language Licence

Howtos for monorepo. New to monorepos ? check this FAQ. This example is managed by Yarn 3.2+ / typescript path aliases. Not the only way to do.

Useful to

  • Establish a structure and present a lifecycle perspective (dx, ci/cd, deployments...)
  • How to create and consume shared packages, locales, assets, api types...
  • Integrate tools & configs (eslint, jest, playwright, storybook, changelogs, versioning, codecov, codeclimate...).
  • Clarify some advantages of monorepos (team cohesion, consistency, duplication, refactorings, atomic commits...).
  • Create nextjs/vercel/prisma... bug reports with reproducible examples (initial goal of this repo).

Sponsors ❤️

If you are enjoying some of my OSS work in your company, I'd really appreciate a sponsorship, a coffee or a dropped star. That gives me some more time to improve it to the next level.

Special thanks to

Jetbrains logo Jetbrains logo Vercel logo
JetBrains Embie.be Vercel

Install

corepack enable
yarn install

Structure

Open in Gitpod

.
├── apps
│   ├── nextjs-app  (i18n, ssr, api, vitest)
│   ├── remix-app   (csr, ssr, api, jest)
│   └── vite-app
└── packages
    ├── common-i18n         (locales...)
    ├── core-lib
    ├── db-main-prisma
    ├── eslint-config-bases (to shared eslint configs)
    └── ui-lib              (emotion, storybook)

Example apps

Apps should not depend on apps, they can depend on packages

Example shared packages

Apps can depend on packages, packages can depend on each others...

Folder overview

Detailed folder structure
.
├── apps
│   ├── remix-app                (Remix.run app as an example)
│   │   ├── app/
│   │   ├── package.json         (define package workspace:package deps)
│   │   └── tsconfig.json        (define path to packages)
│   │
│   ├── 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)

Howto

1. Enable workspace support

Root package.json with workspace directories
{
  "name": "nextjs-monorepo-example",
  // Set the directories where your apps, packages will be placed
  "workspaces": ["apps/*", "packages/*"],
  //...
}

The package manager will scan those directories and look for children package.json. Their content is used to define the workspace topology (apps, libs, dependencies...).

2. Create a new package

Create a folder in ./packages/ directory with the name of your package.

Create the package folder
mkdir packages/magnificent-poney
mkdir packages/magnificent-poney/src
cd packages/magnificent-poney

Initialize a package.json with the name of your package.

Rather than typing yarn init, prefer to take the ./packages/ui-lib/package.json as a working example and edit its values.

Example of package.json
{
  "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:^",
  },
}

3. Using the package in app

Step 3.1: package.json

First add the package to the app package.json. The recommended way is to use the workspace protocol supported by yarn and pnpm.

cd apps/my-app
yarn add @your-org/magnificent-poney@'workspace:^'

Inspiration can be found in apps/nextjs-app/package.json.

package.json
{
  "name": "my-app",
  "dependencies": {
    "@your-org/magnificient-poney": "workspace:^",
  },
}

Step 3.2: In tsconfig.json

Then add a typescript path alias in the app tsconfig.json. This will allow you to import it directly (no build needed)

Inspiration can be found in apps/nextjs-app/tsconfig.json.

Example of tsonfig.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",
      ],
    },
  },
}

PS:

  • Don't try to set aliases in the global tsonfig.base.json to keep strict with graph dependencies.
  • The star in @your-org/magnificent-poney/* allows you to import subfolders. If you use a barrel file (index.ts), the alias with star can be removed.

Step 3.3: Next config

Edit your next.config.mjs and enable the experimental.externalDir option. Feedbacks here.

const nextConfig = {
  experimental: {
    externalDir: true,
  },
};
Using a NextJs version prior to 10.2.0 ?

If you're using an older NextJs version and don't have the experimental flag, you can simply override your webpack config.

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;
  },
};

PS: If your shared package make use of scss bundler... A custom webpack configuration will be necessary or use next-transpile-modules, see FAQ below.

Step 3.4: Using the package

The packages are now linked to your app, just import them like regular packages: import { poney } from '@your-org/magnificent-poney'.

4. Publishing

Optional

If you need to share some packages outside of the monorepo, you can publish them to npm or private repositories. An example based on microbundle is present in each package. Versioning and publishing can be done with atlassian/changeset, and it's simple as typing:

$ yarn g:changeset

Follow the instructions... and commit the changeset file. A "Version Packages" P/R will appear after CI checks. When merging it, a github action will publish the packages with resulting semver version and generate CHANGELOGS for you.

PS:

  • Even if you don't need to publish, changeset can maintain an automated changelog for your apps. Nice !
  • To disable automatic publishing of some packages, just set "private": "true" in their package.json.
  • Want to tune the behaviour, see .changeset/config.json.

4. Monorepo essentials

Monorepo scripts

Some convenience scripts can be run in any folder of this repo and will call their counterparts defined in packages and apps.

Name Description
yarn g:changeset Add a changeset to declare a new version
yarn g:codegen Run codegen in all workspaces
yarn g:typecheck Run typechecks in all workspaces
yarn g:lint Display linter issues in all workspaces
yarn g:lint --fix Attempt to run linter auto-fix in all workspaces
yarn g:lint-styles Display css stylelint issues in all workspaces
yarn g:lint-styles --fix Attempt to run stylelint auto-fix issues in all workspaces
yarn g:test Run unit and e2e tests in all workspaces
yarn g:test-unit Run unit tests in all workspaces
yarn g:test-e2e Run e2e tests in all workspaces
yarn g:build Run build in all workspaces
yarn g:clean Clean builds in all workspaces
yarn g:check-dist Ensure build dist files passes es2017 (run g:build first).
yarn g:check-size Ensure browser dist files are within size limit (run g:build first).
yarn clean:global-cache Clean tooling caches (eslint, jest...)
yarn deps:check --dep dev Will print what packages can be upgraded globally (see also .ncurc.yml)
yarn deps:update --dep dev Apply possible updates (run yarn install && yarn dedupe after)
yarn install:playwright Install playwright for e2e
yarn dedupe Built-in yarn deduplication of the lock file

Why using : to prefix scripts names ? It's convenient in yarn 3+, we can call those scripts from any folder in the monorepo. g: is a shortcut for global:. See the complete list in root package.json.

Maintaining deps updated

The global commands yarn deps:check and yarn deps:update will help to maintain the same versions across the entire monorepo. They are based on the excellent npm-check-updates (see options, i.e: yarn check:deps -t minor).

After running yarn deps:update, a yarn install is required. To prevent having duplicates in the yarn.lock, you can run yarn dedupe --check and yarn dedupe to apply deduplication. The duplicate check is enforced in the example github actions.

5. Quality

5.1 Linters

See an example in ./apps/nextjs-app/.eslintrc.js and our eslint-config-bases.

5.2 Hooks / Lint-staged

Check the .husky folder content to see what hooks are enabled. Lint-staged is used to guarantee that lint and prettier are applied automatically on commit and/or pushes.

5.3 Tests

Tests relies on ts-jest or vitest depending on the app. All setups supports typescript path aliases. React-testing-library is enabled whenever react is involved.

Configuration lives in the root folder of each apps/packages. As an example see

5.4 CI

You'll find some example workflows for github action in .github/workflows. By default, they will ensure that

  • You don't have package duplicates.
  • You don't have typecheck errors.
  • You don't have linter / code-style errors.
  • Your test suite is successful.
  • Your apps (nextjs) or packages can be successfully built.
  • Basic check-size example in nextjs-app.

Each of those steps can be opted-out.

To ensure decent performance, those features are present in the example actions:

  • Caching of packages (node_modules...) - install around 25s

  • Caching of nextjs previous build - built around 20s

  • Triggered when changed using actions paths, ie:

     paths:
       - "apps/nextjs-app/**"
       - "packages/**"
       - "package.json"
       - "tsconfig.base.json"
       - "yarn.lock"
       - ".yarnrc.yml"
       - ".github/workflows/**"
       - ".eslintrc.base.json"
       - ".eslintignore"
    

6. Editor support

6.1 VSCode

The ESLint plugin requires that the eslint.workingDirectories setting is set:

"eslint.workingDirectories": [
    {
        "pattern": "./apps/*/"
    },
    {
        "pattern": "./packages/*/"
    }
],

More info here

7. Deploy

Vercel

Vercel support natively monorepos, see the vercel-monorepo-deploy document.

Docker

There's a basic example for building a docker image, read the docker doc.

Others

Netlify, aws-amplify, k8s-docker, serverless-nextjs recipes might be added in the future. PR's welcome too.

FAQ

Monorepo

Benefits

  • Ease of code reuse. You can easily extract shared libraries (like api, shared ui, locales, images...) and use them across apps without the need of handling them in separate git repos (removing the need to publish, version, test separately...). This limit the tendency to create code duplication amongst developers when time is short.
  • Atomic commits. When projects that work together are contained in separate repositories, releases need to sync which versions of one project work with the other. In monorepo CI, sandboxes and releases are much easier to reason about (ie: dependency hell...). A pull-request contains all changes at once, no need to coordinate multiple packages versions to test it integrally (multiple published canary versions...).
  • Code refactoring. Changes made on a library will immediately propagate to all consuming apps / packages. Typescript / typechecks, tests, ci, sandboxes... will improve the confidence to make a change (or the right one thanks to improved discoverability of possible side effects). It also limits the tendency to create tech debt as it invites the dev to refactor all the code that depends on a change.
  • Collaboration across teams. Consistency, linters, discoverability, duplication... helps to maintain cohesion and collaboration across teams.

Drawbacks

  • Increased build time. Generally a concern but not relevant in this context thanks to the combination of nextjs/webpack5, typescript path aliases and yarn. Deps does not need to be build... modified files are included as needed and properly cached (nextjs webpack5, ci, deploy, docker/buildkit...).
  • Versioning and publishing. Sometimes a concern when you want to use the shared libraries outside of the monorepo. See the notes about atlassian changeset. Not relevant here.
  • Git repo size. All packages and apps and history will fit in the same git repository increasing its size and checkout time. Generally when you reach size problems, check for assets like images first and extract packages that don't churn anymore.
  • Multi-languages. Setting up a monorepo containing code in multiple languages (php, ruby, java, node) is extremely difficult to handle due to nonexistence of mature tooling (bazel...).The general idea is to create a monorepo with the same stack (node, typescript...) and managed by the same package manager (yarn, pnpm,...)

Exact vs semver dependencies

Apps dependencies and devDependencies are pinned to exact versions. Packages deps will use semver compatible ones. For more info about this change see reasoning here and our renovabot.json5 configuration file.

To help keeping deps up-to-date, see the yarn deps:check && yarn deps:update scripts and / or use the renovatebot.

When adding a dep through yarn cli (i.e.: yarn add something), it's possible to set the save-exact behaviour automatically by setting defaultSemverRangePrefix: "" in yarnrc.yml. But this would make the default for packages/* as well. Better to handle yarn add something --exact on per-case basis.

License

FOSSA Status

nextjs-monorepo-example's People

Contributors

belgattitude avatar bryce-larson avatar ekafyi avatar github-actions[bot] avatar nnmax avatar oste avatar renovate-bot avatar renovate[bot] avatar tianyingchun avatar wdh2100 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

nextjs-monorepo-example's Issues

RFC: Move to pnpm

Is it worthy to move to pnpm and reduce carbon emissions ?

WIP PR in #2765

Criteria

  • Time on CI and ability to start in warm cache
  • Vercel deployment time and size
  • Easy to maintain versions of the pm in ci, docker... (corepack will help in the future but not yet)
  • Easy ways to build a docker image
  • Best integration with tools like nx, turbo

Checklist

Tested on this monorepo with nextjs 12.3.1. At first sight pnpm is faster, but going into details... not sure.

Check Yarn 4rc Pnpm 7 Winner
Laptop (cold cache) 71.410 ± 1.835 34.696 ± 1.413 pnpm (x2)
Laptop (warm cache) 21.576 ± 0.390 10.780 ± 0.881 pnpm (x2)
Github action (cold) ±2m ±1m20 pnpm (x1.8)
Github action (warm) ±1m20 ±50s pnpm (x1.3)
Vercel (warm) ±2m20 ±3m30s yarn
Vercel (ssr lambda size) 25MB (8.88Mb) 50MB (25Mb zip) yarn
Vercel (api routes) 68Mb (22Mb zip) 49.4 MB (22.6Mb zip) pnpm
  • Yarn is slower in ci & local but with the automatic rotation of its cache, it's run always (mostly) warm everywhere. So the difference is not huge. The warm cache works also in vercel.
  • Yarn is commited in the github repo. No need to take care of different versions on CI, Github, local machines... Install is reproducible
  • Vercel deployments/previews are slower (couldn't make pnpm cache as good as yarn).
  • Lambdas size differs a lot... need more investigations (vercel/nft...)

PS: locally bench were done with hyperfine, timings on github are based on few runs and include the install and the action/cache (de-)compression. As yarn already compress the archives, the post compression is very fast (zstd is disabled for files that does not compress)

Links

Yarn3 PnP Jest Issue

I tried yarn test & yarn workspace web-app test in the yarn-pnp branch, and got these errors.

  • yarn test
➤ YN0000: [@your-org/core-lib]: Process started
➤ YN0000: [@your-org/ui-lib]: Process started
➤ YN0000: [@your-org/ui-lib]: No tests yet
➤ YN0000: [@your-org/ui-lib]: Process exited (exit code 0), completed in 0s 443ms
➤ YN0000: [@your-org/core-lib]: ● Validation Error:
➤ YN0000: [@your-org/core-lib]: 
➤ YN0000: [@your-org/core-lib]:   Module jest-circus/runner in the testRunner option was not found.
➤ YN0000: [@your-org/core-lib]:          <rootDir> is: /Users/jackjin/Documents/nextjs-monorepo-example/packages/core-lib/src
➤ YN0000: [@your-org/core-lib]: 
➤ YN0000: [@your-org/core-lib]:   Configuration Documentation:
➤ YN0000: [@your-org/core-lib]:   https://jestjs.io/docs/configuration
➤ YN0000: [@your-org/core-lib]: 
➤ YN0000: [@your-org/core-lib]: Process exited (exit code 1), completed in 0s 770ms
➤ YN0000: The command failed for workspaces that are depended upon by other workspaces; can't satisfy the dependency graph
➤ YN0000: Failed with errors in 0s 776ms
ERROR: "test:unit" exited with 1.
  • yarn workspace web-app test
● Validation Error:

  Module jest-circus/runner in the testRunner option was not found.
         <rootDir> is: /Users/jackjin/Documents/nextjs-monorepo-example/apps/web-app/src

  Configuration Documentation:
  https://jestjs.io/docs/configuration

ERROR: "test:unit" exited with 1.

Yarn: 3.0.0-rc6
Node: 14.17.0
OS: MacOS 11.3

Issue with Yarn workspaces

I tried to install the dependencies using yarn I'm getting below errors

Yarn: 1.22.11
Node: v14.18.1
OS: MacOS

Error: Couldn't find package "@your-org/ui-lib@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:38129:17
    at Generator.throw (<anonymous>)
    at step (/Users/karthik/.yarn/releases/yarn-1.22.11.cjs:310:30)
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:323:13
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
Error: Couldn't find package "@your-org/ui-lib@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:38129:17
    at Generator.throw (<anonymous>)
    at step (/Users/karthik/.yarn/releases/yarn-1.22.11.cjs:310:30)
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:323:13
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
Error: Couldn't find package "@your-org/ui-lib@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:38129:17
    at Generator.throw (<anonymous>)
    at step (/Users/karthik/.yarn/releases/yarn-1.22.11.cjs:310:30)
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:323:13
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
Error: Couldn't find package "@your-org/core-lib@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:38129:17
    at Generator.throw (<anonymous>)
    at step (/Users/karthik/.yarn/releases/yarn-1.22.11.cjs:310:30)
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:323:13
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
Error: Couldn't find package "@your-org/db-main-prisma@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:38129:17
    at Generator.throw (<anonymous>)
    at step (/Users/karthik/.yarn/releases/yarn-1.22.11.cjs:310:30)
    at /Users/karthik/.yarn/releases/yarn-1.22.11.cjs:323:13
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
Error: Couldn't find package "@your-org/core-lib@workspace:*" required by "[email protected]" on the "npm" registry.
    at /Users/karthik/.yarn/releases/yarn-1.2

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

docker-compose
docker-compose.yml
  • postgres 16.2-alpine3.18
docker/docker-compose.db.yml
  • postgres 16.2-alpine3.18
docker/docker-compose.yml
packages/db-main-prisma/docker-compose.e2e.yml
  • postgres 16.2-alpine3.18
dockerfile
docker/Dockerfile
  • node 20-alpine3.18
  • node 20-alpine3.18
github-actions
.github/actions/playwright-install/action.yml
  • actions/cache v4
.github/actions/yarn-nm-install/action.yml
  • actions/cache v4
  • actions/cache v4
  • actions/cache v4
  • actions/cache v4
.github/workflows/ci-codegen.yml
  • actions/checkout v4
  • actions/setup-node v4
.github/workflows/ci-e2e-nextjs-app.yml
  • actions/checkout v4
  • actions/setup-node v4
  • felixmosh/turborepo-gh-artifacts v3
  • actions/cache v4
  • BerniWittmann/background-server-action v1
  • actions/upload-artifact v4
.github/workflows/ci-e2e-prisma.yml
  • actions/checkout v4
  • actions/setup-node v4
.github/workflows/ci-monorepo-integrity.yml
  • actions/checkout v4
  • actions/setup-node v4
.github/workflows/ci-nextjs-app.yml
  • actions/checkout v4
  • actions/setup-node v4
  • felixmosh/turborepo-gh-artifacts v3
  • actions/cache v4
.github/workflows/ci-packages.yml
  • actions/checkout v4
  • actions/setup-node v4
  • felixmosh/turborepo-gh-artifacts v3
  • actions/cache v4
.github/workflows/ci-remix-app.yml
  • actions/checkout v4
  • actions/setup-node v4
  • felixmosh/turborepo-gh-artifacts v3
.github/workflows/ci-vite-app.yml
  • actions/checkout v4
  • actions/setup-node v4
  • felixmosh/turborepo-gh-artifacts v3
.github/workflows/clean-up-pr-caches.yml
  • actions/checkout v4
.github/workflows/codesee-arch-diagram.yml
  • Codesee-io/codesee-action v2
.github/workflows/release-nextjs-app-docker.yml
  • actions/checkout v4
  • docker/metadata-action v5
  • docker/setup-qemu-action v3
  • docker/setup-buildx-action v3
  • docker/login-action v3
  • docker/build-push-action v5
.github/workflows/release-or-version-pr.yml
  • actions/checkout v4
  • actions/setup-node v4
  • changesets/action v1
npm
apps/nextjs-app/package.json
  • @emotion/cache 11.11.0
  • @emotion/react 11.11.4
  • @emotion/server 11.11.0
  • @emotion/styled 11.11.5
  • @envelop/core 5.0.0
  • @envelop/graphql-jit 8.0.3
  • @envelop/validation-cache 7.0.0
  • @escape.tech/graphql-armor-character-limit 2.1.0
  • @escape.tech/graphql-armor-cost-limit 2.1.0
  • @escape.tech/graphql-armor-max-aliases 2.3.0
  • @escape.tech/graphql-armor-max-depth 2.2.0
  • @escape.tech/graphql-armor-max-directives 2.1.0
  • @escape.tech/graphql-armor-max-tokens 2.3.0
  • @fontsource-variable/inter 5.0.18
  • @headlessui/react 1.7.19
  • @hookform/resolvers 3.3.4
  • @httpx/assert 0.8.0
  • @httpx/dsn-parser 1.7.0
  • @httpx/exception 3.0.5
  • @httpx/json-api 0.5.18
  • @mui/icons-material 5.15.15
  • @mui/material 5.15.15
  • @nextvalid/zod-request 0.4.0
  • @pothos/core 3.41.1
  • @pothos/plugin-errors 3.11.1
  • @pothos/plugin-prisma 3.65.1
  • @prisma/client 5.13.0
  • @sentry/nextjs 7.112.2
  • @sentry/react 7.112.2
  • @soluble/cache-interop 0.12.8
  • @soluble/cache-ioredis 0.13.11
  • @tanstack/react-query 5.32.0
  • @vercel/analytics 1.2.2
  • clsx 2.1.1
  • cors 2.8.5
  • graphql 16.8.1
  • graphql-jit 0.8.6
  • graphql-yoga 5.3.0
  • i18next 23.11.2
  • jose 5.2.4
  • ky 1.2.4
  • next 14.1.4
  • next-auth 4.24.7
  • next-connect 1.0.0
  • next-i18next 15.3.0
  • next-secure-headers 2.2.0
  • next-seo 6.5.0
  • ofetch 1.3.4
  • picocolors 1.0.0
  • react 18.2.0
  • react-dom 18.2.0
  • react-hook-form 7.51.3
  • react-i18next 14.1.1
  • rippleui 1.12.1
  • rooks 7.14.1
  • sharp 0.33.3
  • superjson 2.2.1
  • type-fest 4.17.0
  • wonka 6.3.4
  • zod 3.22.5
  • @next/bundle-analyzer 14.1.4
  • @next/env 14.1.4
  • @playwright/test 1.43.1
  • @prisma/nextjs-monorepo-workaround-plugin 5.13.0
  • @size-limit/file 11.1.2
  • @svgr/webpack 8.1.0
  • @tailwindcss/forms 0.5.7
  • @tailwindcss/typography 0.5.12
  • @testing-library/dom 10.0.0
  • @testing-library/jest-dom 6.4.2
  • @testing-library/react 15.0.4
  • @testing-library/user-event 14.5.2
  • @types/cors 2.8.17
  • @types/is-ci 3.0.4
  • @types/node 20.12.7
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • @types/react-test-renderer 18.0.7
  • @vitejs/plugin-react-swc 3.6.0
  • @vitest/coverage-v8 1.5.2
  • @vitest/ui 1.5.2
  • autoprefixer 10.4.19
  • cross-env 7.0.3
  • dotenv-flow 4.1.0
  • dotenv-flow-cli 1.1.1
  • es-check 7.1.1
  • eslint 8.57.0
  • eslint-config-next 14.1.4
  • eslint-plugin-tailwindcss 3.15.1
  • is-ci 3.0.1
  • jsdom 24.0.0
  • npm-run-all2 6.1.2
  • postcss 8.4.38
  • postcss-flexbugs-fixes 5.0.2
  • postcss-preset-env 9.5.9
  • prettier 3.2.5
  • react-test-renderer 18.2.0
  • rimraf 5.0.5
  • size-limit 11.1.2
  • tailwindcss 3.4.3
  • typescript 5.4.5
  • vite 5.2.10
  • vite-plugin-magical-svg 1.2.1
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
apps/remix-app/package.json
  • @remix-run/node 2.9.1
  • @remix-run/react 2.9.1
  • @remix-run/serve 2.9.1
  • isbot 5.1.5
  • react 18.2.0
  • react-dom 18.2.0
  • @remix-run/dev 2.9.1
  • @remix-run/eslint-config 2.9.1
  • @tailwindcss/forms 0.5.7
  • @testing-library/dom 10.0.0
  • @testing-library/jest-dom 6.4.2
  • @testing-library/react 15.0.4
  • @testing-library/user-event 14.5.2
  • @types/node 20.12.7
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • @vitest/coverage-v8 1.5.2
  • @vitest/ui 1.5.2
  • autoprefixer 10.4.19
  • cssnano 7.0.0
  • eslint 8.57.0
  • postcss 8.4.38
  • prettier 3.2.5
  • stylelint 16.4.0
  • stylelint-config-standard 36.0.0
  • tailwindcss 3.4.3
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
  • node >=18.14.0
apps/vite-app/package.json
  • @emotion/react 11.11.4
  • @emotion/styled 11.11.5
  • react 18.2.0
  • react-dom 18.2.0
  • @babel/core 7.24.4
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • @vitejs/plugin-react 4.2.1
  • @vitest/coverage-v8 1.5.2
  • @vitest/ui 1.5.2
  • eslint 8.57.0
  • eslint-plugin-tailwindcss 3.15.1
  • happy-dom 14.7.1
  • prettier 3.2.5
  • rimraf 5.0.5
  • tailwindcss 3.4.3
  • typescript 5.4.5
  • vite 5.2.10
  • vite-plugin-svgr 4.2.0
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
package.json
  • cross-env 7.0.3
  • @changesets/changelog-github 0.5.0
  • @changesets/cli 2.27.1
  • @commitlint/cli 19.3.0
  • @commitlint/config-conventional 19.2.2
  • @types/shell-quote 1.7.5
  • eslint 8.57.0
  • husky 9.0.11
  • lint-staged 15.2.2
  • npm-run-all2 6.1.2
  • prettier 3.2.5
  • rimraf 5.0.5
  • shell-quote 1.8.1
  • syncpack 12.3.2
  • turbo 1.13.2
  • typescript 5.4.5
  • node >=18.17.0
  • yarn >=1.22.0
  • yarn 4.1.1
packages/common-i18n/package.json
  • @types/node 20.12.7
  • cross-env 7.0.3
  • eslint 8.57.0
  • prettier 3.2.5
  • rimraf 5.0.5
  • typescript 5.4.5
packages/core-lib/package.json
  • dequal ^2.0.3
  • @testing-library/dom 10.0.0
  • @testing-library/react 15.0.4
  • @testing-library/user-event 14.5.2
  • @types/node 20.12.7
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • @vitejs/plugin-react 4.2.1
  • @vitest/coverage-v8 1.5.2
  • @vitest/ui 1.5.2
  • cross-env 7.0.3
  • eslint 8.57.0
  • npm-run-all2 6.1.2
  • prettier 3.2.5
  • react 18.2.0
  • react-dom 18.2.0
  • rimraf 5.0.5
  • tsup 8.0.2
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
  • react ^18.2.0
  • react-dom ^18.2.0
packages/db-main-prisma/package.json
  • @pothos/core 3.41.1
  • @pothos/plugin-prisma 3.65.1
  • @prisma/client 5.13.0
  • @soluble/dsn-parser 1.9.2
  • @types/node 20.12.7
  • @vitest/coverage-v8 1.5.2
  • @vitest/ui 1.5.2
  • camelcase 8.0.0
  • cross-env 7.0.3
  • dotenv-flow 4.1.0
  • dotenv-flow-cli 1.1.1
  • eslint 8.57.0
  • graphql 16.8.1
  • keyword-extractor 0.0.28
  • npm-run-all2 6.1.2
  • picocolors 1.0.0
  • prettier 3.2.5
  • prisma 5.13.0
  • rimraf 5.0.5
  • transliteration 2.3.5
  • tsup 8.0.2
  • tsx 4.7.3
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
  • @pothos/plugin-prisma ^3.41.0
  • @prisma/client ^4.10.1 || ^5.0.0
  • graphql ^16.6.0
packages/eslint-config-bases/package.json
  • @rushstack/eslint-patch ^1.10.1
  • @tanstack/eslint-plugin-query ^5.28.11
  • @typescript-eslint/eslint-plugin ^7.5.0
  • @typescript-eslint/parser ^7.5.0
  • eslint-config-prettier ^9.1.0
  • eslint-import-resolver-typescript ^3.6.1
  • eslint-plugin-import ^2.29.1
  • eslint-plugin-jest ^28.0.0
  • eslint-plugin-jest-formatting ^3.1.0
  • eslint-plugin-jsx-a11y ^6.8.0
  • eslint-plugin-playwright ^1.5.4
  • eslint-plugin-prettier ^5.1.3
  • eslint-plugin-react ^7.34.1
  • eslint-plugin-react-hooks ^4.6.0 || 5.0.0-canary-7118f5dd7-20230705
  • eslint-plugin-regexp ^2.4.0
  • eslint-plugin-sonarjs ^0.25.0
  • eslint-plugin-storybook ^0.8.0
  • eslint-plugin-testing-library ^6.2.0
  • @graphql-eslint/eslint-plugin 3.20.1
  • @testing-library/jest-dom 6.4.2
  • @testing-library/react 15.0.4
  • @types/node 20.12.7
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • es-check 7.1.1
  • eslint 8.57.0
  • eslint-plugin-mdx 3.1.5
  • eslint-plugin-tailwindcss 3.15.1
  • graphql 16.8.1
  • react 18.2.0
  • react-dom 18.2.0
  • rimraf 5.0.5
  • tailwindcss 3.4.3
  • typescript 5.4.5
  • @graphql-eslint/eslint-plugin ^3.14.3
  • eslint ^8.55.0
  • eslint-plugin-mdx ^2.2.0 || ^3.0.0
  • eslint-plugin-tailwindcss ^3.13.0
  • graphql ^16.8.0
  • prettier ^3.0.0
  • react ^18.2.0
  • react-dom ^18.2.0
  • typescript ^5.1.6
  • node >=18.12.0
packages/ts-utils/package.json
  • @size-limit/file 11.1.2
  • @types/node 20.12.7
  • @vitest/coverage-v8 1.5.2
  • cross-env 7.0.3
  • es-check 7.1.1
  • eslint 8.57.0
  • get-tsconfig 4.7.3
  • rimraf 5.0.5
  • size-limit 11.1.2
  • tslib 2.6.2
  • tsup 8.0.2
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
  • node >=18.17
packages/ui-lib/package.json
  • @emotion/react 11.11.4
  • @emotion/styled 11.11.5
  • @storybook/addon-essentials 8.0.9
  • @storybook/addon-interactions 8.0.9
  • @storybook/addon-links 8.0.9
  • @storybook/blocks 8.0.9
  • @storybook/react 8.0.9
  • @storybook/react-vite 8.0.9
  • @storybook/testing-library 0.2.2
  • @tailwindcss/forms 0.5.7
  • @testing-library/dom 10.0.0
  • @testing-library/jest-dom 6.4.2
  • @testing-library/react 15.0.4
  • @testing-library/user-event 14.5.2
  • @types/node 20.12.7
  • @types/react 18.2.79
  • @types/react-dom 18.2.25
  • @vitest/coverage-v8 1.5.2
  • autoprefixer 10.4.19
  • cross-env 7.0.3
  • eslint 8.57.0
  • eslint-plugin-tailwindcss 3.15.1
  • npm-run-all2 6.1.2
  • postcss 8.4.38
  • prettier 3.2.5
  • react 18.2.0
  • react-dom 18.2.0
  • require-from-string 2.0.2
  • rimraf 5.0.5
  • rooks 7.14.1
  • sirv 2.0.4
  • sirv-cli 2.0.2
  • storybook 8.0.9
  • tailwindcss 3.4.3
  • tsup 8.0.2
  • typescript 5.4.5
  • vite 5.2.10
  • vite-tsconfig-paths 4.3.2
  • vitest 1.5.2
  • @emotion/react ^11.10.8
  • @emotion/styled ^11.10.8
  • @types/react ^18.2.11
  • @types/react-dom ^18.2.4
  • react ^18.2.0
  • react-dom ^18.2.0

  • Check this box to trigger a request for Renovate to run again on this repository

nextjs-app compilation error and warning

I got this error and warning from the nextjs-app v3.58.0 build:

➤ YN0000: [nextjs-app]: info  - Loaded env from /Users/joe/repos/nounzoo/apps/nextjs-app/.env
➤ YN0000: [nextjs-app]: notice- Will transpile [ky]
➤ YN0000: [nextjs-app]: info  - Linting and checking validity of types...
➤ YN0000: [nextjs-app]: warn  - You have enabled experimental features (outputFileTracingRoot, externalDir) in next.config.mjs.
➤ YN0000: [nextjs-app]: warn  - Experimental features are not covered by semver, and may cause unexpected or broken application behavior. Use at your own risk.
➤ YN0000: [nextjs-app]: 
➤ YN0000: [nextjs-app]: 
➤ YN0000: [nextjs-app]: Failed to compile.
➤ YN0000: [nextjs-app]: 
➤ YN0000: [nextjs-app]: ./src/backend/graphql/graphqlSchema.ts
➤ YN0000: [nextjs-app]: 4:1  Error: `@nounzoo/db-main-prisma` import should occur before import of `@pothos/core`  import/order
➤ YN0000: [nextjs-app]: 
➤ YN0000: [nextjs-app]: ./src/features/home/blocks/hero/HeroBlock.tsx
➤ YN0000: [nextjs-app]: 10:11  Warning: 't' is assigned a value but never used.  @typescript-eslint/no-unused-vars
➤ YN0000: [nextjs-app]: 
➤ YN0000: [nextjs-app]: info  - Need to disable some ESLint rules? Learn more here: https://nextjs.org/docs/basic-features/eslint#disabling-rules
➤ YN0000: [nextjs-app]: Process exited (exit code 1), completed in 8s 902ms

I was able to eliminate the error by moving the following line to the top of the file graphqlSchema.ts:

import type { DbMainPrismaTypes } from '@nounzoo/db-main-prisma';

And by removing the following two lines from HeroBlock.tsx:

import { useTranslation } from 'next-i18next';

const { t } = useTranslation(['home', 'common']);

Would you like a pull request?

How does tree shaking work with this setup?

Hi! Thanks for maintaining this repo up to date, it has been really useful in my company since we have a similar setup.

We are having issues with tree shaking and barrel (index.ts) files in our setup, we have 3 big shared libraries and we're getting (a lot) more code than we need from them on every Next.js page.

I did some research and found that adding "sideEffects": false to the libraries package.json helps a lot, but still doesn't fix all of our problems.

I've also been testing this setup and tree shaking works really well, adding a new export to a shared's lib index.ts doesn't affect the page bundle at all if it's not being imported, or even if it's being imported but it's not used.

So I'm curious to know what config is enabling tree shaking to work properly, even without needing "sideEffects": false in the package.json files.

Thank you!

add prettier for formatting and remove prettier for linting

Consider removing prettier as part of eslint and add it the package script for formatting, it is not a linter.

https://prettier.io/docs/en/integrating-with-linters.html
https://prettier.io/docs/en/comparison.html

For example running yarn run g:lint

With prettier lintting rule:

[nextjs-app]: Rule                                   | Time (ms) | Relative
[nextjs-app]: :--------------------------------------|----------:|--------:
[nextjs-app]: prettier/prettier                      |   592.110 |    23.5%
[nextjs-app]: import/default                         |   382.082 |    15.2%
[nextjs-app]: import/no-duplicates                   |   330.011 |    13.1%
[nextjs-app]: tailwindcss/classnames-order           |   294.505 |    11.7%
[nextjs-app]: tailwindcss/no-contradicting-classname |   150.598 |     6.0%
[nextjs-app]: sonarjs/no-ignored-return              |   148.545 |     5.9%
[nextjs-app]: import/no-unresolved                   |   117.598 |     4.7%
[nextjs-app]: import/no-named-as-default             |   104.360 |     4.1%
[nextjs-app]: tailwindcss/enforces-shorthand         |   101.104 |     4.0%
[nextjs-app]: @typescript-eslint/naming-convention   |    40.204 |     1.6%

Without prettier lintting rule:

[nextjs-app]: Rule                                   | Time (ms) | Relative
[nextjs-app]: :--------------------------------------|----------:|--------:
[nextjs-app]: import/default                         |   360.500 |    21.5%
[nextjs-app]: import/no-duplicates                   |   283.216 |    16.9%
[nextjs-app]: tailwindcss/classnames-order           |   216.061 |    12.9%
[nextjs-app]: sonarjs/no-ignored-return              |   151.779 |     9.1%
[nextjs-app]: tailwindcss/no-contradicting-classname |   135.110 |     8.1%
[nextjs-app]: tailwindcss/enforces-shorthand         |    97.479 |     5.8%
[nextjs-app]: import/no-named-as-default             |    96.537 |     5.8%
[nextjs-app]: import/no-unresolved                   |    69.346 |     4.1%
[nextjs-app]: @typescript-eslint/naming-convention   |    40.471 |     2.4%
[nextjs-app]: import/order                           |    20.577 |     1.2%

Best practice for add a backend server

Since we know nextjs is a good framework for frontend, and it can handle simple backend functions, but if I need a powerful backend framework such as nestjs, how can I add it to this monorepo.

Thank you a lot.

Example with standalone build

Hi, this is a great repo and has been really helpful to me in setting up my own Next.js monorepo. Thank you.

One suggestion. Next.js recommends using output file tracing ("standalone" build) with Docker:

I've modified your example to use this feature, and it seems to work.

In next.config.mjs:

import path from "path";
import url from "url";

const _filename_ = url.fileURLToPath(import.meta.url);
const _dirname_ = path.dirname(_filename_);
const ROOT_DIR = path.resolve(_dirname_, "..", "..");

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  ...
  experimental: {
    // For tracing, include files from the monorepo base (two directories up).
    // https://nextjs.org/docs/advanced-features/output-file-tracing#caveats
    outputFileTracingRoot: ROOT_DIR,
  },
  output: "standalone",
  ...
};

In Dockerfile's last stage:

ARG APP_NAME

WORKDIR /base/apps/${APP_NAME}

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs && adduser --system --uid 1001 nextjs

COPY --from=builder --chown=nextjs:nodejs /base/apps/${APP_NAME}/.next/standalone/ /base/
COPY --from=builder --chown=nextjs:nodejs /base/apps/${APP_NAME}/.next/static /base/apps/${APP_NAME}/.next/static
COPY --from=builder --chown=nextjs:nodejs /base/apps/${APP_NAME}/public /base/apps/${APP_NAME}/public

...

# Start the app.
CMD ["node", "server.js"]

Note: The contents of the standalone directory are copied to /base/. (My base directory is base rather than app because I don't like the look of /app/apps.)

Error: No mesh config file found

Steps to reproduce:

  1. Clone repo - main branch
  2. run yarn docker:nextjs-app:develop

Expected result - images come up with apps.
Actual result: fails with
Mesh Error: No mesh config file found in "/workspace-install/packages/api-gateway"! #0 45.99 ➤ YN0000: │ @your-org/api-gateway@workspace:packages/api-gateway STDOUT at findAndParseConfig (/workspace-install/node_modules/@graphql-mesh/cli/cjs/config.js:71:15) #0 45.99 ➤ YN0000: │ @your-org/api-gateway@workspace:packages/api-gateway STDOUT at async Object.handler (/workspace-install/node_modules/@graphql-mesh/cli/cjs/index.js:291:32)

OS: MacOS Ventura 13.1
Macbook Air M1

Using ts-jest/babel-jest with this setup

Hi! I'm using this setup in our monorepo and it's awesome, having cross-package fast refresh and being able to import external packages without building/watching them really makes the difference in DX.

I've been trying to set Jest for the whole morning with no success, so I'll like to ask you for some hints if you already did it.

So far, I was able to use the tsconfig to resolve packages paths:

module.exports = {
  // ...config
  moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths, {
    prefix: "<rootDir>/../../../",
  }),
  // ...more config
};

But got this error while importing them:

image

I tried both ts-jest and babel-jest and couldn't make them work.

I think this may have to do with Jest not being "aware" of the need to transpile the monorepo packages, since that's not specified neither in .babelrc nor tsconfig.json.

Is there any way to make Jest transpile monorepo packages?

Thanks

Disabled SWC as replacement for Babel

Hello! I believe you're aware of this, so I guess this is more like a question. When I try to build the Next.js app, I get the following warning:

Process started
info  - Checking validity of types...
info  - Creating an optimized production build...
info  - Disabled SWC as replacement for Babel because of custom Babel configuration "babel.config.js" https://nextjs.org/docs/messages/swc-disabled
info  - Using external babel configuration from /Users/.../web-app/babel.config.js
Compiled successfully

May you please why we need a specific Babel configuration and if it's worth to forego SWC for it?

Semantic error TS6059 File 'packages/ts-utils/src/index.ts' is not under 'rootDir'

Hello, I am getting this error when trying to build with yarn g:build locally.

semantic error TS6059: File '/Users/marie-maxime/webdev/nextjs-monorepo-example/packages/ts-utils/src/index.ts' is not under 'rootDir' '/Users/marie-maxime/webdev/nextjs-monorepo-example/packages/ui-lib/src'. 'rootDir' is expected to contain all source files.

To reproduce:

In file nextjs-monorepo-example/packages/ui-lib/src/base/index.ts
add the following line export { BasicCard } from './card/BasicCard';
and then run yarn g:build in root folder.

This seems to be caused by import { isNonEmptyString } from '@your-org/ts-utils';

Tested with a fresh install and latest version of main as of time of writing this issue.

Thank you for building and maintaining this repo btw!

Automated releases

After reading the publishing section in the README, I was expecting that merging the release PR would have resulted in a new release being published (on NPM, GitHub or anywhere):

When merging it, a github action will publish the packages with resulting semver version and generate CHANGELOGS for you.

But actually, one has to run g:release to publish new releases.
I suggest to add automation for this step.

With a publishing workflow that runs only for '**/CHANGELOG.md' paths, the action of merging the release PR would also publish a new release.

WDYT?

How to use `baseUrl` in `bar` package

Hi @belgattitude. Thank you for sharing this monorepo, it's been very helpful.

I'm trying to accomplish a similar setup for a new project. In particular, I'm setting up a monorepo with two Next.js apps and several private packages for things like UI components and domain logic. I'm trying to exclusively use the tsconfig.paths approach and avoid the next-transpile-module approach.

My question is: is it possible, and, if so, is it appropriate, to use baseUrl in my private packages? For example, I cloned your repo, added baseUrl to bar's tsconfig, and changed one import to non-absolute. VS code can find the module and does not complain, but when I run the web-app I get a "module not found" error.

See: master...andreavaccari:av/non-relative-imports

Is it wrong to use baseUrl in this situation?

Debug Nexjs app in monorepo with "NODE_OPTIONS='inspect'"

What?

Hi, nice to meet you. I've been looking for a solution for this hours and I don't find anything. So first of all sorry for creating an issue in this repo 🙏. But I think this can be really helpful for a lot of people. Debugging Node is not always easy

The problem. Debug node server NextJS app

I'm following their oficial docs: https://nextjs.org/docs/pages/building-your-application/configuring/debugging#server-side-code

But these docs are for a flat next app not for an app living in a monorepo like this so maybe someone already did this.

In my case this is my setup

  • pnpm
  • turbo
  • nextjs 13.x.x

I'm trying this

turbo run dev:debug

And i have a nextjs app called apps/web/package.json

"scripts": {
  "dev:debug": "NODE_OPTIONS='--inspect' next dev"

I see the debugger session:

web:dev:debug: > NODE_OPTIONS='--inspect' next dev
web:dev:debug:
web:dev:debug: Debugger listening on ws://127.0.0.1:9229/63260d0c-65a0-4fa7-8285-e42487920401
web:dev:debug: For help, see: https://nodejs.org/en/docs/inspector
web:dev:debug: - ready started server on 0.0.0.0:3000, url: http://localhost:3000

And going to the app on http://localhost:3000 I see Node debugger session
image

But if I open it any file of my app is there. Only react
image

I'm out of idea 😓

Adding commitzen command

Hi @belgattitude and thank you very much for this template, with it I was able to bootstrap a monorepo for our organization very quickly.

One tiny suggestion: I think having a commit linter only can be a bit frustrating without an interface to teach a contributor the commit convention used.
I've previously used commitzen which works as a vscode extension and npm package and I think with a bit of tweaking to make it aligned with the commit linter this would be a good feature added to this amazing template.

Pages directory cannot be found at /monorepo/pages or /monorepo/src/pages. If using a custom path, please configure with the no-html-link-for-pages rule in your eslint config file

It seems there can be some conflicts between eslint rules and mono repo file structure. I was seeing above error using @next/next/no-html-link-for-pages. I added to my app and it works now.

  settings: {
    next: {
      rootDir: 'apps/my-poney',
    },
  },

More info can be found here: vercel/next.js#26330

Thanks for the awesome how-tos and examples.

How do you allow PascalCase functions not to be linted by eslint?

Hi!

First of all, this is not an issue. Mark as question.

I have cloned your repo and tried to apply the same eslint configuration, which is awesome.

The problem I am facing is my PascalCase functions are being marked as errors by eslint, due to the following rule

      {
        selector: 'variable',
        format: ['camelCase'],
        leadingUnderscore: 'allow',
      },
      {
        selector: ['function'],
        format: ['camelCase'],
      },

So I had to add this in each project configuration:

    "@typescript-eslint/naming-convention": [
      "error",
      {
        "selector": ["function"],
        "format": ["camelCase", "PascalCase"]
      }
    ]

But you dont have anything like this. I was wondering... how did you make this work??

thanks in advance!

Babel 'decorators-legacy' syntax isn't currently enabled

Hello. I am currently migrating my old workspace setup to match the one from example. There seems to be an issue with TypeScript decorators when imported TS file is inside a monorepo, but outside the Next.JS app location.

  • I am using tsconfig path method, same issue is present with next-transpile-modules.
  • I have added the webpack config for Next.JS app.

This is the error:
image

My project structure is:
| packages
| -- components
| -- utils
| websites
| -- ts4u-client

next dev is being launched from 'websites/ts4u-client'.

Same decorators were working with my previous setup, where I had to precompile all 'packages' content before launching the next dev command.

Any ideas what could cause the problem?

Make repo size lower

Size starts to become big... Would like to remove some obsolete history, hope it does not break possible forks/clones...

Possible:

git clone https://github.com/belgattitude/nextjs-monorepo-example.git
cd nextjs-monorepo-example

git filter-repo --invert-paths --path .yarn --path apps/web-app --path apps/blog-app --path packages/bar --path packages/foo

git filter-repo --invert-paths --use-base-name --path-glob '*water*.png' --path-glob '*water*.jpg' 

-> du -h .git -> 260Mb to 53Mb

Optionnally all lock files

git filter-repo --invert-paths --path yarn.lock

To make it down to 13Mb

Then

git remote add origin https://github.com/belgattitude/nextjs-monorepo-example.git
git push origin --force --all

I'll investigate a bit

https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/removing-sensitive-data-from-a-repository

Problem with prisma in monorepo

Hi! I tried replicating your example with prisma in a monorepo but it seems like its not working, i've sent the error as an attachment. if you have encountered this error, could you tell me how you solved it? Thanks in advance

storybook recognizing tailwind config from outside

Hi,

I have a ui kit library and im migrating to a monorepo structure here

My structure is similar to the one here
├── apps
│ ├── docs (next.js app)
└── packages
├── components (the actual ui kit)
├── storybook

And the storybook workspace is used to develop the ui components from the componenets workspace. But for some reason storybook is not able to recognize the tailwind.config.js from /components workspace

Respect packages babel.config.js in apps

Hi!

Is there any way to respect babel.config.js files placed inside packages from inside apps? For example, In web-app I want to import Message component from packages/bar. This component is using css prop from @emotion/react.

cd packags/bar
yarn add -E @emotion/react @emotion/babel-plugin @emotion/babel-preset-css-prop
// packages/bar/babel.config.js

module.exports = {
  plugins: ['@emotion'],
  presets: ['@emotion/babel-preset-css-prop'],
}
// packages\bar\src\message.tsx
- <span>{props.message}</span>
+ <span css={{ color: 'red' }}>{props.message}</span>

With these changes yarn build inside bar package will work just fine.

But this will not work if Message is imported in web-app. I tried placing babel.config.js here and there but no luck. I know I can create extra babel.config.js inside web-app with similar content, but it doesn't sound right.

Thanks,

Rafał

Early cache invalidation in multistage Docker build

Hello - I'm not sure if this counts more as a question or an issue, as I am not sure if this is intentional or not.
So essentially, when running docker compose to build this project, if there is a change in any of the workspace files, an early build step is rerun, and the cache for all subsequent docker commands is also invalidated for some reason.

For example (from a fresh install):

  • Run docker compose -f docker-compose.nextjs-app.yml build runner
  • The cache has not yet been built, so this takes around 180 seconds to build on my machine
  • Run docker compose -f docker-compose.nextjs-app.yml build runner again
  • The cache has been built and no files have changed, so the build takes basically no time to finish (as it should)
  • In apps\nextjs-app\src\pages_app.tsx, add a single character to the comment on line 45 ( * Generally don't enable getInitialProp if you don't need to, -> * Generally, don't enable getInitialProp if you don't need to.)
  • Run docker compose -f docker-compose.nextjs-app.yml build runner again
  • In the first build stage (deps [7/7]), the yarn install --immutable --inline-builds command runs again, and takes 60 seconds to finish (specifically, jumping straight to the yarn 'link step'), and all subsequent commands in all following stages (builder and runner) are no longer cached.

This also occurs when the deps or builder stages are built only (ex. docker compose -f docker-compose.nextjs-app.yml build deps)

This is especially an issue in situations where one would want to create multiple builders/runners for different applications within the same dockerfile, as the 'deps' stage and all further stages would have to be rebuilt after every single change made throughout any of the packages/apps (even though none of the dependencies actually change).

This issue is currently affecting the most recent commit (3952f16) but also affects all of the previous versions I have tested up until now.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Location: renovate.json5
Error type: The renovate configuration file contains some invalid settings
Message: Invalid configuration option: packageRules[5].matchPackageName, packageRules[5]: Each packageRule must contain at least one match* or exclude* selector. Rule: {"groupName":"Soluble cache-interop","groupSlug":"soluble-cache-interop","matchPackageName":["@soluble/dsn-parser","@soluble/cache-ioredis","@soluble/cache-redis","@soluble/cache-interop"]}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.