我们平时使用的npm 第三方包一般基于这两种规范开发的,很容易遇到一个项目里既有 CommonJS 又有 ES Module 的情况,那么我们应该如何解决这种CommonJS 和 ES Module 混合开发的问题呢?
(1)、服务器端JavaScript应用程序
(2)、命令行工具
(3)、图形界面应用程序
(4)、混合应用程序(如,Titanium或Adobe AIR)
通俗大白话,特点就是: 使用require关键词来引入依赖,举个例子:
const path = require('path')
const AutoLoad = require('@fastify/autoload')
以及 module.exports
module.exports = async function (fastify, opts) {
fastify.get('/', async function (request, reply) {
return 'this is an example'
})
}
ES Modules(ESM)是用于处理模块的 ECMAScript 标准。 虽然 Node.js 长期使用 CommonJS 标准,但浏览器从未有过模块系统。 每个主要决策(如模块系统)必须首先由 ECMAScript 标准化,然后由浏览器实施。
ES modules(ESM) 是 JavaScript 官方的标准化模块系统。
当使用模块来开发的时候,会建立一个模块模块依赖图。不同依赖之间联系来自于你使用的任何 import 语句。
在CommonJS中我们可以直接使用__dirname,就像下面这样:
fastify.register(AutoLoad, {
dir: path.join(__dirname, 'plugins'),
options: Object.assign({}, opts)
})
但是在ESM中不再支持,我们需要改为
import {dirname} from 'path';
import { fileURLToPath } from 'url';
function getDirname(url) {
const __filename = fileURLToPath(url);
return dirname(__filename);
}
单独指定某些文件使用 CommonJS 模块,或者ES Module 模块
ReferenceError: require is not defined in ES module scope, you can use import instead
This file is being treated as an ES module because it has a '.js' file extension and 'test/package.json' contains "type": "module". To treat it as a CommonJS script, rename it to use the '.cjs' file extension.
ReferenceError: 在 ES 模块范围中没有定义要求,您可以使用 import 代替
这个文件被视为 ES 模块,因为它有一个’。Js 的文件扩展名和‘ test/package.json’包含“ type”: “ module”。若要将其视为 CommonJS 脚本,请将其重命名为使用’。Cjs 的文件扩展名。
我们可以单独给某个文件设置后缀名来使用CommonJS 脚本,强制的指定文件后缀为 .cjs
指定需要使用ES Module 的文件的后缀名为 .mjs,那么这个文件会被强制指定使用 ES Module 规范
npm install --save-dev babel-cli babel-preset-env babel-register babel-preset-stage-0
npm install --save babel-polyfill # babel转码时不能识别一些全局对象的API,例如Object.assign,使用它可以解决这个问题
{
"presets": [
"env",
"stage-0"
]
}
require('babel-polyfill');
require('babel-register');
require('./app.js'); // 引入您的项目的启动文件
package.json中加入
"scripts": {
"start": "node main.js",
},
npm start
欢迎大家指出文章需要改正之处~
学无止境,合作共赢