《解锁 JavaScript 模块化:导入导出实战指南》

《解锁 JavaScript 模块化:导入导出实战指南》

各种模块化的导入导出,总是傻傻分不清,碰到就是一团浆糊,就是分不清,今天来整理一下。

CommonJS 模块

导出:

ini 复制代码
module.exports = {
  name: 'John',
  age: 25
};

在这个例子中,使用 module.exports 对象来导出模块的内容。您可以将任何数据结构、函数、对象等赋值给 module.exports ,使其能够被其他模块导入和使用。

例如,如果模块中还定义了一个函数:

javascript 复制代码
function greet() {
  console.log('Hello!');
}
module.exports = {
  name: 'John',
  age: 25,
  greet: greet
};

导入:

ini 复制代码
const person = require('./person');
console.log(person.name); 

通过 require('./person') 语句来导入名为 person 的模块。这里的 './person' 表示相对路径。导入后,得到的模块内容被赋值给变量 person ,然后可以通过 person 对象来访问导出的属性和方法。

ES6 模块

导出:

dart 复制代码
// 导出单个值
export const num = 5;

使用 export 关键字来导出单个常量。

javascript 复制代码
// 导出函数
export function add(a, b) {
  return a + b;
}

直接在函数定义前加上 export 来导出函数。

javascript 复制代码
// 导出类
export class Person {
  constructor(name) {
    this.name = name;
  }
}

在类定义前加上 export 导出类。

ini 复制代码
// 导出多个值
const name = 'Alice';
const age = 30;
export { name, age };

先定义多个值,然后使用 export { 变量名 1, 变量名 2 } 的形式来一次性导出多个值。

导入:

javascript 复制代码
// 导入单个值
import { num } from './module';

通过 import 语句,使用花括号指定要导入的单个导出值。

csharp 复制代码
// 导入函数
import { add } from './module';

同样使用花括号指定要导入的函数。

javascript 复制代码
// 导入类
import { Person } from './module';

导入类的方式与导入其他值相同。

javascript 复制代码
// 导入多个值
import { name, age } from './module';

一次性导入多个值。

AMD 模块(Asynchronous Module Definition) 想象一下 AMD 模块就像是一个工厂。

define 函数就好比是这个工厂的建设规划。

规划里的第一个参数 ['dep1', 'dep2'] ,可以理解为这个工厂在生产过程中需要的原材料清单,比如 dep1 是钢材,dep2 是塑料。

第二个参数,也就是那个回调函数,就像是工厂的生产线。生产线上的 dep1dep2 就是已经运到生产线上的钢材和塑料。

在这个生产线上,工厂最终生产出一个产品,也就是通过返回的对象 { name: 'AMD Module' } ,这个产品就是这个工厂向外输出的东西。

require 函数呢,就像是一个客户下订单。['module'] 就是客户指定要的某个产品,比如就是我们刚刚说的那个工厂生产的产品。

当这个订单完成,也就是模块加载好之后,通过回调函数的参数 module ,客户就拿到了他想要的产品,然后就可以对这个产品进行使用,比如查看、操作等。

再给您举个更具体的例子。比如说我们要做一个游戏,有一个模块是负责生成地图,叫 mapModule

它依赖于另一个模块 tileModule (提供各种地图块)和 enemyModule (生成敌人)。

define 函数可能像这样:

javascript 复制代码
define(['tileModule', 'enemyModule'], function(tileModule, enemyModule) {
  return {
    generateMap: function() {
      // 使用 tileModule 和 enemyModule 来生成地图
      return '生成的地图数据';
    }
  };
});

虽然代码内部没有直接写明 mapModule ,但根据 AMD 的约定,这个模块就被默认命名为 mapModule

然后在游戏的其他部分,使用这个地图模块时:

javascript 复制代码
require(['mapModule'], function(mapModule) {
  const gameMap = mapModule.generateMap();
  // 后续使用生成的地图进行游戏逻辑处理
});

require 函数用于加载模块,并在回调函数中获取加载的模块对象进行使用。

UMD 模块(Universal Module Definition)

javascript 复制代码
(function (root, factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(['dep1', 'dep2'], factory);
    } else if (typeof exports === 'object') {
        // CommonJS
        module.exports = factory(require('dep1'), require('dep2'));
    } else {
        // 全局变量
        root.returnExports = factory(root.dep1, root.dep2);
    }
}(this, function (dep1, dep2) {
    return {
        name: 'UMD Module'
    };
}));

UMD 模块的目的是使模块在不同的环境(如 AMD 环境、CommonJS 环境、浏览器全局环境)中都能正确工作。它通过判断当前环境的类型来决定如何导出模块。如果支持 AMD ,就按照 AMD 方式导出;如果支持 CommonJS ,就按照 CommonJS 方式导出;否则,将模块对象赋给全局变量。

相关推荐
mldong6 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排7 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60617 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角8 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!8 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰9 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi10 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen11 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马12 小时前
AI源码分析:拆解模型底层实现逻辑
前端
IT_陈寒12 小时前
React子组件莫名其妙重渲染?你可能漏了这个Hook
前端·人工智能·后端