Babel ES6: Import node modules that need to be transpiled in ES6 as well - node.js

I am importing a node module correctly but run into an issue where the node module I am importing is written in es6 and babel is unable to transpile it.
In base class header:
import foo from 'bar/lib/foo';
in foo.js in node modules:
import Debug from 'debug';
export default class foo from bar {
...
...
...
}
Error Message:
import Debug from 'debug';
^^^^^^
SyntaxError: Unexpected token import
As you can see it is able to find the file foo.js but it is not running the node module in es6. How can I have Babel transpile both the base code as well as the node module that it is trying to import?

Do you have a file .babelrc with this content?
{
"presets": ["es2015"],
"plugins": []
}
You can check an example here: https://github.com/Talento90/ima-up

The node module should be compiled separately from your source code. If you are using an external lib, they should have a directory with the transpiled code. If you are writing your own, you need to use npm link and compile it separately.
If the node module already has a transpiled directory (like dist), you could try importing the transpiled code into the node module:
import foo from 'bar/dist/foo';

Related

"Cannot use import statement outside a module" without "type: module"

I've NodeJS app whit many file like this:
import '#babel/polyfill'
import app from './app'
./app is a js file: app.js and #babel/polyfill is a npm package
When I try to start my app with npm run dev i got this error:
SyntaxError: Cannot use import statement outside a module
I've seen that you can use "type": "module" on package.json to solve the problem
But this causes another problem:
Error [ERR_MODULE_NOT_FOUND]: Cannot find module './app' imported from /boot.js
I have many file that import modules and other files like that so i can't change them all
How do I keep the two type fo import?
If you only import babel like that you can setup babel for global import
This is .babelrc file on root folder:
{
"presets": [
"#babel/preset-env"
]
}

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.

How to import an npm module that has a Typescript main file in Typescript?

I can't figure out what's the proper way of importing a Typescript npm module.
Here's how I'm trying to do it:
module package.json
{
"name": "my-module",
"main": "src/myModule.ts"
}
module src/myModule.ts
export module MyModule {
// Code inside
}
code using the npm module
import { MyModule } from 'my-module'; // Doesn't work
import { MyModule } = require('my-module'); // Doesn't work.
The module is installed as a dependency in the package.json, and for example I can do
import { MyModule } from '../node_modules/my-module/src/myModule.ts';
But obviously this isn't great. What I want is a way to just import any exports that are in the main module file, but it doesn't seem possible.
The 'main' in package.json is useful only to packaging tools like webpack or the build tool of angular-cli. It is used to select different bundles according to the user's needs: ES6, ES5, UMD...
TypeScript ignores that. You need to specify the file you want, exactly as if you were refering to your own project:
import { MyModule } from 'my-module/src/myModule';
What other libraries like Angular do is to create a barrel, a file usually called 'index.ts' or 'index.d.ts', that imports and exports all types in the library.
The advantage of this is that, if you create a index.d.ts file in the root of my-module:
export { MyModule } from './src/myModule';
// other exports
You can simply do this:
import {MyModule} from 'my-module'
As typescript, when importing from a folder, automatically uses a index.ts or index.d.ts file.
You should use "types" property instead of "main" property with typescript modules. How TypeScript resolves modules

Resources