Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to share code between TypeScript projects?

Tags:

typescript

Let's say I have two projects with following file structure

/my-projects/    /project-a/     lib.ts     app.ts     tsconfig.json    /project-b/     app.ts         // import '../project-a/lib.ts'     tsconfig.json 

I want to consume lib.ts located in project-a also from project-b. How to do that?

  • Release it as NPM module - absolutely don't want that, it's an overkill for such a simple use case. I just want to share one file between two projects.

  • Use import '../project-a/lib.ts' - doesn't work, TypeScript complains

'lib.ts' is not under 'rootDir'. 'rootDir' is expected to contain all source files.

  • Put tsconfig.json one level up so it would cover both project-a and project-b - can't do that, the TypeScript config is slightly different for those projects. Also it's not very convenient, don't want to do that.

Any other ways?

like image 415
Alex Craft Avatar asked Dec 09 '17 14:12

Alex Craft


People also ask

How do I share TypeScript between projects?

The most common method is to publish our code to the npm registry, so it can be installed as a dependency in any other project where we'd like to use it. An alternative is to publish our code to a Git repository (it doesn't have to be GitHub, but usually it is) and then use npm to install it directly from there.

Is TypeScript good for small projects?

For all its hype, TypeScript is less a fast/new tool and, instead, makes writing JavaScript slower and more methodical, which can help regularize code and prevent common errors. On the flip side, however, TypeScript simply isn't worth it on some smaller projects, or if the project isn't well suited to static typing.

What is project reference in TypeScript?

Project references are a new feature in TypeScript 3.0 that allow you to structure your TypeScript programs into smaller pieces. By doing this, you can greatly improve build times, enforce logical separation between components, and organize your code in new and better ways.


2 Answers

Since Typescript 3.0 this can be done with Project References.

Typescript docs: https://www.typescriptlang.org/docs/handbook/project-references.html

I believe you would have to move lib.ts into a small ts project called something like 'lib'

The lib project should have a tsconfig containing:

// lib/tsconfig.json     {           "compilerOptions": {             /* Truncated compiler options to list only relevant options */             "declaration": true,              "declarationMap": true,             "rootDir": ".",                "composite": true,                },           "references": []  // * Any project that is referenced must itself have a `references` array (which may be empty).         } 

Then in both project-a and project-b add the reference to this lib project into your tsconfig

// project-a/ts-config.json // project-b/ts-config.json {         "compilerOptions": {             "target": "es5",              "module": "es2015",             "moduleResolution": "node"             // ...         },         "references": [             {                  "path": "../lib",                 // add 'prepend' if you want to include the referenced project in your output file                 "prepend": true,              }         ]     } 

In the lib project. Create a file index.ts which should export all your code you want to share with other projects.

// lib/index.ts     export * from 'lib.ts'; 

Now, let's say lib/lib.ts looks like this:

// lib/lib.ts export const log = (message: string) => console.log(message); 

You can now import the log function from lib/lib.ts in both project-a and project-b

// project-a/app.ts  // project-b/app.ts import { log } from '../lib'; log("This is a message"); 

Before your intelissense will work, you now need to build both your project-a and project-b using:

tsc -b  

Which will first build your project references (lib in this case) and then build the current project (project-a or project-b).

The typescript compiler will not look at the actual typescript files from lib. Instead it will only use the typescript declaration files (*.d.ts) generated when building the lib project.

That's why your lib/tsconfig.json file must contain:

"declaration": true, 

However, if you navigate to the definition of the log function in project-a/app.ts using F12 key in Visual Studio code, you'll be shown the correct typescript file. At least, if you have correctly setup your lib/tsconfig.json with:

"declarationMap": true, 

I've create a small github repo demonstrating this example of project references with typescript:

https://github.com/thdk/TS3-projects-references-example

like image 115
ThdK Avatar answered Oct 13 '22 06:10

ThdK


This can be achieved with use of 'paths' property of 'CompilerOptions' in tsconfig.json

{   "compilerOptions": {     "paths": {       "@otherProject/*": [         "../otherProject/src/*"       ]     }   }, } 

Below is a screenshot of folder structure.

enter image description here

Below is content of tsconfig.json which references other ts-project

{   "compilerOptions": {     "baseUrl": "./",     "outDir": "./tsc-out",     "sourceMap": false,     "declaration": false,     "moduleResolution": "node",     "module": "es6",     "target": "es5",     "typeRoots": [       "node_modules/@types"     ],     "lib": [       "es2017",       "dom"     ],     "paths": {       "@src/*": [ "src/*" ],       "@qc/*": [         "../Pti.Web/ClientApp/src/app/*"       ]     }   },   "exclude": [     "node_modules",     "dist",     "tsc-out"   ] } 

Below is import statement to reference exports from other project.

import { IntegrationMessageState } from '@qc/shared/states/integration-message.state'; 
like image 34
Oleg Polezky Avatar answered Oct 13 '22 04:10

Oleg Polezky