0

I am creating a large Typescript library that I'll call feature-lib that I want to use in other projects. In this project I'm using baseUrl: 'src' so that I can have import statements that aren't full of ../../../../../... The code provided below is not a "great" example of the problem, but it works.

Problem

The project where I'm importing feature-lib throws an error at compile time:

Module not found: Error: Can't resolve 'feature-a/components/test-component' in 'C:\dev\my-project\node_modules\feature-lib\feature-a'
WARNING in ./node_modules/feature-lib/feature-a/utils.js
Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from 'C:\dev\my-project\node_modules\src\feature-a\utils.ts' file: Error: ENOENT: no such file or directory, open 'C:\dev\my-project\node_modules\src\feature-a\utils.ts'

ERROR in ./node_modules/feature-lib/feature-a/utils.js 1:0-83
Module not found: Error: Can't resolve 'feature-a/components/test-component' in 'C:\dev\my-project\node_modules\feature-lib\feature-a'

Directory structure

├── src
|   ├── feature-a
│   |   ├── components
│   |   |   ├── index.ts
│   |   |   ├── test-component.ts
│   |   ├── index.ts
│   |   ├── utils.ts
│   ├── index.ts
├── package.json
├── tsconfig.json

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "baseUrl": "src",
    "outDir": "dist",
    "rootDir": "src",
    "declaration": true,
    "allowJs": false,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": false,
    "jsx": "preserve",
    "sourceMap": true,
    "noImplicitAny": true
  },
  "include": [
    "src"
  ]
}

package.json

{
  "name": "feature-lib",
  "version": "0.1.0",
  "description": "",
  "type": "module",
  "main": "dist/index.js",
  "module": "dist/index.js",
  "types": "dist/index.d.ts",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "clean": "rm -rf ./dist",
    "build": "npx tsc"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "typescript": "^4.9.5"
  }
}

test-component.ts

export class TestComponent {
    constructor() {
        console.log("hello from TestComponent");
    }

    getText() {
        return "hello from TestComponent";
    }
}

utils.ts here the import for TestComponent is based on baseUrl from tsconfig.json instead of a relative url as an example of the problem.

import { TestComponent } from "feature-a/components/test-component";
// instead of
// import { TestComponent } from "./components/test-component";

const testComponent = new TestComponent();

export function getTestComponentText() {
    return testComponent.getText();
}

App.tsx from my-project

import { getTestComponentText } from 'feature-lib/feature-a/utils';

import './App.css';

export function App() {
  return (
    <div className="App">
      {getTestComponentText()}
    </div>
  );
}

There must be someway to "rewrite" the generated import statements to be relative to the current file, no?

Jeff Tillwick
  • 41
  • 1
  • 9

0 Answers0