error TS2307: Cannot find module 'crypto' - node.js

Im writting a web with Angular 6. I need to hash a string client-side, so i'm using createHash("sha256") from 'crypto'.
actually, I just wrote createHash and vscode suggest me the import, which looks like this:
import { createHash } from "crypto";
(this way of importing seems to be fine, and it's used in some typescript tutorial, here) and then:
var hashed = createHash("sha256").update(data).digest()
all syntax is being suggested by vscode, with docstrings and everything. But at the moment of compile with npm start I get:
ERROR in src/domain/User.ts(2,28): error TS2307: Cannot find module 'crypto'.
as far as I could understand, crypto is now built-in into node, and I shouldn't have any problem importing it.
also notice that if I run node in terminal to open a REPL, entering 'crypto' gives me an output that suggest that everything works well.
Here are the versions of everything I think that cares:
node --version: v10.15.1
ng --version:
Angular CLI: 6.2.9
Node: 10.15.1
OS: linux x64
Angular: 6.1.10
typescript 2.9.2
webpack 4.16.4
Any help will be appreciated.

For Typescript 2.* and Angular 2+ -
Install and add this package to the devDependencies.
npm install #types/node --save-dev
In tsconfig.app.json under the compilerOptions, add this -
"types": [ "node" ],

You need to install the dependency. There was the same question, try to do the same, it must help How to use 'crypto' module in Angular2?

I had the same issue. The first solution I found was to add the following to packages.json
"browser": {
"crypto": false
}
Since all I wanted was to generate a sha256 digest to use a an index I removed crypto-js and #types/crypto=js and replaced it with jshashed.
yarn add jshashes
I then modified my digest service to reflect the new library:
import { Injectable } from '#angular/core';
import * as JsHashes from 'jshashes';
#Injectable({
providedIn: 'root'
})
export class CryptoService {
getSha256HEX(value: string): string {
const hash = new JsHashes.SHA256;
return hash.hex(value);
}
}
Simply add CryptoService to your module file apps.module.ts
import { CryptoService } from '#services/crypto.service';
Note: The #services path defined in tsconfig.json
All that is left is to declaref CryptoService in the constructor were needed:
constructor( private _crypto: CryptoService; ) {}
and use it by passing a string, or if compound data (like and HTTP query string to build a cache key) stringify it.
myHash = this._crypto.getSha256HEX(JSON.stringify(_compoundDataStruccture));
Note: jshashes supports
Digests:
MD5
SHA1
SHA256
SHA512
HMAC
RIPEND-160
Also:
Base64 encoding/decoding
CRC-32 calculation
UTF-8 encoding/decoding

If you are making a server side application for NodeJs using typescript then you simply need to install #types/node using npm i #types/node -D and then you should be able to import it using import * as crypto from "crypto"

Related

Swiper.js React compile failing

