Import native node modules correctly in Typescript - node.js

I've been using node for quite a while now (for my backends) and typescript with ionic (for frontend). On Ionic i realize I have managed to avoid many pitfalls and errors just because of TypeScript. I have hence decided to convert all my backends that are in pure JS to TypeScript.
The first obstacle I've run into is how to import native node modules like http, os and child_process, among others, correctly.
On most modules you can usually do something like import { some_export } from 'that_module'. I can also see the type definitions for node in the #types/ repo. I've tried import { http, os } from 'node' but I get a complaint that
/node_modules/#types/node/index.d.ts is not a module
My question hence is how should I import native node modules?

I've managed to solve this issue thanks to some light reading from this simple tutorial
To my understanding, the native modules are standalone modules that are not namespaced under node. You should therefore import from them directly.
Simply done so:
import * as http from "http";
import * as os from "os";
import * as path from "path";
.
.
.
and so on

Related

Convert old CJS module into ESM and import into TS files

I am wanting to convert an old module, https://github.com/capaj/object-resolve-path, into ESM so I can use it via an import statement, in order to move all my NodeJS Lambda functions to ESM.
I have forked the repo, and changed the 2 main .js files to .mjs, updated the exports, as well as update the main property in package.json to point to the object-resolve-path.mjs file.
In my NodeJS Lambda function, I have then installed the fork via NPM from my private repo, which pulls the new code in.
However, when I try to import the package in my code now, using import * as resolvePath from 'object-resolve-path'; I get an error:
Could not find a declaration file for module 'object-resolve-path'.
What am I missing? The module isn't written in TS, so why is it asking for a declaration file?

How to make ES modules import from a Lambda layer work?

I have a lambda function in node v14 that imports AWS SDK v3 from a lambda layer.
In my function I can use my node modules from the layer only if I use CommonJS syntax:
const { parseUrl } = require('#aws-sdk/url-parser');
Using ES modules doesn't work.
import { parseUrl } from '#aws-sdk/url-parser';
It will throw an error:
"errorMessage": "Cannot find package '#aws-sdk/url-parser' imported from /var/task/index.js\nDid you mean to import #aws-sdk/url-parser/dist-cjs/index.js?"
It should work. I have "type": "module" in package.json and locally the import works.
It also starts working when I specify the full path to cjs index file:
import { parseUrl } from '/opt/nodejs/node_modules/#aws-sdk/url-parser/dist-cjs/index.js';
Which is really weird.
I checked NODE_PATH and /opt/nodejs/node_modules is there so I don't know where the problem is.
The full implementation is here so you can replicate the error:
https://github.com/simon-q/lambda-layer-es-modules-error
Is it something broken in lambda layers or am I doing something wrong?
I would really appreciate any help.
Thanks.
it's a path error for files in node_modules folder. In this link you can get more details about the problem.
I created a serverless plugin that fixes it automatically, hope it helps someone. Follow the link: https://www.npmjs.com/serverless-esm-layer

TypeScript - how to import 'os' module

I'm learning Typescript. To do this, I'm building a basic utility app with Node for myself. For this app, I need to use Node's OS Module. My question is, how do I import this module?
In my Typescript file, I have the following:
import { os } from 'os';
This line generates the error: "Cannot find module 'os'". What am I missing?
This line generates the error: "Cannot find module 'os'". What am I missing?
The correct code is
import os from 'os';
Also make sure you have npm i #types/node
More
Some notes I wrote on NodeJS quickstart : https://basarat.gitbook.io/typescript/docs/quick/nodejs.html
Just to update this entry:
import * as os from 'os';
and later, you can use:
const hostname = os.hostname();

Isomorphic import of CommonJS modules

I've written a small library that's meant to run both in the browser and on the server. The library in turn uses npm libraries published as CommonJS modules (e.g. lodash.isequal).
I'd like to compile the library two different ways:
Using tsc, generating commonjs modules for use on the server
Through webpack, using the awesome-typescript-loader, generating es6 modules for webpack to bundle
Per the docs, the correct way of importing CommonJS libraries which override module.exports is as follows:
import isEqual = require('lodash.isequal');
However for the second compilation case, typescript complains that
error TS1202: Import assignment cannot be used when targeting ECMAScript modules. Consider using 'import * as ns from "mod"', 'import {a} from "mod"', 'import d from "mod"', or another module format instead.
I've managed to get code generation to work properly by importing it as:
import * as isEqual from 'lodash.isequal';
but that requires disabling typechecks, since otherwise typescript complains with errors like the following:
error TS2497: Module '"/home/user/ts-mod-test/node_modules/#types/lodash.isequal/index"' resolves to a non-module entity and cannot be imported using this construct.
Since TypeScript 2.7, this issue can be resolved by using synthetic default imports. Using the esModuleInterop flag, isEqual (and similar modules) can be imported like in babel and webpack:
import isEqual from 'lodash.isequal';
For webpack with the module option set to es6, the import will be left as-is, and webpack itself will handle the synthetic default. For node, with module set to CommonJS, the corresponding emit will be const lodash_isequal_1 = __importDefault(require("lodash.isequal"));, where the __importDefault handles the non-es module case like Babel

How to force tu use RTCPeerConnection from AdapterJS

I tried to add RTCPeerConnection from adapterJS, but my typescript wouldn't allow me to do that.
Always import from lib.es6 instead off adapterJS.
I installed adapterJS via this command npm install webrtc-adapter --save
And I tried to do sth like this:
import RTCPeerConnection from 'webrtc-adapter';
or
import adapter from 'webrtc-adapter';
But it always fails.
What I'm doing wrong guys?
That was totally misunderstanding!
Adapter is working out of the box, it's the layer between my component and the javascript interpreter in browser.
So adapter is working fine, I don'w have to import them.
All I have to do is import 'webrtc'; in typings.d.ts

Resources