做者:Valentino Gagliardi
译者:前端小智
来源:valentinog
点赞再看,微信搜索
【大迁世界】 关注这个没有大厂背景,但有着一股向上积极心态人。本文
GitHub
https://github.com/qq44924588... 上已经收录,文章的已分类,也整理了不少个人文档,和教程资料。
ECMAScript模块(简称ES模块)是一种JavaScript代码重用的机制,于2015年推出,一经推出就受到前端开发者的喜好。在2015之年,JavaScript 尚未一个代码重用的标准机制。多年来,人们对这方面的规范进行了不少尝试,致使如今有多种模块化的方式。html
你可能据说过AMD模块,UMD,或CommonJS,这些没有孰优孰劣。最后,在ECMAScript 2015中,ES 模块出现了。前端
咱们如今有了一个“正式的”模块系统。node
理论上,ES 模块应该在全部JavaScript环境中。实际上,ES 模块的主要应用仍是在浏览器上。webpack
2020年5月,Node.js v12.17.0 增长了在不使用标记前提下对ECMAScript模块的支持。 这意味着咱们如今能够在Node.js
中使用import
和export
,而无需任何其余命令行标志。git
ECMAScript模块要想在任何JavaScript环境通用,可能还须要很长的路要走,但方向是正确的。github
ES 模块是一个简单的文件,咱们能够在其中声明一个或多个导出。如下面utils.js
为例:web
// utils.js export function funcA() { return "Hello named export!"; } export default function funcB() { return "Hello default export!"; }
这里有两个导出。json
第一个是命名导出,后面是export default
,表示为默认导出。redux
假设咱们的项目文件夹中有一个名为utils.js
的文件,咱们能够将这个模块提供的对象导入到另外一个文件中。promise
假设咱们在项目文中还有一个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模块,但有一些警告。 要使用模块,须要在 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(模块绑定器)独有的。
像React
和Vue
经过动态导入代码拆分来加载响应事件的代码块,好比用户交互或路由更改。
假设咱们项目有一个 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); }); });
这里咱们使用解构的方式取出 name
和 age
:
const { name, age } = module.default;
由于 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。