简体   繁体   English

在同一项目中混合 CommonJS 和 ES6 模块

[英]Mix CommonJS and ES6 modules in same project

I am working in NodeJS.我在 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.这段代码都是CommonJS,Node require() 模块结构。

Node now supports ES6. Node 现在支持 ES6。 Since it is a Javascript language feature, I would like to migrate to it.由于它是一个 Javascript 语言功能,我想迁移到它。

Today, I started a small project.今天,我开始了一个小项目。 My small project boilerplate requires() a couple of my favorite utilities and then says 'Hello World'.我的小项目样板需要()几个我最喜欢的实用程序,然后说“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. Node 告诉我需要将 "type":"module" 添加到我的 package.json 中,我做到了。

When I ran it, I was told that "require is not defined", this in reference to one of the utility modules I imported.当我运行它时,我被告知“require is not defined”,这是指我导入的实用程序模块之一。

I infer that this means that a project is either CommonJS or ES6 and it appears that never the twain shall meet.我推断这意味着一个项目要么是 CommonJS 要么是 ES6,而且这两者似乎永远不会相遇。 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().我对此感到惊讶,因为这意味着我永远不会在 NodeJS 中使用 ES6,因为我永远无法更改我需要的所有模块()。 Some are not even mine, others are used in projects (npm.) that I do not even know about.有些甚至不是我的,有些在我什至不知道的项目 (npm.) 中使用。

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.我不明白 ES6 如何成为广泛使用的标准,因为 ES^ 和 CommonJS 不能在应用程序中一起使用。 I realize that Webpack, etc, will preprocess code and revise all the require() statements but not everyone uses that sort of utility.我意识到 Webpack 等会预处理代码并修改所有 require() 语句,但并不是每个人都使用这种实用程序。

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?我即将做出的永远、永远不使用 ES6 的决定是正确的吗?

I'm NOT a javascript person so I humbly accept any corrections here.我不是 javascript 的人,所以我在这里谦虚地接受任何更正。 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?所以,如果您的索引(或其他入口点)文件是基于 ES 的,并且它需要包含一个 CommonJS 文件 - 您使用哪种格式? For the most common basic case of importing CommonJS files/libraries into a modern ES6 app):对于将 CommonJS 文件/库导入现代 ES6 应用程序的最常见基本情况):

  1. Do NOT specify type:module in package.json (this leaves the default as CommonJS)不要在package.json中指定类型:模块(这将默认设置为 CommonJS)
  2. File Extensions: Use the.mjs extension for all of the ES6 files.文件扩展名:对所有 ES6 文件使用 .mjs 扩展名。 Use (or leave) the older.js extension for all of the CommonJS files对所有 CommonJS 文件使用(或保留)older.js 扩展名
  3. Export statements: Use export keyword (eg"export functionName") for all ES6 exports - use "modules.export" for all CommonJS exports导出语句:对所有 ES6 导出使用 export 关键字(例如“export functionName”) - 对所有 CommonJS 导出使用“modules.export”
  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例如,如果你在 ES6 模块文件中,需要引入 CommonJS 文件,使用 ES6 导入语法

在此处输入图像描述

For node.js 16.18.0对于 node.js 16.18.0

package.json包.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书.cjs

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

student.js学生.js

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

app.js应用程序.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运行命令node./app.js

result:结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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