概述

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

参考资料:

异步函数 - 提高 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. 【leetcode389】389. Find the Difference

    异或 找不同 —.— public class Solution { public char findTheDifference(String s, String t) { char temp = 0 ...

  2. issue - 登录前的信息和标识文件

    DESCRIPTION (描述) /etc/issue 是一个文本文件,它包含了在登录提示符出现之前显示的信息或者系统标识.如果 getty(1) 支持的话,它可能包括多个 @char 和 \char ...

  3. MATLAB中产生高斯白噪声的两个函数

    MATLAB中产生高斯白噪声非常方便,可以直接应用两个函数,一个是WGN,另一个是AWGN.WGN用于产生高斯白噪声,AWGN则用于在某一信号中加入高斯白噪声.1.WGN:产生高斯白噪声 y = wg ...

  4. heartbeat如何避免脑裂

    heartbeat避免脑裂的方法 1)增加冗余的心跳线,例如双线条线,尽量减少脑裂发生的机会 2)启用磁盘锁:正在服务的一方锁住了共享磁盘,脑裂发生时,让对方完全抢走资源,如果占用资源的一方不解锁 , ...

  5. (转) Java中的负数及基本类型的转型详解

    (转) https://my.oschina.net/joymufeng/blog/139952 面这行代码的输出是什么? 下面两行代码的输出相同吗? 请尝试在Eclipse中运行上面的两个代码片段, ...

  6. Python核心技术与实战——十六|Python协程

    我们在上一章将生成器的时候最后写了,在Python2中生成器还扮演了一个重要的角色——实现Python的协程.那什么是协程呢? 协程 协程是实现并发编程的一种方式.提到并发,肯很多人都会想到多线程/多 ...

  7. python---注册表操作

    手动打开注册表   WIN+R      regedit 利用QSettings 一.创建子健和键值对 settings = QSettings("HKEY_CURRENT_USER\\So ...

  8. SpringCloud微服务面试题

    spring data是spring用于简化spring开发中数据访问操作的项目spring Dataspring Data为我们提供了使用统一的API来对数据访问层进行操作,这主要是Spring D ...

  9. encode()和decode()两个函数

    编码可以将抽象字符以二进制数据的形式表示,有很多编码方法,如utf-8.gbk等,可以使用encode()函数对字符串进行编码,转换成二进制字节数据,也可用decode()函数将字节解码成字符串:用d ...

  10. redis主从+keepalived实现高可用技术

    Redis是我们当下比较流行使用的非关系数据库,可支持多样化的数据类型,多线程高并发支持,redis运行在内存拥有更快的读写.因为redis的表现如此出色,如何能保障redis在运行中能够应对宕机故障 ...