ES6 和 CommonJS 导出约定的缺点

Disadvantage of ES6 and CommonJS export convention

对于 npm 模块的 main 文件,由 package.json 定义,我正在考虑这样的模式:

import Struct from './src/struct'

module.exports = Struct
module.exports.default = Struct

为了同时支持 CommonJS 和 ES6 导入:

const Struct = require('my-module')
// or
import Struct from 'my-module'

此约定是否有任何可能导致意外问题的缺点?

我试图解决的问题是必须强制包的消费者坚持使用 ES6 或 CommonJS,因为这两者看起来都相当令人讨厌:

const Struct = require('my-module').default
// or
import * as Struct from 'my-module'

进一步考虑后,像这样在 /src/struct.js 中定义我的 class 会更好吗?

export default class Struct {
  static get default () {
    return Struct
  }
  ...
}

好吧,由于 nodejs 仍然没有对 ES6 模块的原生支持,所以现在它真的只是代码可读性的问题。但 IMO 不需要同时支持 CommonJS 和 ES6 模块。坚持一个。

default 导出在 Node.js 应用程序中不是很方便,因为

const Struct = require('my-module').default;
const { default: Struct } = require('my-module');

require

更难阅读
const Struct = require('my-module');

由于与 CommonJS 模块的互操作在当前 Babel、TypeScript(带有 allowSyntheticDefaultImports 选项)和 Node 对 ES 模块(.mjs 模块)的原生支持中的工作方式,建议导出如下函数:

module.exports = Struct

所以它可以导入为

import Struct from './src/struct';

在 ES 模块中,以及

const Struct = require('./src/struct');

在 CommonJS 模块中。

Lets look at what Babel does when you do import foo from 'bar';:

'use strict';

var _bar = require('bar');

var _bar2 = _interopRequireDefault(_bar);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

你可以看到,根据导入模块的 "type",Babel 要么导入 default 导出,要么导入 module.exports(因为 require('bar') returns module.exports.

这意味着,为了让您的模块可以导入为

const Struct = require('my-module')
// and
import Struct from 'my-module'

你所要做的就是

module.exports = Struct;