Working with yarn-workspace, specify the package root folder to have a nicer import path

Viewed 2149

Context

I am working with yarn-workspace and typescript.

Consider the following project structure :

project/
|- package.json
|- packages/
| |- common/
| | |- build/
| | | `- src/
| | |  |- myFile.d.ts
| | |  `- myFile.js
| | |- package.json
| | `- src/
| |  | `- myFile.ts
| |  `- tsconfig.json
| `- app/
|   |- package.json
|   |- src/
|   | `- index.ts
|   `- tsconfig.json
`- yarn.lock
// packages/common/src/myFile.ts
export function functionFromCommon(): void {
  console.log("Greetings from common");
}

Problem

My problem is that, when trying to reference functionFromCommon from the "app" folder, I have to write the following :

// packages/app/src/index
import { functionFromCommon } from 'common/build/src/myFile';

functionFromCommon();

What I would like is to find a way to only write import {} from "common/myFile" when referencing it from other packages.

I know I could bundle all of my common package in a single entry point index.js but I would like to keep the folder` structure as it is in order to write:

import { f1 } from "common/moduleA";
import { f2 } from "common/moduleB";

I tried to look into what could be specified in the package.json (some kind of "mainFolder" field) but couldn't find anything.

Additional information

For your information, the package.json files look like this :

// root package.json
{
  "name": "project",
  "license": "MIT",
  "workspaces": [
    "packages/*"
  ]
}
// packages/common/package.json
{
  "name": "common",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {},
  "devDependencies": {
    "@types/node": "^14.0.4",
    "typescript": "^3.9.3"
  }
}
// packages/app/package.json
{
  "name": "app",
  "version": "1.0.0",
  "license": "MIT",
  "dependencies": {
    "common": "1.0.0"
  },
  "devDependencies": {
    "@types/node": "^14.0.4",
    "typescript": "^3.9.3"
  }
}

And the tsconfig.json both are like this:

{
  "include": ["src"],
  "compilerOptions": {
    /* Basic Options */
    "incremental": true,
    "declaration": true,
    "target": "ES2020",
    "module": "commonjs",
    "sourceMap": true,
    "outDir": "./build",
    "types": ["node"],
    "composite": true,
    "tsBuildInfoFile": "./build/tsbuildinfo.json",

    /* Strict Type-Checking Options */
    "strict": true,

    /* Module Resolution Options */
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}

Update: (2020-10-13)

A new field called "exports" has been added to package.json to define just that. See more information here: https://nodejs.org/docs/latest-v12.x/api/esm.html#esm_exports_sugar.

But it is not currently supported by Typescript...

I was able to have a working version by following this workaround: https://github.com/microsoft/TypeScript/issues/33079#issuecomment-702617758.

0 Answers
Related