Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import local package in typescript monorepo

Tags:

npm

typescript

Given a monorepo project. --project_root/ |--packageA/ |--index.ts |--package.json |--foo/ |--index.ts |--packageB/ |--index.ts |--package.json |--bar/ |--spam.ts Normally, when you are in packageA/index.ts and you want to import packageB/index.ts you would do import index from '../packageB',

and when you are packageA/foo/index.ts and you want to import packageB/index.ts you need to move two directory up import index from '../../packageB'

The question is, is there a way to import like import index from 'packageB and for nested folder import spam from 'packageB/bar/spam'?

EDIT

I have uploaded a github repo to demo the issue https://github.com/jaimesangcap/lerna-ts-monorepo

like image 356
Jaime Sangcap Avatar asked Nov 20 '18 18:11

Jaime Sangcap


1 Answers

You can do this by specifing the base url and (in more complicated cases) by using path mapping.

If you have a tsconfig.json in project_root, you can achieve the desired import strategy by defining

"compilerOptions": {
  "baseUrl": "."
}

This works if the package name always corresponds with the folder name of the sub-project.

If this isn't the case, you can use paths:

"compilerOptions": {
  "baseUrl": ".", // This must be specified if "paths" is.
  "paths": {
    "A": ["packageA"],
    "B": ["packageB"],
    "A/*": ["packageA/*"],
    "B/*": ["packageB/*"]
  }
}

This will cause typescript to correctly resolve the types of import during compilation. However the import paths are not resolved in the compiled javascript, which means it is necessary to tell the next step in your pipeline (usually a bundler like webpack) how to resolve these imports as well. For webpack specifically this can by done by specifying an alias in the webpack config:

resolve: {
  alias: {
      A: path.resolve(__dirname, 'packageA/'),
      B: path.resolve(__dirname, 'packageB/')
  }
}

If you want to execute the typescript files directly, ts-node is the easiest way to do so, since it will already know about the modified paths from the typescript config if you use tsconfig-paths - in this case you just have to execute the file using ts-node -r tsconfig-paths/register packageA/index.ts (ts-node and tsconfig-paths have to be installed via npm)

like image 173
Johannes Reuter Avatar answered Nov 04 '22 15:11

Johannes Reuter