Why is 'type: module' in package.json file?
Asked Answered
C

6

149

I upgraded the node and built the existing file.

But it didn't build, and there was an error.

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module:                          │
   │   ~~/nuxt.config.js                                      │
   │   require() of ES modules is not supported.                                            │
   │   require() of ~~/nuxt.config.js from                    │
   │   ~~/config.js 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 nuxt.config.js to end in .cjs, change the requiring code to use       │
   │   import(), or remove "type": "module" from                                            │
   │   ~~/package.json.  

So I removed 'type: module' in package.json file.

Is it okay to remove it?

Cornwell answered 24/4, 2020 at 5:1 Comment(0)
C
203

When you have "type": "module" in the package.json file, your source code should use import syntax. When you do not have, you should use require syntax; that is, adding "type": "module" to the package.json enables ES 6 modules. For more info, see here.

Crown answered 24/6, 2020 at 12:20 Comment(3)
I think what Alex was trying to say is that omitting type from package.json has the same effect as setting it to CJS. (This is what the spec says: "If the nearest parent package.json lacks a "type" field, or contains "type": "commonjs", .js files are treated as CommonJS. If the volume root is reached and no package.json is found, Node.js defers to the default, a package.json with no "type" field.")Veranda
Somthing to be noted: it will apply to all exports. So I don't know how to mix commonjs and ESM yet.Gertrude
can i still use require syntax after add type module in package.json file?Ossein
D
31

Update as of mid-2022

If you're using Node.js v16, and you should if you can since it's LTS, you only need to use type: module as explained here: https://blog.logrocket.com/es-modules-in-node-today/


If you're still stuck with a lower version of Node.js for some reasons, you can follow this blog post from Flavio: https://flaviocopes.com/how-to-enable-es-modules-nodejs/

And do the following:

  • add "type": "module" in your package.json
  • use --experimental-modules when launching your app, eg: node --experimental-modules app.js

Or you can do one of those instead if on a modern version of Node already:

  • add "type": "module" in your package.json
  • rename your file with an .mjs extension, end result will look like this node app.mjs
Doubletongue answered 28/7, 2021 at 10:20 Comment(2)
Unless I'm missing something, you still need to either (a) declare "type": "module" in package.json or (b) use .mjs file extensions when using Node 14 (tested with version 14.17.3). Otherwise you get an error from Node like Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. and SyntaxError: Cannot use import statement outside a module. This also applies to Node 16.5.0.Swinton
@Swinton Nvm, you're right, type: module is still required. My bad: blog.logrocket.com/es-modules-in-node-todayDoubletongue
A
5

From the Node documentation

The "type" field defines the module format that Node.js uses for all .js files that have that package.json file as their nearest parent.

Files ending with .js are loaded as ES modules when the nearest parent package.json file contains a top-level field "type" with a value of "module".

If the nearest parent package.json lacks a "type" field, or contains "type": "commonjs", .js files are treated as CommonJS.

So by default, Node treats .js files as CommonJS Module (i.e. you can use require and module.exports).

If you want to use ES Module, you should add "type": "module" in your package.json so that Node treats .js files as ES Module (i.e. you can import and export)

Ant answered 3/11, 2023 at 9:51 Comment(0)
C
3

@AfsharMohebi's answer is excellent and covers the most useful points.

This answer is to add some color around CI/CD pipelines, where one may need to utilize adding a dynamic type parameter for executing code with node, written in ES6 JavaScript. Additionally, I am aware this is tangential to the OP's question but Google brought me here and so hopefully this is found useful by someone else.

In particular, we may use --input-type=module according to the node docs if we do not have a package.json including type: module.

For example, I use the command below to test that an npm package was uploaded successfully and is usable:

mkdir test-mypkg && cd test-mypkg 
echo "import { myFunc } from '@myname/myPkg';" > test.js 
npm i @myname/myPkg @babel/core @babel/node && cat test.js | node --input-type=module

Note: babel dependencies are included for full ES6 to ES5 transpilation and may/may not be necessary. In addition, you should probably pin the version of the package myPkg you're testing!

Camelopardalis answered 4/1, 2021 at 21:21 Comment(0)
A
2

When you switch from const express = require("express") to import { Express } from "express"; you will have to insert "type": "module" in your package.json. It is basically used to enable the ES6 modules import/export syntax.

Aforementioned answered 18/8, 2023 at 6:58 Comment(0)
F
1

Update as of late-2023

With Node.js version v20.10.0 or later, the "type": "module" declaration in the package.json file is no longer necessary.

Instead, execute your program using the --experimental-detect-module flag:

node --experimental-detect-module index.js

Alternatively, you can achieve the same result with the --experimental-default-type="module" flag:

node --experimental-default-type="module" index.js

To avoid adding the flag every time, include it in the package.json file within the "scripts" section like this:

{
  ...
  "scripts": {
    "start": "node --experimental-detect-module index.js"
  },
  ...
}

Now, you can run your program using:

npm run start

This approach works well even without the presence of "type": "module" anywhere else in your project.

Forsta answered 24/11, 2023 at 5:17 Comment(1)
This is a good option if you don't mind the disclaimer in the link; "Detection increases startup time"Jackinthepulpit

© 2022 - 2024 — McMap. All rights reserved.