Build npm package with desired file structure - node.js

I have created a simple typescript project to export ENUMS, I successfully compile the project. tsconfig.json and package.json below.
I use the npm command to pack it and npm publish it also. I install the same package to a new project and I import the same with the code
import Numbers = require('#hk18/export/dist');
while I want to be like
import Numbers = require('#hk18/export');
It is including the dest folder in the package why so ?
{ "compilerOptions": {
"module": "commonjs",
"target": "es5",
"outDir": "./dist",
"moduleResolution": "node",
"declaration": true }, "include": [
"src/**/*.ts",
"index.ts" ] }
___________________________________________________________
{ "name": "#hk18/export", "version": "2.0.0", "description": "test project to create npm package", "main": "index.js", "scripts": {
"build": "tsc",
"build:watch": "tsc --watch",
"lint": "tslint --project \"./tsconfig.json\"",
"test": "mocha --reporter spec",
"docs": "typedoc --out docs src",
"gh-pages": "rimraf docs && npm run docs && gh-pages -d docs" }, "author": "HK", "license": "ISC", }

Your package.json is missing a types entry. It should match your main entry. Also your main should point to the dist folder as well.
Fixed Version
"main": "./dist/index.js",
"types" : "./dist/index.d.ts",

Related

Top-level await and Import in Typescript

I'm studying Typescript and running into a problem. I want to use the import and top-level await but currently, I can only use one at a time.
Here is my config in tsconfig.json which allows me to use import
"target": "ESNext",
"module": "ESNext"
And this one allows me to use top-level await:
"module":"commonjs"
I added
"type":"module"
to my package.json
Is there any way that I can take advantage of both features? Many thanks.
I'm using Nodejs 16 and Typescript 4.5.5
Yes, you can use both. Here's info to help you reproduce a successful test:
Node.js (LTS) version:
$ node --version
v16.14.0
./package.json:
{
"name": "so-71099311",
"version": "0.1.0",
"private": true,
"description": "",
"type": "module",
"scripts": {
"compile": "tsc",
"start": "npm run compile && node dist/main.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "MIT",
"dependencies": {
"#types/node": "^17.0.17",
"typescript": "^4.5.5"
}
}
./tsconfig.json:
{
"compilerOptions": {
"esModuleInterop": true,
"exactOptionalPropertyTypes": true,
"isolatedModules": true,
"lib": [
"esnext"
],
"module": "esnext",
"moduleResolution": "node",
"noUncheckedIndexedAccess": true,
"outDir": "dist",
"strict": true,
"target": "esnext",
"useUnknownInCatchVariables": true
},
"include": [
"./src/**/*"
]
}
./src/module.ts:
export function greet (name = 'world'): void {
console.log(`Hello ${name}`);
}
./src/main.ts:
import {greet} from './module.js';
const name = await Promise.resolve('Nguyen');
greet(name);
In your console:
$ cd /path/to/the/directory/where/you/created/these/files
$ npm install
$ npm run start
> so-71099311#0.1.0 start
> npm run compile && node dist/main.js
> so-71099311#0.1.0 compile
> tsc
Hello Nguyen

How to use a git+https dependency correctly

I am trying to use a git+https dependency (on github) to make a typescript library. I pared it down to a single file as an example and it is still failing. Using a file dependency works perfectly. Switching to a git+https dependency causes me to get an error:
export const Greeter = (name: string) => `Hello ${name}`;
^^^^^^
SyntaxError: Unexpected token 'export'
The two dependencies, nothing else changes in either project:
"#dgmyers/greeter": "git+https://git#github.com:dgmyers/typescript-greeter-library.git#v0.1.1",
"#dgmyers/greeter": "file:../typescript-greeter-library",
Files:
typescript-greeter-library/src/hello.ts
export const Greeter = (name: string) => `Hello ${name}`;
typescript-greeter-library/dist/hello.d.ts (tsc generated)
export declare const Greeter: (name: string) => string;
typescript-greeter-library/package.json
{
"name": "typescript-greeter-library",
"version": "1.0.0",
"description": "",
"main": "src/hello.ts",
"types": "dist/hello.d.ts",
"scripts": {
"clean": "rm -rf dist/*",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/dgmyers/typescript-greeter-library.git"
},
"author": "",
"license": "UNLICENSED",
"bugs": {
"url": "https://github.com/dgmyers/typescript-greeter-library/issues"
},
"homepage": "https://github.com/dgmyers/typescript-greeter-library#readme"
}
typescript-greeter-library/tsconfig.json
{
"compilerOptions": {
"sourceMap": true,
"lib": ["es2020"],
"target": "es5",
"declaration": true,
"moduleResolution": "node",
"emitDeclarationOnly": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"baseUrl": "./node_modules",
"outDir": "./dist",
"module": "commonjs",
"typeRoots": [
"./types"
]
}
}
consumer/package.json
{
"name": "consumer",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"run": "ts-node src/index.ts",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "UNLICENCED",
"dependencies": {
"#dgmyers/greeter": "git+https://git#github.com:dgmyers/typescript-greeter-library.git#v0.1.2",
"#types/node": "^16.3.1",
"ts-node": "^10.1.0",
"typescript": "^4.3.5"
}
}
consumer/index.ts
import { Greeter } from '#dgmyers/greeter'
console.log(`${Greeter('dgmyers')}`);
When installing via a source repo, ie. via the github: or git+https: protocol, npm will run the prepare lifecycle script and pack it like publishing it.
Generally, even your source repo is not in pure js (e.g. written in typescript) it's still fine because the script for compiling the source (e.g. tsc) is usually configured in prepare and npm will compile it when you install the repo.
However, there're still 2 scenarios it will fail.
missing the compilation script in prepare
missing the .npmignore file in the source repo so npm fallbacks to .gitignore which generally excludes the folder containing the compiled code
Mayne you've one of them.

Elastic Beanstalk "error TS2688: Cannot find type definition file for 'node'."

I'm trying to deploy an app to elastic beanstalk's NodeJs Platform (10.15.3) but as it builds (the Node commmand is npm start --production) I'm seeing the following errors in logs:
npm run build
app#1.0.0 build /var/app/current
tsc -p .
error TS2688: Cannot find type definition file for 'node'.
My package.json is the following (it includes #type/node:10.14):
{
"name": "app",
"version": "1.0.0",
"private": true,
"main": "dist/app.js",
"scripts": {
"build": "tsc -p .",
"prestart": "npm run build",
"watch": "tsc -w -p .",
"start": "node .",
"test": "echo \"Error: no test specified\" && exit 1"
},
"dependencies": {
"#types/morgan": "^1.7.35",
"#types/node": "^10.14",
"aws-sdk": "^2.411.0",
...
},
"devDependencies": {
"#types/express": "^4.16.1"
}
}
You should add types to your tsconfig.json
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"outDir": "dist-api",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"types": ["node"]
},
"include": [
"src/**/*.ts"
],
"exclude": [
"node_modules"
]
}