I'm trying to update the swiper.js library
I was using swiper version: 6.8.2,
Now I would like to upgrade it to a newer version 7.4.1
My App is written in React and Node js with SSR( I'm not using Next.js) and Node version: v14.11.0
Here is how my component code, looks like
import React from 'react'
import { Swiper, SwiperSlide } from 'swiper/react'
const CustomView = () => {
return (
<Swiper>
</Swiper>
)
}
export default CustomView
When I run it I'm getting the following error in terminal
"message":"Must use import to load ES Module: /Users/Projects/ReactStarter/node_modules/swiper/react/swiper-react.js\nrequire() of ES modules is not supported.
Then I change Import to:
import { Swiper, SwiperSlide } from 'swiper/react/swiper-react.js'
In Terminal error is printed:
"message":"Package subpath './react/swiper-react.js' is not defined by \"exports\"
Is there any way I can bypass this, since I'm using webpack so maybe I can somehow ignore it or something else
can u try in terminal
npm cache clean --force
npm rm -rf node_modules
and install again 3. npm i
Looks like a problem with next.js a temporary fix would be changing experimental.esmExternals to loose in your next.config.js and follow this thread for more updates regarding this issue.
module.exports = {
experimental: {
esmExternals: "loose",
}
};
Updating the library might not be a option.
Considering you are using React 18.
https://github.com/nolimits4web/swiper/issues/4871

How would you fix an 'ERR_REQUIRE_ESM' error?

I am trying to use the chalk npm.
My code is:
const chalk = require('chalk');
console.log(
chalk.green('All sytems go') +
chalk.orange('until').underline +
chalk.black(chalk.bgRed('an error occurred'))
);
And I receive this error in my terminal when I type node main.js
Error [ERR_REQUIRE_ESM]: require() of ES Module /Users/ezell/Documents/CodeX/NPM/node_modules/chalk/source/index.js from /Users/ezell/Documents/CodeX/NPM/main.js not supported.
Instead change the require of index.js in /Users/ezell/Documents/CodeX/NPM/main.js to a dynamic import() which is available in all CommonJS modules.
at Object. (/Users/ezell/Documents/CodeX/NPM/main.js:1:15) {
code: 'ERR_REQUIRE_ESM'
}
I got the same 'ERR_REQUIRE_ESM' error for nanoid:^4.0.0 & there are multiple ways to resolve this error:-
1)Use fix esm https://www.npmjs.com/package/fix-esm module & import the module like this:
const someModule = require("fix-esm").require("some-module");
2)Use dynamic import as shown below:
import('nanoid')
.then((res)=>{ console.log(res) })
.catch((err)=>{ console.log(err) });
Just make sure you dont have type:"module" field in package.json in above both cases otherwise you got "TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension" error
3)Downgrade the module version to a stable old version, for eg in my case it was resolved when I downgraded nanoid version to :
"nanoid": "^3.1.22"
You need to switch to using the import keyword, as Chalk 5 only supports ESM modules.
So, to fix your code to adapt these changes, you need to...
Edit your package.json file to allow ESM imports. Add the following in your package.json file:
{
"type": "module"
}
Load Chalk with the import keyword, as so:
import chalk from "chalk";
If you, however, want to use require(), you need to downgrade to Chalk 4. Follow these steps to downgrade.
Replace your existing chalk key with the following in your package.json file:
{
"dependencies": {
"chalk": "4.1.2"
}
}
Then, run the following command to install Chalk from your package.json file. Make sure to run this in the directory in which your package.json file is in!
$ npm install
Use the require() statement like normal.
const chalk = require("chalk");
In summary, these are the two things you can do.
Stay with Chalk 5, and update import statements.
Downgrade to Chalk 4, and keep require() statements.
Solution, this happens because you have to use the current stable release 2.x
first:
npm uninstall -D node-fetch
After that:
npm install node-fetch#2
This should work.
The latest version of Chalk is only compatible with ESM modules and thus wants you to load it with import, not require().
From the doc:
IMPORTANT: Chalk 5 is ESM. If you want to use Chalk with TypeScript or
a build tool, you will probably want to use Chalk 4 for now. Read more.
So, your choices are:
Switch your project to an ESM module and load the latest version of Chalk with import instead of require().
Install version 4 of Chalk which can be used with require().
With a fairly recent version of Node.JS, you can use dynamic import to load the ESM module into your CommonJS module: const chalk = await import('chalk');

SyntaxError: The requested module 'graphql-relay' does not provide an export named 'fromGlobalId' [duplicate]

