I'm learning how to publish a typescript package to NPM. It's a simple package that just exports some random number functions, but eventually it'll do more:
src
/random
/index.ts
/index.ts
package.json
tsconfig.json
.gitignore
When I import the npm package into another typescript project, I get the following error:
import {Random} from "@whiterook6/my-package";
console.log(Random.randomInt(1, 10));
Cannot find module '@whiterook6/my-package' or its corresponding type declarations.ts(2307)
But if I change the import to this, it works:
import {Random} from "@whiterook6/my-package/src";
console.log(Random.randomInt(1, 10));
What have I done wrong in my library package to get this horrible result, and how can I change it so users can write these sorts of imports?
import {Random, Logger} from "@whiterook6/my-package";
Here's my tsconfig.json file:
{
"compilerOptions": {
"target": "ESNext", // Specify the ECMAScript target version
"module": "ESNext", // Specify the module code generation
"moduleResolution": "node", // Specify module resolution strategy
"declaration": true, // Generate declaration files
"emitDeclarationOnly": true, // Only emit declaration files
"outDir": "./src", // Redirect output structure to the directory
"rootDir": "./src", // Specify the root directory of input files
"strict": true, // Enable strict type checking options
"esModuleInterop": true, // Enable compatibility with CommonJS and ES modules
"skipLibCheck": true, // Skip type checking of declaration files
"forceConsistentCasingInFileNames": true // Ensure consistent casing in imports
},
"include": [
"src/**/*" // Include all files in the src directory
],
"exclude": [
"node_modules", // Exclude node_modules directory
"dist" // Exclude dist directory
]
}
if I change the import to [
import {Random} from "@whiterook6/my-package/src";
], it works
This means that your package.json
file does not specify "exports"
(otherwise it would not be possible to import arbitrary files from your package), nor "main"
entry point (or that the latter is incorrect).
You can use the "main"
field to specify what is returned when a consumer project imports the root of your package:
if your package is named
foo
, and a user installs it, and then doesrequire("foo")
, then your main module's exports object will be returned.
Therefore in your case you could do:
// package.json
{
"main": "src/index"
}
You can alternatively use the "exports"
field instead, as suggested in Tim Hansen's answer:
// package.json
{
"exports": {
".": "src/index"
}
}