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?