avatarCharly Poly

Summary

The web content provides essential guidance for developing a TypeScript NPM module that is compatible with Node.js.

Abstract

The article "5 things to know when writing a TypeScript NPM module" outlines crucial considerations for developers aiming to create a module that supports both TypeScript and Node.js environments. It emphasizes the importance of structuring the package with a package.json that includes references to the transpiled JavaScript and TypeScript definitions, a tsconfig.json configured for Node.js compatibility, and an index.ts file at the root for easy importing. The use of a gulpfile for automating the build process and transpiling TypeScript to JavaScript is recommended, along with the inclusion of Jasmine for testing TypeScript code. The author also suggests using the --traceResolution option with the TypeScript compiler to troubleshoot module resolution issues and provides a public repository for a TypeScript package bootstrap.

Opinions

  • The author believes that targeting Node.js and TypeScript simultaneously in a single module can be challenging.
  • They recommend subscribing to updates on the topic, indicating a commitment to keeping the community informed with the latest practices.
  • The author expresses that the gulpfile should be straightforward, leveraging tools like gulp-typescript and gulp-jasmine.
  • They highlight the utility of the standard-version package for release management.
  • The author advocates for the inclusion of TypeScript definitions in the package to ensure type safety and proper integration with TypeScript projects.
  • They suggest that using the --traceResolution option during TypeScript compilation is a valuable technique for diagnosing issues with module resolution.
  • The author encourages community engagement by inviting readers to leave comments and contribute to the provided bootstrap repository.

5 things to know when writing a TypeScript NPM module

Cause targeting Node.js and TypeScript in one module isn’t that easy.

Note: This article will be soon updated in TypeScript Essentials. Subscribe and stay tuned ! 👋

Recently i started a library named spotify-graphql in TypeScript. I wanted the library to be “importable” in Node.js(v6) and TypeScript. Here are all the things to know that will save you hours.

Proposed Package structure

- package.json
- gulpfile.js
- lib/
   - myFile.ts
- spec/
   - myFile.spec.ts
- index.ts
- tsconfig.json

1. package.json

{
  "name": "my-package",
  "version": "0.0.0",
  ...
  "main": "dist/index.js", // for import from nodejs environments
  "typings": "definitions/index", // TypeScript definitions
  "typescript": {
    "definition": "definitions/index" // TypeScript definitions
  },
  ...
  "devDependencies": {
    "@types/node": "~6.0.46", // needed for Node.js targeting
    ...
  },
  "scripts": {
    "test": "gulp test",
    "release": "standard-version" // amazing package, seriously !
  },
  ...
  "dependencies": {
    "@types/jasmine": "^2.5.38" // need for using jasmine in TS !
  }
}

2. tsconfig.json

{
  "compilerOptions": {
    "lib": ["es6"], // we target Node.js(v6)
    "module": "commonjs", // export compatibility
    "target": "es5", // we target Node.js(v6)
    "moduleResolution": "node", // we target Node.js(v6)
    "declaration": true, // generate TypeScript definitions
    "rootDir": ".",
    "outDir": "dist", // transpile JS in this directory
    "types" : ["node", "jasmine"] // only use needed types
  },
  "include": [
    "index.ts",
    "lib/**/*",
    "spec/**/*"
  ]
}

3. gulpfile.js

The gulpfile is dead-simple.

It just uses : - gulp-typescript - gulp-jasmine

gulp.task('build', function() {
    const merge = require('merge2');
    const tsProject = ts.createProject('tsconfig.json');
var tsResult = tsProject.src()
        .pipe(tsProject());
return merge([
        tsResult.dts.pipe(gulp.dest('./definitions')),
        tsResult.js.pipe(
          gulp.dest(tsProject.config.compilerOptions.outDir)
        )
    ]);
});

the build task fetches the tsconfig.json compilerOptions and generate 2 things :

  • transpiled JS in outDir
  • - TypeScript definitions in ./definitions dir (only needed if tsconfig.json specify definitions: true)

4. the “index.ts story”

When doing the following :

import * from 'my-package'

tsc will start to search for a index.ts in node_modules and all possible directories. I found that by running tsc with — traceResolution option.

This option print all the path looked by tsc during module resolution, this is very helpful when a NPM module is “missing”.

So, when creating a TypeScript NPM module, remember to place a index.ts file a the root of your structure

5. Testing in TypeScript

In order to use Jasmine with TypeScript, you’ll need 2 things :

  • import Jasmine typings
  • transpile code to JS before running your specs

For the typing, see the “package.json” section.

Transpiling code before running the specs is done in the gulpfile, let’s take a glance :

gulp.task('test:run', function() {
   return gulp.src('dist/spec/**').pipe(jasmine())
});
// ...
gulp.task('test', [], function(cb) {
   runSequence('clean', 'build', 'test:run', cb);
});

As seen in “gulpfile.js” section, the build task transpile all JS (as specified in tsconfig.json) and store it in dist/ folder.

All we have to do is to send file located in dist/spec/ to jasmine, and “tada !”

I’ve made a public repo for bootstraping a TypeScript package : https://github.com/wittydeveloper/typescript-npm-module-bootstrap/

Feel free to leave a comment, and have fun !

JavaScript
Gulp
Typescript
Nodejs
NPM
Recommended from ReadMedium