nodejs模块/文件导出与引入总结:一次搞懂export、export default、module.exports、exports

太迷了,为避免后面再次忘记或混淆,总结下来一次理清楚这些。

目录

导出方

引入方

总结

module.exports、exports

export、export default


如果想快速看结论,可跳过前面的典型案例!

下面以详细案例举例,下述的文件都在同一目录下。

导出方

导出方1:export.js

// 基于export导出时可以是多个
export let m = 91
export let n = 92

导出方2:export_default.js

// 调用方import sub0  from "./export_default.js"
export default function sub0(a, b) {return a - b;
}

导出方3:mod_exports.js

const y0 = 100// 故意分两部分来导入看看其用法,第一部分以给module.exports直接赋值导出
module.exports = {y0: y0,     // es6中,导出的名称和原名称一样时,也可以直接y0,无需使用冒号multiply0: function multiply(a, b) {   // 导出用于计算乘法的函数,导出名称叫multiply0return a * b}
}// 第二部分以module.exports.xxx导出,给module.exports挂载一个新属性sub
// 引入方使用const mod = require("./mod_exports");导入
module.exports.sub  = function (a, b) {return a - b;
}

导出方4:exports.js

const x = 10
const y = 20function add(a, b) {return a + b
}function Person(name, age) {this.name = namethis.age = age
}// 在一个文件或模块中,export、import可以有多个,export default仅有一个
exports.addFunc = add   // 导出add函数并给出别名addFunc
exports.xNum = x   // 导出变量x,别名为xNum
exports.y = y       // 导出变量yexports.multiply = function multiply(a, b) {   // 导出用于计算乘法的函数,导出名称叫multiplyreturn a * b
}// 换一种方式,把Person给module.exports挂载上去
// 上述exports.xxx和下面的module.exports.xxx的方式实际一样
module.exports.Person = Person       // 导出Person构造函数

引入方

下面看调用方(模块引入方),共两个文件。

引入方1:call.js  用来验证module.exports和exports

// 注意,加了"type": "module",就不能以require导包了,否则报错ReferenceError: require is not defined in ES module scope, you can use import instead
// 本文件在没有"type": "module",配置的条件下执行
const funcs = require("./exports")// const funcs = require("funcs")  // 注意 Error: Cannot find module 'funcs'
const xNum = require("./exports").xNum   // 单独导出xNum
const multiplyFunc = require("./exports").multiply   // 单独导出乘法匿名函数,并起名叫multiplyFunc// 用funcs来调用,使用基于exports导出的函数、变量等
console.log(funcs.addFunc(1, 2))   // 3
console.log(funcs.addFunc("a", "b"))  // ab
console.log(funcs.xNum)  // 10
console.log(xNum - 1)   // 9
console.log(xNum + "x")   // 10xconst y = require("./exports").y   // 单独导出y
console.log(y + 1)   // 21console.log(multiplyFunc(5, 5))   // 25
// 用funcs来调用
console.log(funcs.multiply(5, 5))   // 25const p1 = new funcs.Person("名称", 99)
console.log("p1: ", p1)   // Person { name: '名称', age: 99 }
console.log("p1.name: ", p1.name)   // 名称const p2 = new funcs.Person()
p2.name = "名称1"
p2.age = 99
console.log("p2: ", p2)   // Person { name: '名称1', age: 99 }
console.log("p2.name: ", p2.name)   // 名称1// 使用基于module.exports导出的函数、变量等
const mod = require("./mod_exports");
console.log(mod.y0)   // 100
console.log(mod.sub(20, 5))   // 15  调用以module.exports方式导出的减法函数
console.log(mod.multiply0(20, 5))   // 100  调用以module.exports方式导出的乘法函数

引入方2:call_byimport.js 用来验证export和export default

// 本导入需在有"type": "module",配置的条件下执行
// 引入基于export default导出的函数、变量等
import sub0  from "./export_default.js"
console.log(sub0(100, 5))   // 95// 本导入需在有"type": "module",配置的条件下执行
// 引入基于export导出的函数、变量等
// 注意此时import {m,n}中的m和n必须和export时的一致,如写为{m1,n}会提示SyntaxError: The requested module './export.js' does not provide an export named 'm1'
import {m,n} from "./export.js"
console.log(m,n)  // 91 92

上述是正常情况下的指向,结果已随行写出,各位看官各细细观察。


重要

module.exports、exports导出时,如果引入方必须要用import导入,那没辙,会有这个报错:

 SyntaxError: The requested module './mod_exports.js' does not provide an export named 'y0' 

万事不要强求,如下看起来没毛病,但实际不行(加  "type": "module",也一样)

import {y0,sub,multiply0} from "./mod_exports.js"
console.log(y0)   //  调用以module.exports方式导出的y0
console.log(sub(20, 5))   //  调用以module.exports方式导出的减法函数
console.log(multiply0(20, 5))   //  调用以module.exports方式导出的乘法函数

此种情况用require就可以了。

总结

这四个操作都可以向(模块)外暴露成员。

前两者export、export default可为一组,是es6的规范,和import匹配,import是es6中的语法标准;
后两者module.exports、exports可为一组,是commonjs的规范,和require匹配,require是amd规范下的引入方式。

当组合不适配时,当然就会报错了。

module.exports、exports

1,从使用方式来看,exports是module的一个属性

2,exports默认指向module.exports对象的引用,不能单独给exports赋值,否则无用(改变了exports的指向),引入方什么也拿不到;可给module.exports赋值,或通过module.exports.xx来挂载新属性xx等。

3,不论是module.exports还是exports,向外共享的最终结果是module.exports所指的对象,这两个没什么区别。

4,基于require引入module.exports、exports导出的成员时,括号里的文件不需要带.js,带上也能运行成功。

export、export default

1,export和export default都可以用于导出常量,函数,模块,文件等,export default是把此命令后面的变量赋值给default这个特殊的系统变量,并把它导出到其余模块中使用,仅导出模块中一个成员时可使用。

2,以export方式导出时,导入时要加{};以export default导出时,导入时不需要{}

3,export可有多个,export default只能有一个,多个export default会提示TS2528: A module cannot have multiple default exports.

4,用export default导出时的名称可以与引入时的名称不同,但export导出必须和import时名称一致;

5,基于import引入export、export default导出的成员时,from后的文件需要带.js后缀。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部