I'm having troubles with import of Inquirer using modules in Node 13.12.0. Any other import works well. As long as I've been using Node 12.x with require() it worked well.
My use-case of anything.mjs
import fs from "fs"; // works well
import inquirer from 'inquirer'; // undefined
So I've tried to import only one exported module
import {prompt} from 'inquirer'; // The requested module 'inquirer' does not provide an export named 'prompt'
also tried:
import * as inquirer from 'inquirer'; // [Module] { default: undefined }
I've also tried to require() but it is not defined in modules anymore.
How should I properly import Inquirer in Node 13.12.0 using modules?
According to the docs, you can use require in ESM in Node 13 as follows:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const inquirer = require('inquirer');
inquirer just released v9.0 and migrated to ESM modules.
So now this will simply work:
import inquirer from 'inquirer';
const response = await inquirer.prompt([
{
type: 'input',
name: 'question',
message: 'Want to answer?'
}
]);
console.log(response.question);
Using ES Modules and enquirer 2.3.6 I am using it this way. We could pass types to prompt object.
import enquirer from 'enquirer';
const enquirerObj = new enquirer();
const response = await enquirerObj.prompt({
type:'confirm',
name: 'question',
message: 'Want to answer?'
});
console.log(response);
Related
I am trying to import a .node binary addon in an ESM & Node Typescript based context. However, when I try to do this I get the following error "error TS2307: Cannot find module './addon.node' or its corresponding type declarations."
I've looked online for several solutions, these are my versions:
NodeJS: v16.14.1
ts-node: v10.7.0
Typescript: 4.6.3
This is my current approach for importing:
import addon from "./addon.node";
Just to note, because of my configuration I am limited to only using import.
Thanks in advance for any support.
Node.js import doesn’t support .node files. To import such files in an ESM context, you need to use createRequire:
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const addon = require('./addon.node');
You could also import the .node file in a CommonJS file that an ESM file then imports.
// addon.cjs
module.exports = require('./addon.node');
// main.js
import addon from './addon.cjs';
Finally, you could create an ESM loader that adds support for .node files to import, by wrapping the createRequire method into a loader (untested):
import { cwd } from 'node:process';
import { pathToFileURL } from 'node:url';
const baseURL = pathToFileURL(`${cwd()}/`).href;
export async function resolve(specifier, context, nextResolve) {
if (specifier.endsWith('.node')) {
const { parentURL = baseURL } = context;
// Node.js normally errors on unknown file extensions, so return a URL for
// specifiers ending in `.node`.
return {
shortCircuit: true,
url: new URL(specifier, parentURL).href,
};
}
// Let Node.js handle all other specifiers.
return nextResolve(specifier);
}
export async function load(url, context, nextLoad) {
if (url.endsWith('.node')) {
const source = `
import { createRequire } from 'node:module';
import { fileURLToPath } from 'node:url';
const require = createRequire(import.meta.url);
const path = fileURLToPath(${url});
export default require(path);`;
return {
format: 'module',
shortCircuit: true,
source,
};
}
// Let Node.js handle all other URLs.
return nextLoad(url);
}
Like this problem, same error is occurring while using svelte kit.
here is the error:
import { remove } from "ts-invariant/process/index.js";
^^^^^^
SyntaxError: Named export 'remove' not found. The requested module 'ts-invariant/process/index.js' 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 'ts-invariant/process/index.js';
const { remove } = pkg;
I'm using the current version(^3.5.10) of #apollo/client, and using the beta version(^3.6.0-beta.6) gets other error; while using import { ApolloClient, InMemoryCache, gql } from '#apollo/client/core/index.js', it gets:
Directory import '/node_modules/#apollo/client/core' is not supported resolving ES modules imported from /node_modules/svelte-apollo/dist/svelte-apollo.js
or if I use import { ApolloClient, InMemoryCache, gql } from '#apollo/client/core', it gets:
Directory import 'node_modules/#apollo/client/core' is not supported resolving ES modules imported from node_modules/svelte-apollo/dist/svelte-apollo.js
Did you mean to import #apollo/client/core/core.cjs?
or if I use import { ApolloClient, InMemoryCache, gql } from '#apollo/client/core/core.cjs' it just says
exports is not defined
I am trying to use Postgresql in a Node project. I am using modular imports, so I am having issues importing 'pg':
import * as pg from 'pg'
const { Client } = pg
let client = new Client()
leading to this error
let client = new Client()
^
TypeError: Client is not a constructor
I've looked at a couple other questions similar to this, but still have issues:
import { native as pg } from 'pg';
let client = new pg.Client()
leading to this error:
import { native as pg } from 'pg';
^^^^^^
SyntaxError: Named export 'native' not found. The requested module 'pg' is a CommonJS module, which may not support all module.exports as named exports.
Does anyone know what I can try to make this import correctly?
From the error suggestion, pg is a CommonModule which may not support all module.exports as named exports.
change the import from
import * as pg from 'pg'
to
import pg from 'pg'
will solve the import problem.
I am using Nestjs with WebStorm & TS 4.2.3^latest.
The problem that I am facing is a bit strange. For example, some modules, like axios can be installed, imported, and used as usual. But some modules, especially Nodejs Core, like fs or path, can't be imported as modules. BUT their methods can be imported and used just fine!
//ERROR: Module undefined on run:dev, but no error in IDE
import path from 'path';
import fs from 'fs';
//Working fine
import { join } from 'path';
import { readFileSync } from 'path';
I am sure, they have correct TS types, even installed manually. For example:
import axios from 'axios';
import path from 'path'; //path is undefined
import { join } from 'path'; // working fine
import { Injectable } from '#nestjs/common';
#Injectable()
export class AppService {
async test(input: string): Promise<void> {
await axios.get() // working fine
await path.join() // Cannot read property 'join' of undefined
//BUT await join() // Works fine!
}
}
I have only one tsconfig.json which is generated by Nest Cli. I am starting my apps via npm start:dev -name and IDE don't show any errors in code, until I ran code.
tsconfig.json module part, just to be sure: "module": "commonjs", package.json doesn't have module part at all.
IDE in this case, misdirect me a bit. Almost forgot, that I am dealing with TS now. Some modules seem to have no default exports, so:
You should import as with them: import * as fs from 'fs';
Or, another option is enabling: "esModuleInterop": true, in your tsconfig.json
Why do I get errors like these when I try to use the new Node.js support for ES6 modules (e.g. with node --experimental-modules script.mjs)?
// script.mjs
import * as fs from 'fs';
// TypeError: fs.readFile is not a function
fs.readFile('data.csv', 'utf8', (err, data) => {
if (!err) {
console.log(data);
}
});
// TypeError: fs.readdirSync is not a function
fs.readdirSync('.').forEach(fileName => {
console.log(fileName);
});
You must use import fs from 'fs', not import * as fs from 'fs'.
This is because (at least from the point of view of mjs files) the 'fs' module exports only one thing, which is called default. So if you write import * as fs from 'fs', fs.default.readFile exists but fs.readFile does not. Perhaps the same is true of all Node.js (CommonJS) modules.
Confusingly, in TypeScript modules (with #types/node and ES5 output), import fs from 'fs' produces error
error TS1192: Module '"fs"' has no default export
so in TypeScript you must write import * as fs from 'fs'; by default. It appears this can be changed to match the way mjs files work using the new "esModuleInterop": true option in tsconfig.json.
We can simply import like this it in our code
import * as fs from 'fs';
and it is perfectly working for me, give it a try