dev0experiment
dev0experiment

Reputation: 520

Simple import statements for npm package

I want to publish new npm TypeScript package and I want to be able to use simple import statements (import multiple classes from library via single line) in my project e.g.:

import { FirstClass, SecondClass } from "my-repo";

At this time I have to use many longer import statements e.g.:

import { FirstClass} from "my-repo/first-class";
import { SecondClass } from "my-repo/second-class";

In the beginning, I have built the package with tsc -p . to dist and then run npm publish. Now I am experimenting with pikapkg/pack to make the build process easier, however I still have to use the long import statements.

Is there any tool to automatically create a package with a single file to import from (index.ts which is places as main in package.json) or have I to manually create main index.ts with all classes exported and each time I will add a new class add it also to index.ts again?

Upvotes: 4

Views: 919

Answers (1)

Milan Tenk
Milan Tenk

Reputation: 2715

There are two approaches to do this.

Installing in node_modules

In this case we want to install the library in the node_modules of the consumer and use Node module resolution.

The Node module resolution configuration means, that the TypeScript compiler looks for the node_modules directory in your workspace and if there is an exported code in it which matches your import statement then it will be able to resolve it with the short import statement. You can find details about this here.

If you have your library published and deployed in a registry (for example to https://registry.npmjs.org/ or in an Artifactory repository etc.) then add the deployed library to the package.json of the consumer as dependency and install it with npm install. With this step, the library will be installed in node_modules and if in the tsconfig.json you have in the compiler options Node module resolution configured then the TypesSript compiler will be able to resolve the short import statement.

This approach assumes that you have the library deployed into a registry. If you have your library only local, then the CLI of install-local can help you to install the library in node_modules locally without any deployment. But there is an alternative to this, see therefore the next section.

Referencing the published source directly from dist

In the tsconfig.json of the consumer project you can specify your locally published modules in the paths of the compilerOptionssettings (see details compiler options). This way the TypeScript compiler will resolve the dependencies from the configured paths as well. It follows you don't need to install your dependency in the node_modules to use the short import statement, the compiler will find them following the configured paths.

Let's say I have a library called my-lib. The dist folder looks following:

dist
-->my-lib
---->{all the published files of my-lib}
-->my-app
---->{all the published files of my-app}

In this case an example tsconfig.json of the consumer looks like this:

{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./",
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "es2015",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ],
    "paths": {
      "my-lib": [
        "dist/my-lib"
      ],
      "my-lib/*": [
        "dist/my-lib/*"
      ]
    }
  }
}

Above in the paths both my-lib and my-lib/* are needed. my-lib is what can be used in the short import statement, for example this way:

import { MyLibModule } from 'my-lib';

The paths after those entries in the tsconfig point to the published library in dist.

As far as I know the exports have to be done manually in the index.ts of the package.

Upvotes: 2

Related Questions