likes
comments
collection
share

export/exports/export default/module.exports,傻傻分不清楚,到底在什么时候使用

作者站长头像
站长
· 阅读数 14

一、引言

在 Node.js 中,模块是指实现某个功能的一组代码,可以被其他模块引用和复用。在编写模块时,我们通常需要将模块中的某些代码导出,以便其他模块可以使用它们。Node.js 中提供了多种导入导出模块的方式。

二、CommonJS模块导出

CommonJS 是 Node.js 中最常用的模块规范,它定义了一套模块导入导出的机制。在 CommonJS 中,我们可以使用 exportsmodule.exports 两个对象来导出模块。后缀mjs是module JS的意思。

1.exports

exports是一个空对象,可以通过添加属性和方法来导出模块。

// math.js
exports.add = function(a, b) {
  return a + b;
};
exports.subtract = function(a, b) {
  return a - b;
};

在另一个模块中,我们可以使用 require 函数来引入这个模块,并使用它导出的方法。并且package.json文件中可以写"type": "commonjs";,也可以不写,因为type默认就是commonjs。

const math = require('./math');
console.log(math); //{ add: [Function (anonymous)], subtract: [Function (anonymous)] }
console.log(math.add(1, 2));       //3
console.log(math.subtract(5, 1)); //4

注意

通过import引入文件,只能写在全局作用域中,而不能写在其他作用域中,而require可以。

if(1){
  import {a} from './msg.js'; //报错
} else {
  const a = require('./msg'); //不报错
}

如下所示,直接通过import函数调用来引入模块是可以的。

const routes = [
  {
    path: '/home',
    component: () => import('./Home.vue') //动态加载模块,是异步的
  }
]

2.module.exports

// msg.js
function helloWorld(message){
  console.log(message);
}
console.log(module);
module.exports = helloWorld;
// receive.js
const helloWorld = require("./msg");
helloWorld("你好,世界!"); //你好,世界!

export/exports/export default/module.exports,傻傻分不清楚,到底在什么时候使用

在msg.js文件中,我们输出module,并且通过module.exports导出helloWorld函数。可以看到module是一个对象,它有id、path、exports、paths等属性,exports是其中的一个属性,它是一个对象。

在receive.js文件中,通过require引入msg.js文件,其中后缀.js可以省略,然后就可以直接使用helloWorld函数了。

// msg2.js
const name = "张三";
function helloWorld(message){
  console.log(message);
}
module.exports.name = name;
module.exports.helloWorld = helloWorld;
module.exports.name = name;
module.exports.helloWorld = helloWorld;

// 以上两行等价于
module.exports = {
    name,
    helloWorld
}
// receive2.js
const msg2 = require('./msg2');
console.log(msg2); //{ name: '张三', helloWorld: [Function: helloWorld] }
console.log(msg2.name); //张三
msg2.helloWorld("你好,世界!"); //你好,世界!

export/exports/export default/module.exports,傻傻分不清楚,到底在什么时候使用

在msg2.js文件中,有一个name变量和helloWorld函数,我们通过module.exports.namemodule.exports.helloWorld导出变量和方法。

在receive2.js文件中,通过require导入msg2.js中的变量和方法,并且使用这些变量和方法。输出msg2模块,可以看到它包括name和helloWorld。

解构

如果只需要导入模块中的特定变量或函数,可以使用解构赋值来选择性导入。

const { name, helloWorld } = require('./msg2');
console.log(name); //张三
helloWorld("你好,世界!"); //你好,世界!

别名

可以使用别名来导入模块的内容。这对于解决名称冲突或简化长模块名称很有用,这里name1是name的别名。

const { name:name1, helloWorld } = require('./msg2');
console.log(name1); //张三

使用const关键字声明常量

注意:在导入其他模块时,最好使用const关键字声明常量,防止模块被重置

var msg2 = require('./msg2');
msg2 = 123;
console.log(msg2); //123
console.log(msg2.name); //undefined
msg2.helloWorld("你好世界!");//报错,msg2.helloWorld is not a function


const msg2 = require('./msg2');
msg2 = 123; //报错,Assignment to constant variable.
console.log(msg2); 
console.log(msg2.name); 
msg2.helloWorld("你好,世界!");

直接导出模块

有时在一个模块中只导出一个成员,为方便其他模块使用,可以采用直接导出的方式。

// msg3.js
module.exports = function helloWorld(message){
  console.log(message);
}

// receive3.js
const helloWorld = require('./msg3');
helloWorld("你好,世界!"); //你好,世界!

三、ECMAScript模块导出

除了 CommonJS 规范外,Node.js 还支持 ECMAScript 模块规范。在 ECMAScript 中,我们可以使用 exportexport default 语句来导出模块。

  • export:用于导出模块中的变量、函数或类。
  • export default:用于导出模块的默认值,一个模块只能有一个默认导出。

在package.json文件中必须写"type": "module";,因为type默认就是commonjs。

1.export

// math.js
export function add(a, b) {
  return a + b;
}
export function subtract(a, b) {
  return a - b;
}
// 两种写法都可以
function add(a, b) {
  return a + b;
}
function subtract(a, b) {
  return a - b;
}
export {add, subtract}

在另一个模块中,我们可以使用 import 语句来引入这个模块,并使用它导出的方法。必须加上后缀js,不然会报错,在Vue中我们可以省略是因为webpack帮我们加上了。

import { add, subtract } from './math.js';
console.log(add(2, 3));        //5
console.log(subtract(5, 2));  //3

取别名

通过export导出时,我们可以用as关键字取别名。

// math.js
function add(a, b) {
  return a + b;
}
function subtract(a, b) {
  return a - b;
}
export {add as jia, subtract}

// receive.js
import { jia, subtract } from './math.js';
console.log(jia(2, 3));          //5
console.log(subtract(5, 2));  //3

整体引入

整体引入math.js,起名fn,然后通过fn去调用各个函数方法。

import * as fn from './math.js';
console.log(fn.add(2, 3));        //5
console.log(fn.subtract(5, 2));  //3

2.export default

export default 用于导出模块中的默认值,一个模块只能有一个默认值导出,不需要再打花括号了。

function add(a, b) {
  return a + b;
}
function subtract(a, b) {
  return a - b;
}
export default add;
import add from './math.js';
console.log(add(2, 3));        //5
console.log(subtract(5, 2));  //报错

也可以在函数之前写export default导出。

// math.js
export default function(a, b) {
  return a + b;
}
function subtract(a, b) {
  return a - b;
}

// receive.js
import add from './math.js';
console.log(add(2, 3));       //5
console.log(subtract(5, 2));  //报错

四、最后的话

在 Node.js 中,模块化是一种重要的开发概念。模块化允许我们将代码分割成独立的模块,以便于重用、维护和测试,导入和导出模块机制使得模块之间的协作变得更加容易。在编写模块时,可以根据自己的需要选择适当的导出方式。

能力一般,水平有限,本文可能存在纰漏或错误,如有问题欢迎大佬指正,感谢你阅读这篇文章,如果你觉得写得还行的话,不要忘记点赞、评论、收藏哦!祝生活愉快!