Node Error Must use import to load ES module - javascript

I have the following code:
import { toString } from 'nlcst-to-string';
import { retext } from 'retext';
import retextPos from 'retext-pos';
import retextKeywords from 'retext-keywords';
const sentence =
"President Obama woke up Monday facing a Congressional defeat that many in both parties believed could hobble his presidency."
function process(params) {
// some code
}
exports.main = processComment;
But I am getting the following error:
[ERR_REQUIRE_ESM]: Must use import to load ES module
Which is strange because I already am using import.
I have also tried adding "type": "module" to package.json - no luck. Tried ending the file extension in .mjs - nothing

It’s either your node version or None of your import locations have ./
Even if those files are in the same directory as your main js file you still need that.
Unless that’s so npm library I have never heard of.

Check your node version. Node version 14+ supports the type: "module"
node --version
If you have node version manager, you can run
nvm install your_desired_version_here
to get a compliant version

Related

Trouble importing the "uuid" npm package. TypeError: Relative references must start with either "/", "./", or "../"

I am trying to import a module called "uuid" to my index.js script which I installed through this command: npm install uuid.
First I tried using CommonJS syntax, but that gave me this error: Uncaught ReferenceError: require is not defined
const { v4: uuidv4 } = require('uuid');
// ReferenceError: require is not defined
My IDE recommended that I convert my file to an ES module instead:
import { v4 as uuidv4 } from 'uuid';
// SyntaxError: Cannot use import statement outside a module
By adding type="module" to my index.js script in the html only produces new errors:
TypeError: Failed to resolve module specifier "uuid". Relative references must start with either "/", "./", or "../".
I have searched for a while now but can't find anything. Upon trying to follow the error message instructions I try to generate a more direct path to the "uuid" module like this:
import { v4 as uuidv4 } from '../node_modules/uuid/dist/v4';
// GET http://localhost:3000/node_modules/uuid/dist/v4 net::ERR_ABORTED 404 (Not Found)
Even with this direct path it can't find the module which is weird as it is at least recognizing something when only specifying the module name "uuid".
If it's to any help here is my package.json dependencies
"dependencies": {
"express": "^4.18.1",
"nodemon": "^2.0.20",
"socket.io": "^4.5.2",
"socket.io-client": "^4.5.4",
"uuid": "^9.0.0"
}
You're trying to import uuid module from node_modules in the script running in the browser. Unfortunately, it's that simple. The node_modules work for Node.js only, browsers don't know about them.
There are multiple ways you can fix this:
Setup a static server that will serve uuid. Then, you can import it by its url (e.g import { v4 as uuidv4 } from './uuid';). This is generally not recommended.
Use CDN. It's similar to the previous method, but this time someone will set up a static server for you. This is often used in production because of good performance, and you don't need to do anything for this. It's simple: import { v4 as uuidv4 } from 'https://jspm.dev/uuid';
But not all libraries are hosted on CDNs. Also, you'd probably need to optimize your dependencies and code. So for complex applications, you should use a so called bundler. Here are a few of the most popular: Vite, Rollup, Webpack, Parcel. What bundlers do: they analyze your imports and then produce a single js file called an "entrypoint". Depending on configuration they can combine all dependencies into one file, or insert special code that will dynamically import your dependencies from other files when they are needed for code to execute.

How can i do npm module support import and require?

I uploaded my first module to npm in Javascript and I want it to support import and require. Is this possible?
The module is this:
https://www.npmjs.com/package/#dariodigulio/pro-log-js
Yes, I get the same error when I did try to require() your package. But, then I manged to get both working (import...from and require()) by converting your package code to commonjs compatible.
You should try to publish the package as commonjs (require()) module and then you'll get support from Node to choose either syntax on application side.
I did following change in your code to get both syntax working.
Removed the "type": "module" from package.json.
Update the main entry from "main": "ProLog.mjs", to "main": "ProLog.js".
Replace the import...from syntax with require() in ProLog.js file.
Update the export class ProLog to module.exports = ProLog.

Promoting Babelized ES module code to native Node 14+

I have lot of javascript written to be run by nodejs, but which we ran through the Babel loader at runtime, so that we could write ES syntax -- in particular using import rather than require.
We have a layout like:
package.json
node_modules/
...packages...
top/
server.js
fribbity.js
server.js looks like (I've elided the babel import boilerplate) :
import {fribbity} from 'top/fribbity'
const x = fribbity()
console.log(`fribbity = ${x}`)
while fribbity.js might be
export const fribbity = () => 17
I'd like to promote all this code to use native ES modules in Node 14+. I added "type": "module" to package.json. But now I've run into the module resolution rules. By default, Node now expects my import in server.js to be
import {fribbity} from './fribbity.js'
Are there settings I can apply in package.json, or on the node command line, that would enable node to resolve the imports as they were originally written? That is, preserving the deep import path style (import string begins with no slash or dot, and ends without the ".js" extension)? I've tried several false starts.

Importing an external module in javascript [duplicate]

This question already has answers here:
Node.js - SyntaxError: Unexpected token import
(16 answers)
Closed 3 years ago.
I'm trying to get the hang of ES6 imports in Node.js and am trying to use the syntax provided in this example:
Cheatsheet Link
I'm looking through the support table, but I was not able to find what version supports the new import statements (I tried looking for the text import/require). I'm currently running Node.js 8.1.2 and also believe that since the cheatsheet is referring to .js files it should work with .js files.
As I run the code (taken from the cheatsheet's first example):
import { square, diag } from 'lib';
I get the error:
SyntaxError: Unexpected token import.
Reference to library I'm trying to import:
//------ lib.js ------
export const sqrt = Math.sqrt;
export function square(x) {
return x * x;
}
export function diag(x, y) {
return sqrt(square(x) + square(y));
}
What am I missing and how can I get node to recognize my import statement?
Node.js has included experimental support for ES6 support.
Read more about here: https://nodejs.org/docs/latest-v13.x/api/esm.html#esm_enabling.
TLDR;
Node.js >= v13
It's very simple in Node.js 13 and above. You need to either:
Save the file with .mjs extension, or
Add { "type": "module" } in the nearest package.json.
You only need to do one of the above to be able to use ECMAScript modules.
Node.js <= v12
If you are using Node.js version 9.6 - 12, save the file with ES6 modules with .mjs extension and run it like:
node --experimental-modules my-app.mjs
You can also use npm package called esm which allows you to use ES6 modules in Node.js. It needs no configuration. With esm you will be able to use export/import in your JavaScript files.
Run the following command on your terminal
yarn add esm
or
npm install esm
After that, you need to require this package when starting your server with node. For example if your node server runs index.js file, you would use the command
node -r esm index.js
You can also add it in your package.json file like this
{
"name": "My-app",
"version": "1.0.0",
"description": "Some Hack",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node -r esm index.js"
},
}
Then run this command from the terminal to start your node server
npm start
Check this link for more details.
I just wanted to use the import and export in JavaScript files.
Everyone says it's not possible. But, as of May 2018, it's possible to use above in plain Node.js, without any modules like Babel, etc.
Here is a simple way to do it.
Create the below files, run, and see the output for yourself.
Also don't forget to see Explanation below.
File myfile.mjs
function myFunc() {
console.log("Hello from myFunc")
}
export default myFunc;
File index.mjs
import myFunc from "./myfile.mjs" // Simply using "./myfile" may not work in all resolvers
myFunc();
Run
node --experimental-modules index.mjs
Output
(node:12020) ExperimentalWarning: The ESM module loader is experimental.
Hello from myFunc
Explanation:
Since it is experimental modules, .js files are named .mjs files
While running you will add --experimental-modules to the node index.mjs
While running with experimental modules in the output you will see: "(node:12020) ExperimentalWarning: The ESM module loader is experimental.
"
I have the current release of Node.js, so if I run node --version, it gives me "v10.3.0", though the LTE/stable/recommended version is 8.11.2 LTS.
Someday in the future, you could use .js instead of .mjs, as the features become stable instead of Experimental.
More on experimental features, see: https://nodejs.org/api/esm.html
Using Node.js v12.2.0, I can import all standard modules like this:
import * as Http from 'http'
import * as Fs from 'fs'
import * as Path from 'path'
import * as Readline from 'readline'
import * as Os from 'os'
Versus what I did before:
const
Http = require('http')
,Fs = require('fs')
,Path = require('path')
,Readline = require('readline')
,Os = require('os')
Any module that is an ECMAScript module can be imported without having to use an .mjs extension as long as it has this field in its package.json file:
"type": "module"
So make sure you put such a package.json file in the same folder as the module you're making.
And to import modules not updated with ECMAScript module support, you can do like this:
// Implement the old require function
import { createRequire } from 'module'
const require = createRequire(import.meta.url)
// Now you can require whatever
const
WebSocket = require('ws')
,Mime = require('mime-types')
,Chokidar = require('chokidar')
And of course, do not forget that this is needed to actually run a script using module imports (not needed after v13.2):
node --experimental-modules my-script-that-use-import.js
And that the parent folder needs this package.json file for that script to not complain about the import syntax:
{
"type": "module"
}
If the module you want to use has not been updated to support being imported using the import syntax then you have no other choice than using require (but with my solution above that is not a problem).
I also want to share this piece of code which implements the missing __filename and __dirname constants in modules:
import {fileURLToPath} from 'url'
import {dirname} from 'path'
const __filename = fileURLToPath(import.meta.url)
const __dirname = dirname(__filename)
If you are using the modules system on the server side, you do not need to use Babel at all. To use modules in Node.js ensure that:
Use a version of node that supports the --experimental-modules flag
Your *.js files must then be renamed to *.mjs
That's it.
However and this is a big however, while your shinny pure ES6 code will run in an environment like Node.js (e.g., 9.5.0) you will still have the craziness of transpilling just to test. Also bear in mind that Ecma has stated that release cycles for JavaScript are going to be faster, with newer features delivered on a more regular basis. Whilst this will be no problems for single environments like Node.js, it's a slightly different proposition for browser environments. What is clear is that testing frameworks have a lot to do in catching up. You will still need to probably transpile for testing frameworks. I'd suggest using Jest.
Also be aware of bundling frameworks. You will be running into problems there.
Use:
"devDependencies": {
"#babel/core": "^7.2.0",
"#babel/preset-env": "^7.2.0",
"#babel/register": "^7.0.0"
}
File .babelrc
{
"presets": ["#babel/preset-env"]
}
Entry point for the Node.js application:
require("#babel/register")({})
// Import the rest of our application.
module.exports = require('./index.js')
See How To Enable ES6 Imports in Node.js
You may try esm.
Here is some introduction: esm
Using the .mjs extension (as suggested in the accepted answer) in order to enable ECMAScript modules works. However, with Node.js v12, you can also enable this feature globally in your package.json file.
The official documentation states:
import statements of .js and extensionless files are treated as ES modules if the nearest parent package.json contains "type": "module".
{
"type": "module",
"main": "./src/index.js"
}
(Of course you still have to provide the flag --experimental-modules when starting your application.)
Back to Jonathan002's original question about
"... what version supports the new ES6 import statements?"
based on the article by Dr. Axel Rauschmayer, there is a plan to have it supported by default (without the experimental command line flag) in Node.js 10.x LTS. According to node.js's release plan as it is on 3/29, 2018, it's likely to become available after Apr 2018, while LTS of it will begin on October 2018.
Solution
https://www.npmjs.com/package/babel-register
// This is to allow ES6 export syntax
// to be properly read and processed by node.js application
require('babel-register')({
presets: [
'env',
],
});
// After that, any line you add below that has typical ES6 export syntax
// will work just fine
const utils = require('../../utils.js');
const availableMixins = require('../../../src/lib/mixins/index.js');
Below is definition of file *mixins/index.js
export { default as FormValidationMixin } from './form-validation'; // eslint-disable-line import/prefer-default-export
That worked just fine inside my Node.js CLI application.
I don't know if this will work for your case, but I am running an Express.js server with this:
nodemon --inspect ./index.js --exec babel-node --presets es2015,stage-2
This gives me the ability to import and use spread operator even though I'm only using Node.js version 8.
You'll need to install babel-cli, babel-preset-es2015, and babel-preset-stage-2 to do what I'm doing.

How do I properly load the lit-html module in Electron

I'm trying to use lit-html to save my self some time, but I'm having trouble getting everything set up correctly.
Electron 4.1.1
Node 11.15
As of 5 minutes before posting this, I've run npm install and electron-rebuild, no luck.
I use require() as one would with any other NPM package
var render = require('lit-html').render
var html = require('lit-html').html
console.log(require("lit-html"))
Unfortunately, I'm greeted with this error
In reference to the three lines of code above.
I don't see any problems with my code.
I've tried reinstalling lit-html through NPM to no avail. I would really love to use this library, but first I have to get over this hurdle. If I'm being honest, I don't know if this error is reproducible, but nothing I do seems to fix it. The problem seems to lie with node and the way that imports are handled.
Am I missing something here? Is this a common issue? If so, what can I do to fix it?
You need to transpile lit-html before you can require it
I tested require('lit-html') and I was greeted with this error:
/home/chbphone55/Workspace/test/node_modules/lit-html/lit-html.js:31
import { defaultTemplateProcessor } from './lib/default-template-processor.js';
It clearly states that the error is coming from lit-html/lit-html.js:31 where the line uses ES Module import syntax.
You can transpile it using tools like Babel or similar ones. However, you may want to try using ES Module syntax so you can import lit-html without transpiling it.
Example:
<!-- HTML File -->
<script type="module" src="index.js"></script>
// index.js
import { html } from 'lit-html';
What if you can't use type="module"
If you are unable to use the type="module" method above, you can also use the ESM package.
ESM is a brilliantly simple, babel-less, bundle-less ECMAScript module loader.
Here are a few examples of how to use it:
Using the node require flag (-r) to load esm before everything else
node -r esm index.js
Loading esm in your main file then loading the rest of your code.
// Set options as a parameter, environment variable, or rc file.
require = require('esm')(module/*, options*/)
module.exports = require('./main.js')

Categories

Resources