概述

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

参考资料:

异步函数 - 提高 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. OneDrive高速下载链接分享

    目录 1. 下载帮助 2. 本文地址 3. 资源链接 4. 打赏&支持 5. 关于&联系我 1. 下载帮助 OneDrive下载教程,建议不了解的先看下: https://www.cn ...

  2. Big Data(七)MapReduce计算框架(PPT截图)

    一.为什么叫MapReduce? Map是以一条记录为单位映射 Reduce是分组计算

  3. Codeforces 982 树边两端点计数偶数连通块 鲨鱼活动最小K最大location 扩展欧几里得方块内光线反射

    A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...

  4. linux下部署nginx服务

    1.安装依赖包  yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel 2.下载并解压安装包  cd /usr/loc ...

  5. python 小题

    python 小题:给定一个字符串,找出不含有重复字符的最长子串的长度.示例 1:输入: "abcabcbb"输出: 3 解释: 无重复字符的最长子串是 "abc&quo ...

  6. CentOS7安装codeblocks

    1.yum -y install epel-release 2.yum clean all && yum makecache 3.yum -y install gtk2-devel c ...

  7. ELK+Filebeat+redis整合

    前面的博客,有具体的ELK安装配置步骤,此处在其基础上修改 修改配置文件并启动 [root@topcheer filebeat-6.2.3-linux-x86_64]# vim filebeat.ym ...

  8. HDU 2923 Relocation(状压dp+01背包)

    题目代号:HDU2923 题目链接:http://poj.org/problem?id=2923 Relocation Time Limit: 1000MS Memory Limit: 65536K ...

  9. Maven开发环境搭建

    配置Maven流程: 1.下载Maven,官网:http://maven.apache.org/ 2.安装到本地: 1 ).解压apache-maven-x.x.x-bin.zip文件 2 ).配置M ...

  10. jquery 给input text元素赋值,js修改表单的值

    简单粗暴: (第一种) $('#checkUserName').attr("value",sessionUser.name); (第二种) $("#checkUserNa ...