简体   繁体   中英

Mix CommonJS and ES6 modules in same project

I am working in NodeJS. I have a great deal of legacy code including several packages that are used in many places. This code is all CommonJS, Node require() module structures.

Node now supports ES6. Since it is a Javascript language feature, I would like to migrate to it.

Today, I started a small project. My small project boilerplate requires() a couple of my favorite utilities and then says 'Hello World'. I edited it to import said utilities. Node told me I needed to add "type":"module" to my package.json and I did.

When I ran it, I was told that "require is not defined", this in reference to one of the utility modules I imported.

I infer that this means that a project is either CommonJS or ES6 and it appears that never the twain shall meet. I am surprised by this because it means that I will never use ES6 in NodeJS because I will never be able to change all of the modules I require(). Some are not even mine, others are used in projects (npm.) that I do not even know about.

Honestly, I have a hard time believing that this is the case. I don't understand how ES6 can ever become a widely used standard because of if ES^ and CommonJS cannot be used together in an application. I realize that Webpack, etc, will preprocess code and revise all the require() statements but not everyone uses that sort of utility.

My questions are:

Is this analysis correct?

Is there some workaround that will let me use both module systems (without a preprocessor)?

Is my impending decision to never, ever use ES6 the right one?

I'm NOT a javascript person so I humbly accept any corrections here. I had the same question and was surprised at the lack of clarity on it in the usual places.

The confusing thing is that where you actually mix these, there are two files (modules) involved - the importing file and the imported file. So, if your index (or other entry point) file is ES-based and it needs to include a CommonJS file - which format do you use? For the most common basic case of importing CommonJS files/libraries into a modern ES6 app):

  1. Do NOT specify type:module in package.json (this leaves the default as CommonJS)
  2. File Extensions: Use the.mjs extension for all of the ES6 files. Use (or leave) the older.js extension for all of the CommonJS files
  3. Export statements: Use export keyword (eg"export functionName") for all ES6 exports - use "modules.export" for all CommonJS exports
  4. Import statements: use the importing syntax for whatever file type you are importing to . For example, if you are in an ES6 module file and need to bring in a CommonJS file, use the ES6 import syntax

在此处输入图像描述

For node.js 16.18.0

package.json

{
  "name": "es6_commonjs",
  "version": "1.0.0",
  "description": "",
  "type": "module",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

book.cjs

module.exports = class Book {
    constructor(name) {
        this.name = name;
    }
}

student.js

export class Student {
    constructor(name) {
        this.name = name;
    }
}

app.js

import { Student } from "./student.js";
import Book from './book.cjs';

const student = new Student('Name');
console.log(student);

const book = new Book('Name');
console.log(book);

run command node./app.js

result:

Student { name: 'Name' }
Book { name: 'Name' }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM