概述

本文是我在查资料的时候学到的一些东西,记录下来,供以后开发时参考,相信对其他人也有用。

参考资料:

异步函数 - 提高 Promise 的易用性

深入 CommonJs 与 ES6 Module

聊聊 package.json 文件中的 module 字段

异步 map

我们知道,Array.map 能够遍历 Array 里面的每一个元素,然后组成一个新的数组,它的参数是一个函数。如果这个函数里面有异步方法会怎样呢?

const jsonPromises = urls.map(async url => {
const response = await fetch(url);
return response;
});

上面的例子中,在 Array.map 里面接了一个 async 函数,它不在乎我提供给它的是不是异步函数,只把它当作一个返回 Promise 的函数来看待。 也就是说:它不会等到第一个函数执行完毕就会调用第二个函数。

虽然上面的例子初看很惊艳,但是我没有找到实际的应用场景。。。

前端模块化

前端模块化发展这么久了,目前比较流行的模块化方案主要有下面三种:

  1. umd 模块(通用模块)
  2. CommonJs 模块(node模块)
  3. es6 module(浏览器模块)

umd 模块

使用 UMD 规范的 js 文件的后缀通常写成 .umd.js

UMD 模块是以前比较流行的模块化方案,它的主要代码如下所示:

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global.libName = factory());
}(this, (function () { 'use strict';})));

这段代码判断运行环境,如果是 node 环境就使用 CommonJs 规范,如果不是则判断是否为 amd 环境,如果是则使用 AMD 规范,如果不是则导出为全局变量。所以 UMD 模块化是 amd + commonjs + 全局变量 这三种风格的结合。

因为 UMD 模块既能使用在浏览器环境,也能使用在 node 环境。所以现在需要在 html 中用 script 标签引入的包大多数都是用 UMD 模块。

CommonJs

使用 CommonJs 规范的 js 文件的后缀通常写成 .cjs.js

CommonJs 规范是 node 使用的模块体系,所有在 node 运行的包都是 CommonJs 规范。示例如下:

// foo.js
module.exports.foo = 2; // index.js
const foo = require('./foo');

CommonJs 规范打包之后就变成类似下面这个样子:

