JavaScript模块化导入和导出

JavaScript模块化的基本用法

概述

JavaScript模块化是一种将代码分割成独立模块的技术,每个模块负责一个特定的功能。

基础知识

在HTML中,通过在<script>标签中添加type="module"属性指示引入的模块:

<script type="module" src="./main.js"/>

或,直接将模块的脚本嵌入到Html文件中:

<script type="module">
    /* JavaScript 模块代码 */
</script>

注:importexport声明只能在模块脚本(type="module")内使用,不能在常规脚本中使用。

export

export声明用于将模块中的变量、函数或类导出,以便其他模块可以导入和使用它们。

  • 将export放到想要导出的项的前面
export const apple = "Apple";

export function sayHello() {
    console.log("Hello");
}
  • 在模块文件末尾使用一个export语句,以花括号和逗号分隔的形式列出所需导出的功能
const apple = "Apple";

function sayHello() {
    console.log("Hello");
}

export { apple, sayHello };

import

import声明用于从其他模块导入导出的项,其必须位于模块的顶级作用域中,不能在块或函数内部使用。

作用域范围

import声明的作用域仅限于当前模块文件。这意味着在当前模块中导入的内容只能在该模块内部使用,不能在其他模块中直接访问。

例如,你有两个模块文件:utils_1.js和utils_2.js。

在utils_1.js文件中导入模块:

import * as myModule from "/modules/my-module.js";

显然,你无法在utils_2.js文件中访问在utils_1.js文件中导入的myModule对象。

具名导入

具名导入允许你从模块中导入特定的导出成员。语法如下:

import {export1, export2} from "/modules/my-module.js";

默认导入

默认导入部分可以参考MDN Web Docs,这部分很详细了。

语法如下:

import myDefault from "/modules/my-module.js";

相当于下面这行的缩写:

import { default as myDefault } from "/modules/my-module.js";

也可以在使用命名空间导入或具名导入时指定默认导入,在这种情况下,必须首先声明默认导入:

import myDefault, * as myModule from "/modules/my-module.js";

import myDefault, { foo, bar } from "/modules/my-module.js";

一个模块只能有一个默认导出,默认导出可以是一个值,并且在导入时可以使用任意名称来引用它。

export default xxx;

命名空间导入

import * as myModule from "/modules/my-module.js";

其中,myModule是一个命名空间对象,包含了模块中所有的导出内容,如果模块中包含默认导出,它将作为命名空间对象的一个属性,名称为default:

// constTemp.js
export default const a = 12;

在main.js中,可以这样访问默认导出:

// main.js
import * as myModule from "./modules/constTemp.js";

console.log(myModule.default);

副作用导入

导入整个模块只是为了产生副作用,而不导入任何内容。

用途:

  • 初始化模块
  • 注册全局功能
  • 执行配置代码
import "/modules/my-module.js";

导入映射

文档中只能有一个导入映射,用于解析静态和动态导入的模块。

在index.html文件中,添加:

<script type="importmap">
  {
    "imports": {
      "alisName1": "./modules/moduleName1.js",
      "alisName2": "./modules/moduleName2.js",
      "alisName3/": "./modules/utils_modules/"
    }
  }
</script>

在main.js文件中导入模块:

import * from "alisName1";
import * from "alisName2";
import * from "alisName3";

其中,模块标识符前缀alisName3/映射为整个包下的js文件。

特性检测

可以使用以下语句来检查浏览器是否支持导入映射:

HTMLScriptElement.supports?.("importmap")

image

导入非JavaScript资源

默认情况下,浏览器假定资源是JavaScript

import colors from "./colors.json" with { type: "json" };
import styles from "./styles.css" with { type: "css" };

示例

基本示例文件结构:

- Root
    - modules
        - xxx.js
    - index.html
    - main.js

具名导入

  1. modules文件夹下新建namedImport.js文件:
// modules/namedImport.js
class Apple{
    name;       // 名称
    cultivar;   // 种类

    constructor(name, cultivar)
    {
        this.name = name;
        this.cultivar = cultivar;
    }
}

function createApple(name, cultivar)
{
    return new Apple(name, cultivar);
}

export { Apple, createApple };
  1. main.js文件中导入createApple函数:
import {createApple} from "./modules/namedImport.js";

function logApple()
{
    let apple = createApple("RedApple", "XXX");

    console.log(apple.name);
}

addEventListener("DOMContentLoaded", logApple);
  1. index.html文件中引用main.js
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script type="module" src="main.js"></script>
</head>
<body>
    <p>具名导入</p>
</body>
</html>
  1. 在VSCode中使用Live Server扩展打开本地服务器:

image

  1. 在浏览器中打开开发者工具查看控制器输出:

image

默认导入

  1. modules文件夹下新建defaultImport.js文件:
// modules/defaultImport.js
class Apple{
    name;       // 名称
    cultivar;   // 种类

    constructor(name, cultivar)
    {
        this.name = name;
        this.cultivar = cultivar;
    }
}

function createApple(name, cultivar)
{
    return new Apple(name, cultivar);
}

export default createApple;
  1. main.js文件中导入createApple函数:
import myDefault  from "./modules/defaultImport.js";

function logApple()
{
    let apple = myDefault ("YellowApple", "XXX");

    console.log(apple.name);
}

addEventListener("DOMContentLoaded", logApple);
  1. 在浏览器中打开开发者工具查看控制器输出:

image

命名空间导入

  1. modules文件夹下新建namespaceImport.js文件:
// modules/namespaceImport.js
class Apple{
    name;       // 名称
    cultivar;   // 种类

    constructor(name, cultivar)
    {
        this.name = name;
        this.cultivar = cultivar;
    }
}

function createApple(name, cultivar)
{
    return new Apple(name, cultivar);
}

const apple = new Apple("BlueApple", "xxx");

export default apple;

export { createApple };
  1. main.js文件中导入createApple函数和默认导出apple
import * as myModule  from "./modules/namespaceImport.js";

function logApple()
{
    console.log(myModule.default.name);

    console.log(myModule.createApple("PurpleApple", "xxx"));
}

addEventListener("DOMContentLoaded", logApple);
  1. 在浏览器中打开开发者工具查看控制器输出:

image

副作用导入

  1. modules文件夹下新建analytics.js文件:
console.log("the module loaded.");

window.addEventListener("click", () => {
  console.log("Click event tracked.");
});
  1. main.js文件中导入analytics.js文件:
// main.js
import "./analytics.js"; // 副作用导入

console.log("Main script executed.");
  1. 在浏览器中打开开发者工具查看控制器输出:

image

参考文章

  1. MDN Web Docs JavaScript参考-语句和声明-import
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/import

  2. JavaScirpt指南-JavaScript模块
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Modules

声明

内容准确性: 我会尽力确保所分享信息的准确性和可靠性,但由于个人知识有限,难免会有疏漏或错误。如果您在阅读过程中发现任何问题,请不吝赐教,我将及时更正。

posted on 2025-02-05 11:37  wubing7755  阅读(431)  评论(0)    收藏  举报