【问题标题】:syntax differences between CJS & ES6 modulesCJS 和 ES6 模块之间的语法差异
【发布时间】:2015-06-30 06:40:18
【问题描述】:

在 CJS 模块中,我会使用 exportvar plugin = require('plugin');   来导出/导入
在 ES6 模块中,我会使用 exportimport * as plugin from 'plugin'; 来导出/导入。

还有更多的语法差异吗?这些 ^ 差异正确吗?

export defaultexport * 是什么意思?

【问题讨论】:

  • 在 CJS 中,export(和module.export)只是一个变量。在 ES6 中,export 是一个关键字,并且在语言中有自己的语法!
  • @Bergi 谢谢你,很有趣。去一个有趣的答案也需要几分钟的学习。

标签: javascript ecmascript-6 commonjs


【解决方案1】:

CommonJS 模块和 ES6 模块非常相似,但它们有一些非常重要的区别需要注意。先直接回答你的问题:

var plugin = require('plugin');

在 ES6 中将等同于两者

// Import all named exports of 'plugin'.
import * as plugin from 'plugin';

和/或

// Import default export of 'plugin'.
import plugin from 'plugin';

// an alias of
import {default as plugin} from 'plugin';

但这取决于“插件”是如何编写的,以及它是使用 ES6 export 还是 CommonJS module.exports 编写的。

CommonJS 模块

CommonJS 导入只有一个导出对象。该对象可能是一个函数、一个对象或任何东西。通常 CommonJS 模块会这样做

exports.foo = ...;
exports.bar = ...;

导出命名属性。他们还可以将“默认”对象导出为

module.exports = function(){};

这里的核心是,如果你想要一个默认导出和命名导出,你唯一的选择就是将属性直接放到默认导出上。

ES6 模块

对于 ES6 模块,命名导出和默认导出的概念是 100% 分离的。例如

export var foo = ...;
export var bar = ...;
export default function fn(){};

主要区别在于

fn.foo !== foo;

那么这个例子有两种情况

插件使用 ES6 export

import * as plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'object';

import plugin from 'plugin';

plugin.foo === undefined;
plugin.bar === undefined;
typeof plugin === 'function';

插件使用 CommonJS module.exports

import * as plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'object';

import plugin from 'plugin';

plugin.foo === ...;
plugin.bar === ...;
typeof plugin === 'function';

实时绑定导入/导出

您的示例中的另一个主要区别是 plugin 是实时绑定。这意味着如果稍后在模块内更新它,它会在您的导入中自行更新,例如

// plugin.js

export var foo = 'foo';

export function update(){
    foo = 'bar';
}

// other.js

import {foo, update} from 'plugin';

foo === 'foo';

update();

foo === 'bar'

如果你这样做了,情况就不是这样了

var foo = require('plugin').foo;
var update = require('plugin').update;

【讨论】:

  • 这是一个非常好的答案! +1。我可以在 Node.js 或 io.js 的同一个项目中使用 commonjs 和 ES6 语法(我想是这样,但想知道是否存在我不知道的问题)? commonsjs 模块会随着时间的推移而消失吗(可能是一个主观问题......)?
  • 还发现了一篇有趣的要点/文章:gist.github.com/domenic/4748675
  • 你绝对可以在 ES6 中使用 ES5 模块。我不能说 Traceur,但是当你使用 import 语法检查你是导入 ES6 模块还是 ES5 时,Babel 包含一个标准的互操作层。
  • 这是一个用于演示上述理论的仓库:github.com/upupming/cjs-vs-esm
猜你喜欢
  • 2019-06-19
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 1970-01-01
  • 2022-01-03
  • 2016-05-14
相关资源
最近更新 更多