简体   繁体   中英

Monorepo with Lerna and TypeScript fails to import package by path alias

I am trying to setup a TypeScript based monorepo using Lerna where I have two packages, bar and foo . foo imports bar by path alias and fails doing so.

  1. tree
.
├── lerna.json
├── package.json
├── package-lock.json
├── packages
│   ├── bar
│   │   ├── lib
│   │   │   ├── index.d.ts
│   │   │   └── index.js
│   │   ├── package.json
│   │   ├── src
│   │   │   └── index.ts
│   │   ├── tsconfig.build.json
│   │   └── tsconfig.json
│   └── foo
│       ├── lib
│       │   ├── index.d.ts
│       │   └── index.js
│       ├── package.json
│       ├── src
│       │   └── index.ts
│       ├── tsconfig.build.json
│       └── tsconfig.json
├── tsconfig.build.json
└── tsconfig.json
  1. ./tsconfig.build.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "declaration": true
  }
}
  1. ./tsconfig.json
{
  "extends": "./tsconfig.build.json",
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@company/bar": [
        "packages/bar"
      ],
      "@company/foo": [
        "packages/foo"
      ]
    }
  }
}
  1. ./lerna.json
{
  "packages": [
    "packages/*"
  ],
  "version": "0.0.0"
}
  1. ./package.json
{
  "name": "root",
  "private": true,
  "scripts": {
    "tsc": "lerna run tsc"
  },
  "devDependencies": {
    "lerna": "^3.22.1",
    "ts-node": "^9.0.0",
    "ts-node-dev": "^1.0.0-pre.63",
    "typescript": "^4.0.3"
  }
}

Package bar :

  1. ./packages/bar/src/index.ts
export const bar = 'bar';
  1. ./packages/bar/package.json
{
  "name": "@company/bar",
  "version": "1.0.0",

  ...

  "main": "lib/index.js",
  "types": "lib/index.d.ts",
  "scripts": {
    "tsc": "tsc -p tsconfig.build.json"
  }
}
  1. ./packages/bar/tsconfig.build.json
{
  "extends": "../../tsconfig.build.json",
  "compilerOptions": {
    "outDir": "./lib"
  },
  "include": [
    "src/**/*"
  ]
}
  1. ./packages/bar/tsconfig.json
{
  "extends": "../../tsconfig.json"
}

Package foo :

  1. ./packages/foo/src/index.ts
import { bar } from '@company/bar';

console.log(bar);
  1. ./packages/foo/package.json
{
  "name": "@company/foo",
  "version": "1.0.0",

  ...

  "main": "lib/index.js",
  "types": "lib/index.d.ts",
  "scripts": {
    "tsc": "tsc -p tsconfig.build.json"
  }
}
  1. ./packages/foo/tsconfig.build.json
{
  "extends": "../../tsconfig.build.json",
  "compilerOptions": {
    "outDir": "./lib"
  },
  "include": [
    "src/**/*"
  ]
}
  1. ./packages/foo/tsconfig.json
{
  "extends": "../../tsconfig.json"
}

Finally:

Running npm run tsc compiles my packages, where foo imports bar . It gives me the following error:

> lerna run tsc

lerna notice cli v3.22.1
lerna info Executing command in 2 packages: "npm run tsc"
lerna info run Ran npm script 'tsc' in '@company/bar' in 2.4s:

> @company/bar@1.0.0 tsc /.../monorepo-lerna/packages/bar
> tsc -p tsconfig.build.json

lerna ERR! npm run tsc exited 2 in '@company/foo'
lerna ERR! npm run tsc stdout:

> @company/foo@1.0.0 tsc /.../monorepo-lerna/packages/foo
> tsc -p tsconfig.build.json

src/index.ts(1,21): error TS2307: Cannot find module '@company/bar' or its corresponding type declarations.

The error itself is pretty clear, though I do not know how to fix it (the path aliases inside ./tsconfig.json (3) look fine I guess). Any ideas where my configs are messed up? What point do I miss?

If I change import { bar } from '@company/bar'; to import { bar } from '../../bar/src'; everything works fine, however I would like to stick with the first way to import bar .

This is the part that allows you to import the packages as @company/bar

    "paths": {
      "@company/bar": [
        "packages/bar"
      ],
      "@company/foo": [
        "packages/foo"
      ]
    }

This is specified in ./tsconfig.json . When you try to compile package foo it is using ./packages/foo/tsconfig.build.json which never includes the root config or specify the paths itself, you probably want to remove the import scheme from the base tscofig and add them to the inner package configs:

./packages/foo/tsconfig.build.json should incorporate this:

{
  "compilerOptions": {
    "paths": {
      "@company/bar": [
        "../bar"
      ]
    }
  }
}

and similarly packages/bar/tsconfig.build.json should be allowed to import @company/foo if needed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM