express-validator usage with ESM modules - javascript

I tried to import into an ESM module with this syntax in Node.js v8.7.0 with --experimental-modules flag:
import { check, validationResult } from 'express-validator/check';
import { matchedData, sanitize } from 'express-validator/filter';
However I'm getting the following error:
(node:29028) ExperimentalWarning: The ESM module loader is experimental.
SyntaxError: The requested module does not provide an export named 'check'
at checkComplete (internal/loader/ModuleJob.js:86:27)
at moduleJob.linked.then (internal/loader/ModuleJob.js:69:11)
at <anonymous>
What is the correct usage with ESM modules turned on with --experimental-modules flag?
I tested with #std/esm package also. It only works of I turn cjs: true.

This happens because, in Node.js, CommonJS modules imported via import only have a default export*.
If the module you're importing is not an ES Module (which is the case of express-validator), then all you can do is something like this:
import checkAPIs from 'express-validator/check';
import filterAPIs from 'express-validator/filter';
const { check, validationResult } = checkAPIs;
const { matchedData } = filterAPIs;
* Source: https://medium.com/the-node-js-collection/an-update-on-es6-modules-in-node-js-42c958b890c

Use This...
import validator from 'express-validator'
const { check, validationResult } = validator

Now, when doing from 'express-validator/check', for example, it says, requires to express-validator/check are deprecated.You should just use require("express-validator") instead. 🙄 Ironically, so are CommonJS modules to some extent.
import validator from 'express-validator'
const { body } = validator

Related

Upgrade js file to use import

I'm trying to upgrade to use import instead of requires for modules:
My old code looked like so:
const { NETWORK } = require(`${basePath}/constants/network.js`);
The network.js File:
export const NETWORK = {
eth: "eth",
sol: "sol",
};
module.exports = {
NETWORK,
};
When ever I try to import i've tried a few syntaxes):
import { NETWORK } from '../constants/network.js';
import NETWORK from '../constants/network.js';
import * as NETWORK from '../constants/network.js';
I get an error:
This file is being treated as an ES module because it has a '.js' file extension and '..\package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
at file:///../constants/network.js:6:1
at ModuleJob.run (node:internal/modules/esm/module_job:193:25)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:526:24)
at async loadESM (node:internal/process/esm_loader:91:5)
at async handleMainPromise (node:internal/modules/run_main:65:12)
When I try to rename the file to be network.cjs I get an error:
SyntaxError: Unexpected token 'export'
how can I import variables from js files using import?
You need to remove the unnecessary "module.exports" part from your network.js, because that is the way to export stuff in commonjs. Your first line of import will work after that import { NETWORK } from '../constants/network.js'; so remove the other ones

node: getting error importing CommonJS module however I try to import it

I have a local node module, #em/inVis in my company whose index.d.ts file looks as follows:
import UWeb from "./UWeb";
import UWebParams from "./UWebParams";
export { UWeb, UWebParams };
elsewhere within the app, it's used as follows in typescript files
import { UWeb, UWebParams } from "#em/inVis";
when I try to do that in my TS file, I get the node error:
SyntaxError: Named export 'UWeb' not found. The requested module '#em/inVis' 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 '#em/inVis'; const { UWeb, UWebParams } = pkg;
so when I try using that approach suggested above, I am getting the node error:
SyntaxError: Cannot use import statement outside a module not sure
what I am doing wrong.

Rollupjs Leave imports unchanged

My input file looks like this:
import * as chalk from 'chalk'
const chalkInstance = new chalk.Instance({
level: 1
})
My output file looks like this:
import { Instance } from 'chalk';
const chalkInstance = new Instance({
level: 1
});
The problem is that chalk is a commonjs module and I want to my output to be an es module so when I execute the file I get the following error: The requested module 'chalk' is expected to be of type CommonJS, which does not support named exports etc. Is there a way to prevent Rollup from changing the import * as something imports? The problem doesn't go away even if I disable treeshaking.
Thank you in advance!
Preserving the import as typed won't help you — you need to do import chalk from 'chalk' instead, since CommonJS modules only have a default export. If you do preserve the import you'll still get an error, it'll just be a different error:
const chalkInstance = new chalk.Instance({
^
TypeError: chalk.Instance is not a constructor

How to publish a library to npm that can be used both with import and require?

tealium-tracker is written in es6 and transpiled using Babel before published to npm.
When consumers do:
import initTealiumTracker from "tealium-tracker";
everything works as expected.
However, some consumers want to use a require instead of an import, and have to append .default:
const initTealiumTracker = require("tealium-tracker).default;
How could I publish the library to avoid appending .default?
I want consumers to be able to do either:
import initTealiumTracker from "tealium-tracker";
or
const initTealiumTracker = require("tealium-tracker);
Source code
In your source code, If you are ok with using commonJS syntax for import and export...
One option would be to replace all import and export with require and module.exports. Looks like webpack doesn't allow mixing the syntaxes (ES6 and commonJS modules).
So your index.js file can require the functions from dependent module as
const { callUtag, flushUtagQueue } = require("./utagCaller");
and export the default function as
module.exports = initTealiumTracker;
module.exports.default = initTealiumTracker;
Likewise your dependent module can export the functions as
module.exports = { callUtag, flushUtagQueue };
This way, consumers should be able to use either
import initTealiumTracker2 from "tealium-tracker";
OR
const initTealiumTracker1 = require("tealium-tracker");

What is the best way of import modules from complicated path in ESModules

In CommonJS, I use this way.
require(constant.APPROOT + "/lib/utils.js")
instead of
require("../../../../../../lib/utils.js")
However, It cannot work in ESModules.
import util from constant.APPROOT + "/lib/util.js"
// Uncaught SyntaxError: Unexpected identifier
I know the reason, because it is not static.
I try two way.
[1st] (accept complicated path)
import path from "path"
import fs from "fs"
import foo from "./foo.js"
import bar from "../../../../../lib/bar.js"
import util from "../../../../../lib/util.js"
// application code
[2nd] (use dynamic import)
import path from "path"
import fs from "fs"
import foo from "./foo.js"
!async function main(){
const [bar, util] = await Promise.all([
import(constant.APPROOT + "/lib/bar.js"),
import(constant.APPROOT + "/lib/util.js"),
])
// application code
}()
I think that both is not good.
What is the best way?
1. Webpack
You could use webpack to setup an alias (if you are building a node app then set target: node in your config, there are plenty of good guides on how to accomplish this):
resolve: {
...,
alias: {
'$lib': constant.APPROOT + "/lib"
}
}
Then import like --> import util from "$lib/util.js"
2. Npm Package
You can use this package to setup aliases in package.json --> https://github.com/ilearnio/module-alias

Categories

Resources