(function (exports, require, module, __filename, __dirname) { ...

es6 module

es6 module 规范又被称为 ESM 规范,使用这个规范的 js 文件的后缀通常写成 .esm.js

CommonJs 规范是 我们开发的时候 使用的模块体系。示例如下:

// foo.js
export default function () {} // index.js
import foo from './foo';

静态规范与 tree shaking

我们经常听到别人说,CommonJs 模块规范是动态的,所以在任何时刻都能使用 require 引入包;而 ESM 模块规范是静态的,所以只能在最开始使用 import 引入包,而且会在编译的时候确定导入和导出。

下面解释下为什么 CommonJs 模块规范是动态的而 ESM 模块规范是静态的?

因为在 node 端,当我们 require 一个包的时候,我们只需要从磁盘里面加载这个包的内容即可,非常迅速;但是如果在浏览器端引入一个包的时候,需要从网络上发送 http 请求加载这个包,耗时非常久,会导致浏览器阻塞,所以不能当代码执行一半的时候引入包,而需要在顶层一次性把包全部引入。(而且是异步引入)

由于,ESM 模块需要在编译的时候引入包,这个缺点却带来一个意想不到的好处,就是 tree shaking。说白了,就是可以在编译的时候确定哪些代码被实际引入了,哪些没有,然后那些没有被实际引用的代码就不会被打包!!!这样可以极大的减少打包体积。

pkg.module

但是我们在实际打包的时候,会忽略 node_modules 里面的内容,直接引入里面的包,而里面的包大多使用的是 UMD 规范,它在 node 端打包的时候是 CommonJs 规范,而 CommonJs 规范是动态的,编译的时候不知道哪些代码没有被使用,所以就不能 tree shaking

这样打包 node_modules 里面的包的时候岂不是会打包很多无用的代码???

这个时候 pkg.module 就应运而生了,pkg.module 指的是 package.json 文件中的 module 字段。我们知道 package.json 文件中 main 字段指向的就是打包后的代码,这个代码一般是 UMD 规范。而 module 字段指向的是 ESM 规范编写的代码!!!这样我们在引入 node_modules 的时候,如果引用的是 module 字段指向的代码,我们就可以对这个包进行 tree shaking 了!!!

异步 map 和模块打包的更多相关文章

  1. js模块化/js模块加载器/js模块打包器

    之前对这几个概念一直记得很模糊,也无法用自己的语言表达出来,今天看了大神的文章,尝试根据自己的理解总结一下,算是一篇读后感. 大神的文章:http://www.css88.com/archives/7 ...

  2. 一份关于webpack2和模块打包的新手指南(二)

    插件 我们已经看到一个内置的webpack插件的例子,在npm run build脚本中调用的webpack -p命令就是使用webpack附带的UglifyJsPlugin插件以生产模式压缩打包文件 ...

  3. 多模块打包后,扫描不到@controller和@service,实现 ADD DIRECTORY ENTRIES

    多模块打包后,扫描不到@controller和@service等Bean. 原因:打包时没有生成目录信息 解决办法: 1.在eclipse或者myeclipse 打包时 勾选 ADD DIRECTOR ...

  4. Webpack - CommonJs & AMD 模块打包器

    Webpack 是一个 CommonJs & AMD 模块打包器.可以把你的 JavaScript 代码分离为多个包,在需要的时候进行加载,支持预处理文件,例如 json, jade, cof ...

  5. Maven之多模块打包成一个jar包及assembly

    一.多模块打包 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  6. 一份关于webpack2和模块打包的新手指南

    webpack已成为现代Web开发中最重要的工具之一.它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片.它可以让你更好地控制应用程序所产 ...

  7. 【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar

    ======================================================================================== 引申:maven打包多 ...

  8. Zepto自定义模块打包构建

    文章转自 http://www.chengxuyuans.com/web_technology/zeptojs-build.html zepto.js 是个好东西,遵循 jQuery API,但比 j ...

  9. python模块打包方法

    http://www.jb51.net/article/92789.htm 一 首先将模块的目录结构整理如下: VASPy/ ├── LICENSE ├── MANIFEST ├── MANIFEST ...

随机推荐

  1. Json解析报错: Error is : Unescaped control character...的解决方法

    在利用json-framework来实现json解析的过程时,会出现"-JSONValue Failed. Error is : Unescaped control character&qu ...

  2. HashMap的相关面试题

    HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...

  3. Linux日常之命令sed

    一. 命令sed简介 利用命令sed能够同时处理多个文件多行的内容,可以不对原文件改动,仅把匹配的内容显示在屏幕上,也可以对原文件进行改动,但是不会在屏幕上返回结果,若想查看改动后的文件,可以使用命令 ...

  4. 摘抄 <关于 作为>

    出路在哪里?出路在于思路! 其实,没有钱.没有经验.没有阅历.没有社会关系,这些都不可怕.没有钱,可以通过辛勤劳动去赚:没有经验,可以通过实践操作去总结:没有阅历,可以一步一步去积累:没有社会关系,可 ...

  5. php判断变量是否为数字is_numeric()

    is_numeric — 检测变量是否为数字或数字字符 <?php $tests = array( "31", 1380, "1e4", "no ...

  6. [易学易懂系列|rustlang语言|零基础|快速入门|(6)|变量绑定]

    [易学易懂系列|rustlang语言|零基础|快速入门|(6)] 有意思的基础知识 变量绑定 我们现在回过头来看看,一些基础知识. 因为理解了前面的重要概念:所有权,借用,生命周期. 我们现在看基础知 ...

  7. python数据类型基础与解压缩

    ''' python数据类型基础与解压缩 ''' # a = 10 # b = 10 # c = 10 # 定义变量就是拿来用的, # 链式赋值 a = b = c = 10 print(a, b, ...

  8. 【HDU5289】Assignment

    题目大意:给定一个长度为 N 的序列,求序列中最大值和最小值相差小于 K 的连续段的个数. 题解: 最大值和最小值相差不超过 K 是一个在值域角度的限制,应考虑采用平衡树或权值...数据结构进行维护. ...

  9. UI控件Telerik UI for WPF发布R2 2019|附下载

    Telerik UI for WPF拥有超过100个控件来创建美观.高性能的桌面应用程序,同时还能快速构建企业级办公WPF应用程序.UI for WPF支持MVVM.触摸等,创建的应用程序可靠且结构良 ...

  10. SQL语句 函数

    6.4 Functions   6.4.1 Numeric abs/mod 绝对值/求模 sqrt/power/exp 求幂 ceil/floor/round 取整 trunc 截取小数点 sin/c ...