ESM( ECMAScript Module)

260 阅读1分钟

Why

  • Daily Code
  • Tree Shaking
    • ES6 模块依赖关系是确定的,和运行时的状态无关,可以进行可靠的静态分析,这就是 tree-shaking 的基础

特点

ES6 模块在编译时就会静态分析,所以不能玩骚操作

由于 import 是静态执行,所以 import 具有提升效果

《你不知道的 JavaScript 上卷》

if (cond) {
  import xxx from "xxxx";
}

想要骚操作

动态 import()

require.ensure 只在浏览器有用武之地,浏览器异步加载模块。

CommonJS 模块可以在运行时确认模块加载。

  • 基于 Promise
  • 可以在脚本的任何地方使用
export const foo = "HSQ MODULE";
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>ESM</title>
  </head>

  <body></body>
</html>
<script type="module">
  const str = "./b.js";
  if (Math.random() < 0.5) {
    import("./b.js").then(({ foo }) => {
      console.log(foo);
    });
  }
  import(str).then(({ foo }) => {
    console.log(foo);
  });
</script>

Promise.all 进行并行异步加载

Promise.all([import("./a.js"), import("./b.js"), import("./c.js")]).then(
  ([a, { default: b }, { c }]) => {
    console.log("a.js finish");
    console.log("b.js finish");
    console.log("c.js finish");
  }
);

Promise.race测速

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body></body>
</html>
<script>
  const CDNs = [
    {
      name: "Redux ",
      url: "https://cdn.bootcdn.net/ajax/libs/redux/4.1.0/redux.js",
    },
    {
      name: "Lodash ",
      url: "https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.core.js",
    },
  ];

  Promise.race([
    import(CDNs[0].url).then((res) => CDNs[0].name),
    import(CDNs[1].url).then((res) => CDNs[1].name),
  ]).then((res) => {
    console.log(res);
  });
</script>