Starting node js service on local

I have a node js gradle application. I am not sure how to run the application locally.
I have done gradle build (./gradlew) and npm run build(compile). All my dependencies are in the node_modules.
I have a server.ts file having server code apart from the routing.
My package.json-
{
"name": "app",
"version": "..",
"description": "",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
"prepublish": "npm run build",
"build": "tsc",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"async-child-process": "^1.1.1",
..
},
"devDependencies": {
"#types/handlebars": "^4.0.36",
"#types/node": "^8.10.45",
"#types/pg-types": "^1.11.4"
}
}
How to run the project on the server.
tsconfig.json
{
"compilerOptions": {
"outDir": "./build/js/",
"sourceMap": false,
"noImplicitAny": false,
"module": "commonjs",
"declaration":true,
"target": "es2015"
},
"include": [
"src/main/ts/**/*.ts"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
Node.js will not run ts code. after build it'll js code in dist directory(depends on tsconf.json).
In package.json add below code, run npm run serve to start server.
or go to dist dir and run node server.js.
I have created a sample on GitHub check here
"scripts": {
"serve": "npm run build && npm run start",
"start": "node dist/server.js",
"build": "tsc"
}

Unable to get TypeScript watching my project and nodemon reloading it

Command tsc -w -p server watch the server directory compile TypeScript into dist/server folder (dist/server/app.js is the main Node script).
Command nodemon -w dist/server dist/server/app.js watches dist/server folder and reloads dist/server/app.js when something changes.
The problem: if I run both commands in parallel, tsc will take some times but nodemon starts too soon, when dist/server/app.js doesn't exist yet.
concurrently \"tsc -w -p server\" \"nodemon -w dist/server dist/server/app.js\"
On the other hand, if I run the commands sequentially I lost nodemon output (that is, the server output) because tsc will watch for changes and "steal" the console ouput:
tsc -w -p server\ && nodemon -w dist/server dist/server/app.js
I've tested both these strategies with nodemon and npm-run-all, a popular alternative.
Related questions (accepted answer doesn't solve the problem):
Is there a way to use npm scripts to run tsc -watch && nodemon --watch?
Adding a delay of 1000ms to nodemon fixed the issue for me.
https://github.com/remy/nodemon#delaying-restarting
nodemon.json
{
"watch": ["build"],
"ext": "js",
"exec": "npm start",
"delay": 1000
}
package.json
{
"name": "demo",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node build/index.js",
"ts": "tsc -w",
"nodemon": "nodemon",
"code": "concurrently -n ts,nodemon npm:ts npm:nodemon"
},
"devDependencies": {
"concurrently": "^4.1.0",
"nodemon": "^1.18.9",
"typescript": "^3.2.2"
}
}
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"target": "es2017",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
"outDir": "build",
"baseUrl": ".",
"paths": {
"*": [
"node_modules/*",
"src/types/*"
]
}
},
"include": [
"src/**/*"
]
}
npm run code

Resources