How to require a node package that wants to be a module, without type: module - node.js

I need to import a module to my project.
When I do const gifsicle = require('gifsicle'); it tells me:
ReferenceError: require is not defined in ES module scope, you can use import instead
When I try to do import, it says
SyntaxError: Cannot use import statement outside a module
Other threads say to fix this I have to add "type": "module" to my package.json
But doing so gives me this error:
ReferenceError: require is not defined in ES module scope, you can use import instead
How do I load in an ES module package into my current non-module package which uses require?

First of all add "type":"commonjs" to package.json.
Downgrade your package version. If you are using let suppose version 8.0.0 then install older version like npm i package-name#7.1.0.
That's all now enjoy coding...

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?

Running into error when importing xterm.js in node.js

I am new to node.js, I am trying to run some node.js code from here:
https://xtermjs.org/docs/api/addons/attach/
I got an error:
(node:1576) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
So I renamed the file to .mjs, and I got an error:
import { Terminal } from 'xterm';
^^^^^^^^
SyntaxError: Named export 'Terminal' not found. The requested module 'xterm' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'xterm';
const { Terminal } = pkg;
I followed its suggestion but it just printed a bunch of source code and then error: ReferenceError: self is not defined
What is the right way to do it?

'ReferenceError: require is not defined' while importing fs module

I am new to NodeJS. I was importing the 'fs' module in NodeJS and this happened.
Is this because of the new import syntax in the current versions?
What went wrong?
Thanks in advance!
This is because something is telling nodejs that this is the newer ESM module. This could be your package.json file or something else. In an ESM module file, you use import, not require() to load modules.
You can see in the stack trace where it shows Object.loadESM and that's how you know it is trying to load this module as an ESM module.
With an ESM module, perhaps you want this:
import fs from "fs";
or
import * as fs from'fs';
Or, if you intend to use a CommonJS module instead (where you can use require()), then we need to see your package.json file to figure out why the loader is attempting to load your file as an ESM module.

How can I dynamically import both commonJS and ES6 modules from the same node CLI?

I have looked through many similar questions on SO, and haven't found a clear answer.
I'm writing an npm CLI tool which is supposed to dynamically import a specified module and run some operations on that module's exports.
In my npm package, I have specified "type": "module" and my binary is bin/generator.mjs.
The way I'm trying to use it is: ❯ ./bin/generator.mjs path/to/test-module.js [other args] - and then in the generator I do:
const modulePath = "file://" + path.resolve(inputFilename);
const objs = await import(modulePath);
With this configuration, I can specify an ES6 module on the command line, and the generator works fine, however, if I specify a CommonJS module, I get:
const Library = require('some-library');
^
ReferenceError: require is not defined
Here are my two test files:
ES6 module
import Library from 'some-library';
export const person = { firstName: "Bob", lastName: "Mortimer };
CommonJS module
const Library = require('some-library');
const person = { firstName: "Bob", lastName: "Mortimer };
module.exports.person = person;
So then I tried having two different binaries - generator for ES6 modules, and generator-cjs for CommonJS ones - I modified the original to use requires in place of import, however, the bin/generator.mjs continues to work fine, but the bin/generator.cjs throws this error:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: [...]/test-module.js
require() of ES modules is not supported.
require() of [...]/test-module.js from [...]/bin/generator.cjs is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename test-module.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from [...]/package.json.
If I remove "type": "module" from my package.json, both generator and generator-cjs work on CommonJS files, but generator throws this error on ES6 modules:
throw new Error('Unexpected import statement in CJS module.');
^
Error: Unexpected import statement in CJS module.
Ideally: I want to have one binary that can import both CommonJS and ES6 modules dynamically.
If you have read through this far - thank you.
Do you have any ideas on how I can resolve this? Let me know if you want me to try things to provide more information.
Thanks,
Edit: I should mention that converting the CommonJS modules to ES6 is not an option as there are nearly a hundred CJS ones, and they have complicated dependency chains that will take time to unravel.

Why am I getting a "Cannot find module" err when compiling Typescript?

I am just getting started using typescript on the server and I'm pretty much stuck trying to import 3rd party npm modules. Here is what I have declared:
import mongodb = require('mongodb');
import assert = require('assert');
import Q = require('q');
... and I am getting the following errors when compiling:
src/Databse.ts(1,26): error TS2307: Cannot find module 'mongodb'.
src/Databse.ts(2,25): error TS2307: Cannot find module 'assert'.
src/Databse.ts(3,21): error TS2307: Cannot find module 'q'.
What is the correct way to import 3rd party modules?
It doesn't feel the correct way to import 3rd party's library. You can simply use only import
import "library";
OR
import {module} from "library";
Note:- when you are using above syntax then you need to make your that
the module you are importing exist otherwise you will get the error
that it can't find the module you are trying to import.
If you want to use webpack then
require("library");
Or like this
var module = require("library");
Have you installed the typing declarations ?
typings install mongodb --save
typings install dt~assert --save
typings install dt~q --save
Then you will need to reference the typings.
Either using the triple slash-directive
/// <reference path="..." />
More about it here Triple-Slash Directives
Or add the typings index.d.ts file in files array in tsconfig.json
"files": [
"./typings/index.d.ts",
]

Resources