How can bundle a monorepo node project into a single file? trying with ncc

Viewed 499

so I've got a tree something like

├── package.json
├── tsconfig.json
└── packages
    ├── lib1
    │   ├── package.json
    │   ├── src
    │   │   ├── index.ts
    │   └── tsconfig.json
    ├── lib2
    │   ├── package.json
    │   ├── src
    │   │   ├── index.ts
    │   └── tsconfig.json
    ├── graph
    │   ├── package.json
    │   ├── src
    │   │   ├── index.ts
    │   └── tsconfig.json
    └── peer
        ├── package.json
        ├── src
        │   └── index.ts
        └── tsconfig.json

where graph depends on lib2 which depends on lib1.

{
  "compilerOptions": {
    "target": "es2018",
    "module": "commonjs",
    "lib": ["es2018"],
    "moduleResolution": "node",
    "declaration": true,
    "strict": true,
    "esModuleInterop": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "sourceMap": true,
    "resolveJsonModule": true,
    "outDir": "build"
  },
  "exclude": ["**/node_modules", "**/build", "**/dist"]
}
{
  "extends": "../tsconfig-build.json",
  "compilerOptions": {
    "rootDir": "src",
    "outDir": "build"
  }
}

and when I build using this, everything is fine at compiletime


  "scripts": {
    ":g:tsc": "cd $INIT_CWD && tsc --project tsconfig-build.json",

but if I try using @vercel/ncc, I get compile time errors, like 'rootDir' is expected to contain all source files.

    "build": "ncc build src/index.ts",

I've tried using paths and references in my tsconfig.json, but neither of them worked for my purposes, and typescript doesn't seem to be correctly looking up the different modules. when I point it at the index.ts of peer it works correctly, but that has no workspace dependencies.

my end goal is to be able to ship a single js file to the docker container. How can I reach my goal?

1 Answers

We use Lerna to manage our Monorepo.

https://github.com/lerna/lerna

It allows having public & private packages. Public packages can be published to the registry and any package which have a dependency on others from the same Monorepo, have to be added as a dependency in package.json. Lerna can manage version incrementation on any changes that happen eventually in the dependent package.

We have implemented the auto-deployment by using GitHub actions to let Lerna publish the public packages to the GitHub registry and increment all packages includes private and commit changes to the master branch.

lerna.json

{
  "version": "independent",
  "packages": ["packages/*"],
  "npmClient": "yarn",
  "ignoreChanges": ["**/*.md"],
  "useWorkspaces": true,
  "command": {
    "version": {
      "conventionalCommits": true,
      "createRelease": "github",
      "exact": true,
      "message": "chore(release): publish",
      "preid": "next"
    },
    "publish": {
      "distTag": "latest",
      "preDistTag": "next",
      "registry": "https://npm.pkg.github.com/"
    }
  }
}
Related