乐趣区

关于javascript:这些-ECMAScript-模块知识都是我需要知道的

作者:Valentino Gagliardi
译者:前端小智
起源:valentinog

点赞再看,微信搜寻 【大迁世界】 关注这个没有大厂背景,但有着一股向上踊跃心态人。本文 GitHub https://github.com/qq44924588… 上曾经收录,文章的已分类,也整顿了很多我的文档,和教程材料。

ES 模块是什么?

ECMAScript 模块(简称 ES 模块)是一种 JavaScript 代码重用的机制,于 2015 年推出,一经推出就受到前端开发者的青睐。在 2015 之年,JavaScript 还没有一个代码重用的规范机制。多年来,人们对这方面的标准进行了很多尝试,导致当初有多种模块化的形式。

你可能据说过 AMD 模块UMD,或CommonJS,这些没有孰优孰劣。最初,在 ECMAScript 2015 中,ES 模块 呈现了。

咱们当初有了一个“正式的”模块零碎。

ES 模块无处不在?

实践上,ES 模块应该在所有 JavaScript 环境中。实际上,ES 模块的次要利用还是在浏览器上。

2020 年 5 月,Node.js v12.17.0 减少了在不应用标记前提下对 ECMAScript 模块的反对。这意味着咱们当初能够在 Node.js 中应用 importexport ,而无需任何其余命令行标记。

ECMAScript 模块要想在任何 JavaScript 环境通用,可能还须要很长的路要走,但方向是正确的。

ES 模块是什么样的

ES 模块是一个简略的文件,咱们能够在其中申明一个或多个导出。以上面 utils.js 为例:

// utils.js
export function funcA() {return "Hello named export!";}

export default function funcB() {return "Hello default export!";}

这里有两个导出。

第一个是 命名导出 ,前面是export default,示意 为默认导出

假如咱们的我的项目文件夹中有一个名为 utils.js 的文件,咱们能够将这个模块提供的对象导入到另一个文件中。

如何从 ES 模块 导入

假如咱们在我的项目文中还有一个 Consumer.js 的文件。要导入 utils.js 公开的函数,咱们能够这样做:

// consumer.js
import {funcA} from "./util.js";

这种对应咱们的 命名导入 形式.

如果咱们要导入 utils.js 中的默认导出也就是 funcB 办法,咱们能够这样做:

// consumer.js
import {funcA} from "./util.js";

当然,咱们能够导入同时导入命名和默认的:

// consumer.js
import funcB, {funcA} from "./util.js";

funcB();
funcA();

咱们也能够用星号导入整个模块:

import * as myModule from './util.js';

myModule.funcA();
myModule.default();

留神,这里要应用默认到处的办法是应用 default() 而不是 funcB()

从近程模块导入:

import {createStore} from "https://unpkg.com/redux@4.0.5/es/redux.mjs";

const store = createStore(/* do stuff */)

浏览器中的 ES 模块

古代浏览器反对 ES 模块,但有一些正告。要应用模块,须要在 script 标签上增加属性 type,对应值 为 module

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ECMAScript modules in the browser</title>
</head>
<body>
<p id="el">The result is: </p>
</body>
<script type="module">
    import {appendResult} from "./myModule.js";

    const el = document.getElementById("el");
    appendResult(el);
</script>
</html>

myModule.js 内容如下:

export function appendResult(element) {const result = Math.random();
  element.innerText += result;
}

动静导入

ES 模块是动态的,这意味着咱们不能在运行时更改导入。随着 2020 年推出的动静导入(dynamic imports),咱们能够动静加载代码来响应用户交互(webpack 早在 ECMAScript 2020 推出这个个性之前就提供了动静导入)。

思考上面的代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Dynamic imports</title>
</head>
<body>
<button id="btn">Load!</button>
</body>
<script src="loader.js"></script>
</html>

再思考一个带有两个导出的 JavaScript 模块

// util.js
export function funcA() {console.log("Hello named export!");
}

export default function funcB() {console.log("Hello default export!");
}

为了动静导入 util.js 模块,咱们能够点击按钮在去导入:

/ loader.js
const btn = document.getElementById("btn");

btn.addEventListener("click", () => {
  // loads named export
  import("./util.js").then(({funcA}) => {funcA();
  });
});

这里应用解构的形式,取出 命名导出 funcA 办法:

({funcA}) => {}

ES 模块实际上是 JavaScript 对象:咱们能够解构它们的属性以及调用它们的任何公开办法。

要应用动静导入的默认办法,能够这样做

// loader.js
const btn = document.getElementById("btn");

btn.addEventListener("click", () => {import("./util.js").then((module) => {module.default();
  });
});

当作为一个整体导入一个模块时,咱们能够应用它的所有导出

// loader.js
const btn = document.getElementById("btn");

btn.addEventListener("click", () => {
  // loads entire module
  // uses everything
  import("./util.js").then((module) => {module.funcA();
    module.default();});
});

还有另一种用于动静导入的常见款式,如下所示:

const loadUtil = () => import("./util.js");

const btn = document.getElementById("btn");

btn.addEventListener("click", () => {//});

loadUtil返回的是一个 promise,所以咱们能够这样操作

const loadUtil = () => import("./util.js");

const btn = document.getElementById("btn");

btn.addEventListener("click", () => {loadUtil().then(module => {module.funcA();
    module.default();})
})

动静导入看起来不错,然而它们有什么用呢?

应用动静导入,咱们能够拆分代码,并只在适当的时候加载重要的代码。在 JavaScript 引入动静导入之前,这种模式是 webpack(模块绑定器)独有的。

ReactVue通过动静导入代码拆分来加载响应事件的代码块,比方用户交互或路由更改。

动静导入 JSON 文件

假如咱们我的项目有一个 person.json 文件,内容如下:

{
  "name": "Jules",
  "age": 43
}

当初,咱们须要动静导入该文件以响应某些用户交互。

因为 JSON 文件不是一个办法,所以咱们能够应用 默认导出 形式:

const loadPerson = () => import('./person.json');

const btn = document.getElementById("btn");

btn.addEventListener("click", () => {loadPerson().then(module => {const { name, age} = module.default;
    console.log(name, age);
  });
});

这里咱们应用解构的形式取出 nameage :

const {name, age} = module.default;

动静导入与 async/await

因为 import() 语句返回是一个 Promise,所以咱们能够应用 async/await:

const loadUtil = () => import("./util.js");

const btn = document.getElementById("btn");

btn.addEventListener("click", async () => {const utilsModule = await loadUtil();
  utilsModule.funcA();
  utilsModule.default();})

动静导入的名字

应用 import() 导入模块时,能够依照本人的志愿命名它,但要调用的办法名保持一致:

import("./util.js").then((module) => {module.funcA();
    module.default();});

或者:

  import("./util.js").then((utilModule) => {utilModule.funcA();
    utilModule.default();});

原文:https://www.valentinog.com/bl…

代码部署后可能存在的 BUG 没法实时晓得,预先为了解决这些 BUG,花了大量的工夫进行 log 调试,这边顺便给大家举荐一个好用的 BUG 监控工具 Fundebug。

交换

文章每周继续更新,能够微信搜寻 【大迁世界】 第一工夫浏览,回复 【福利】 有多份前端视频等着你,本文 GitHub https://github.com/qq449245884/xiaozhi 曾经收录,欢送 Star。

退出移动版