使用 ES5 语法在 Node 中混合默认和命名导出

Posted

技术标签:

【中文标题】使用 ES5 语法在 Node 中混合默认和命名导出【英文标题】:Mixed default and named exports in Node with ES5 syntax 【发布时间】:2019-05-31 12:16:30 【问题描述】:

我在导出/导入模块方面的所有经验都来自使用 exportimport 的 ES6,您可以在其中执行类似的操作来让单个模块导出默认函数以及单独的命名函数。

// module.js
export default mainFunction
export  namedFunction 

// main.js
import mainFunction from 'functions'
mainFunction()

import  namedFunction  from 'function'
namedFunction()

但是,我不知道如何使用 module.exportsrequire 使用 ES5 样式导入来做到这一点。据我了解,我可以导出单个默认值:

// module.js
module.exports = function mainFunction() 

// main.js
const mainFunction = require('module.js')

或者我可以创建命名导出:

// module.js
module.exports = 
  namedFunction: function() 


// main.js
const namedFunction = require('module.js').namedFunction

但我不能两者都做。我想我可以像这样将其中一个导出命名为“默认”,但它不起作用

// module.js
module.exports = 
  default: function() ,
  namedFunction: function() 


// main.js
const mainFunction = require('module.js') // does not work
const mainFunction = require('module.js').default // works, but not what I want
const namedFunction = require('module.js').namedFunction

如何使用 ES5 完成这种双重默认/命名导出?

【问题讨论】:

ES6 中的导出(使用 babel 编译)导出默认为一个名为 default 的属性并设置一个属性 _esModule。导入默认模块时,如果存在_esModule,则会导入default。否则,它将整个模块作为默认值导入。这种行为导致了一些confusion。 【参考方案1】:

您希望将 module.exports 的值指定为默认函数,然后将所有命名导出作为该函数的属性。

const defaultFunction = () =>  console.log('default!'); ;
const namedFunction1 = () =>  console.log('1!'); ;
const namedFunction2 = () =>  console.log('2!'); ;

const myModule = module.exports = defaultFunction;
myModule.namedFunction1 = namedFunction1;
myModule.namedFunction2 = namedFunction2;

假设那是在myModule.js。然后你可以这样做:

const myModule = require('./myModule');
myModule(); // Prints: 'default!'
myModule.namedFunction1(); // Prints: '1!'

【讨论】:

我假设是有原因的,但为什么不直接分配给 module.exports?我试过了,它似乎工作正常:module.exports = defaultFunction; module.exports.namedFunction1 = namedFunction1; @arichards 如果这对您来说更容易/更好,那么应该可以。如果我有理由确定该函数将在使用它的地方被称为myModule,那么我也喜欢在它被定义的地方称它为myModule。但这只是我的偏好。【参考方案2】:

如果您不想重复命名导出,您可以随时执行类似的操作

module.exports = defaultFunction;
module.exports = Object.assign(module.exports, 
    namedFunction1,
    namedFunction2,
);

那么你就可以正常要求了;

const myModule = require('./myModule');
myModule();
myModule.namedFunction1();

【讨论】:

这破坏了 VSCode 在 requireing 模块时提供的好建议 你是说智能感知?有趣【参考方案3】:

只需将exports 重新分配给module.exports

喜欢:

//name.js

const NameType = 
  foo: "bar",
;

function Name(name) 
  this.name = name;


module.exports = Name; // assign default export to Name
exports = module.exports; // re-assign exports to point it to the updated location.

exports.NameType = NameType; // now you can use named export as usual

在另一个文件中你可以像这样导入:

const Name = require("./name");
const  NameType  = require("./name");

这是因为 默认 module = exports: exports = module.exports

参考:Difference between "module.exports" and "exports" in the CommonJs Module System

【讨论】:

以上是关于使用 ES5 语法在 Node 中混合默认和命名导出的主要内容,如果未能解决你的问题,请参考以下文章

ES5匿名函数的打字稿导入

混合默认和命名导入

React笔记__react语法5

ES6 模块

webpack babel 怎么将Object.assign() 转成es5语法

node.js的基本语法