I've installed Node 8.9.1 (same problem happens in v10.5.0).
I'm trying to use named imports from npm packages in a file with the .mjs
import { throttle } from lodash;
I run:
node --experimental-modules index.mjs
and I get:
SyntaxError: The requested module 'lodash' does not provide an export named 'throttle'
at ModuleJob._instantiate (internal/modules/esm/module_job.js:80:21)
--experimental-modules are supposed to stop being experimental in v10 LTS, so why haven't more module authors jumped on the bandwagon?
EDITED NEW (AND MUCH BETTER) ANSWER
The Node team is ... slow. Meanwhile, the same guy who brought us Lodash (John-David Dalton) imagined a brilliant solution, and his idea is the best way to get full ES6 module support in 2019.
(In fact, I want to delete my earlier answer, but I've left it for historical purposes.)
The new solution is SUPER simple.
Step #1:
npm i esm
(https://www.npmjs.com/package/esm for package details)
Step #2:
node -r esm yourApp.js
That's the entirety of it: it's really just that easy. Just add -r esm as a Node arg, and everything just magically works (it's even less typing than --experimental-modules!) Thank you John-David Dalton!!!
As I said in my original answer, presumably someday Node will finally release full ES6 support, but when that happens adopting it will be as easy as removing "-r esm" from a few scripts :D
Finally, to give credit where due, while I didn't find it through his answer, #Divyanshu Rawat actually provided an answer with the precursor to this library long before I made this update.
ORIGINAL ANSWER
--experimental-modules does not have support for named exports yet:
--experimental-modules doesn't support importing named exports from a commonjs module (except node's own built-ins).
https://github.com/apollographql/graphql-tools/issues/913
This is why you are unable to use the syntax:
import { throttle } from 'lodash';
Instead (for now at least) you have to destruct what you need:
import lodash from 'lodash';
const { throttle } = lodash;
Presumably someday Node will add support for all of the ES Module features.
I just had this error with nodejs express *.mjs file and --experimental-modules flag enabled for googleapis.
import { google } from "googleapis";
SyntaxError: The requested module 'googleapis' does not provide an export named 'google'
Solution
//not working!
//import { google } from "googleapis";
//working
import googleapis from "googleapis";
const { google } = googleapis;
I do not understand why this is the case; if anyone knows why, please comment.
You have to use .mjs extension.
Once this has been set, files ending with .mjs will be able to be loaded as ES Modules.
reference: https://nodejs.org/api/esm.html
Update:
Looks like you haven't export the method yet.
Suppose i have hello.mjs with content
export function sayHello() {
console.log('hello')
}
i can use it in index.mjs like this
import {sayHello} from './hello.mjs'
sayHello()
For me loading lodash as ES Library did the job, here is the NPM Package for the same.
The Lodash library exported as ES modules.
https://www.npmjs.com/package/lodash-es
Then you can import utils in normal way.
import { shuffle } from 'lodash-es';
If lodash had been written as modules, and lodash/index.mjs exported throttle: export const throttle = ...;, then you'd be able to import { throttle } from lodash;
The problem here is that in commonjs there's no such thing as a named export. Which means that in commonjs modules export one thing only.
So think that lodash exports an object containing a property named throttle.
For the second part of the question, I believe people will slowly start adopting ES Modules once it's not experimental anymore. At the time of this writing, it still is (Node.js v11.14).
#machineghost answer works. I remember also adding 'type':'module' to package.json along with using esm with node v12(LTS) and it worked fine.## Heading ##
I updated my node to v14(current) and I got an error
C:\Users\andey\Documents\Project\src\app.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:
C:\Users\andey\Documents\Project\src\app.js
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1217:13) {
code: 'ERR_REQUIRE_ESM'
}
To fix it I had to remove 'type':'module' from package.json.
source

node --experimental-modules, requested module does not provide an export named

I've installed Node 8.9.1 (same problem happens in v10.5.0).
I'm trying to use named imports from npm packages in a file with the .mjs
import { throttle } from lodash;
I run:
node --experimental-modules index.mjs
and I get:
SyntaxError: The requested module 'lodash' does not provide an export named 'throttle'
at ModuleJob._instantiate (internal/modules/esm/module_job.js:80:21)
--experimental-modules are supposed to stop being experimental in v10 LTS, so why haven't more module authors jumped on the bandwagon?
EDITED NEW (AND MUCH BETTER) ANSWER
The Node team is ... slow. Meanwhile, the same guy who brought us Lodash (John-David Dalton) imagined a brilliant solution, and his idea is the best way to get full ES6 module support in 2019.
(In fact, I want to delete my earlier answer, but I've left it for historical purposes.)
The new solution is SUPER simple.
Step #1:
npm i esm
(https://www.npmjs.com/package/esm for package details)
Step #2:
node -r esm yourApp.js
That's the entirety of it: it's really just that easy. Just add -r esm as a Node arg, and everything just magically works (it's even less typing than --experimental-modules!) Thank you John-David Dalton!!!
As I said in my original answer, presumably someday Node will finally release full ES6 support, but when that happens adopting it will be as easy as removing "-r esm" from a few scripts :D
Finally, to give credit where due, while I didn't find it through his answer, #Divyanshu Rawat actually provided an answer with the precursor to this library long before I made this update.
ORIGINAL ANSWER
--experimental-modules does not have support for named exports yet:
--experimental-modules doesn't support importing named exports from a commonjs module (except node's own built-ins).
https://github.com/apollographql/graphql-tools/issues/913
This is why you are unable to use the syntax:
import { throttle } from 'lodash';
Instead (for now at least) you have to destruct what you need:
import lodash from 'lodash';
const { throttle } = lodash;
Presumably someday Node will add support for all of the ES Module features.
I just had this error with nodejs express *.mjs file and --experimental-modules flag enabled for googleapis.
import { google } from "googleapis";
SyntaxError: The requested module 'googleapis' does not provide an export named 'google'
Solution
//not working!
//import { google } from "googleapis";
//working
import googleapis from "googleapis";
const { google } = googleapis;
I do not understand why this is the case; if anyone knows why, please comment.
You have to use .mjs extension.
Once this has been set, files ending with .mjs will be able to be loaded as ES Modules.
reference: https://nodejs.org/api/esm.html
Update:
Looks like you haven't export the method yet.
Suppose i have hello.mjs with content
export function sayHello() {
console.log('hello')
}
i can use it in index.mjs like this
import {sayHello} from './hello.mjs'
sayHello()
For me loading lodash as ES Library did the job, here is the NPM Package for the same.
The Lodash library exported as ES modules.
https://www.npmjs.com/package/lodash-es
Then you can import utils in normal way.
import { shuffle } from 'lodash-es';
If lodash had been written as modules, and lodash/index.mjs exported throttle: export const throttle = ...;, then you'd be able to import { throttle } from lodash;
The problem here is that in commonjs there's no such thing as a named export. Which means that in commonjs modules export one thing only.
So think that lodash exports an object containing a property named throttle.
For the second part of the question, I believe people will slowly start adopting ES Modules once it's not experimental anymore. At the time of this writing, it still is (Node.js v11.14).
#machineghost answer works. I remember also adding 'type':'module' to package.json along with using esm with node v12(LTS) and it worked fine.## Heading ##
I updated my node to v14(current) and I got an error
C:\Users\andey\Documents\Project\src\app.js:1
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:
C:\Users\andey\Documents\Project\src\app.js
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1217:13) {
code: 'ERR_REQUIRE_ESM'
}
To fix it I had to remove 'type':'module' from package.json.
source

How do I use pouchdb with typescript?

I am trying to use pouchdb with Typescript. I cannot link to the pouchdb module.
import { PouchDB } from "pouchdb"
reports that it cannot find module pouchdb, even though it is in node_modules.
I also cannot find the appropriate typings for pouchdb.
I'm doing this in Ionic, so I may be missing a step on getting the types file loaded properly.
Make sure your types are installed with:
npm install --save-dev #types/pouchdb
At the top of your data service import pouch like so:
import * as PouchDB from 'pouchdb';
* edit *
I don't have all the facts, but this is my current understanding.
Typings is no longer needed in Typescript >2.0
I believe typescript now works automatically with types files installed from DefinitelyTyped.
DefinitelyTyped is an official central repository that is kept current like npm.
And even if I'm dead wrong about all this, DefinitelyTyped is still better than typings and has a much bigger community.
Cause i just had this Problem, For Angular 2 + Typescript the correct way to use PouchDB (using angular-cli) is to:
ng new SOMENAME
npm install --save pouchdb
npm install --save-dev #types/pouchdb
In your app.component import PouchDB from 'pouchdb';
In your App Component Class public db: any; and to init this.db = new PouchDB('test'); // , {storage:'persistent'} not working in typescript without updating typings
see https://github.com/nolanlawson/pouchdb-find/issues/201.
If you have problems installing the packages on windows with an EPERM Error use (f.e.) npm install --save pouchdb --no-optional to disable the warning. The installation should still be ok. For more info see https://github.com/npm/npm/issues/17671
I had the same problem trying to import into Angular 6.
Your imports seem fine:
import PouchDB from 'pouchdb';
import PouchFind from 'pouchdb-find';
PouchDB.plugin(PouchFind);
What you may be missing is you need to add this to your polyfills.ts file:
(window as any).global = window;
(window as any).process = {};
(window as any).process.nextTick = setTimeout;
import PouchDB from 'pouchdb';
export abstract class PouchDBDatabase {
private _database: PouchDB.Database<Sheet>;
constructor(protected DATABASE_URL: string) {
this._database = new PouchDB(this.DATABASE_URL);
}
}
And you're good to go with typescript + pouchDB :)
I managed to get the module recognised by using
declare function require(a)
var PouchDB = require("pouchdb")
I have given up type checking, but at least I can make progress.

Resources