异步 map 和模块打包
概述
本文是我在查资料的时候学到的一些东西,记录下来,供以后开发时参考,相信对其他人也有用。
参考资料:
异步函数 - 提高 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 的函数来看待。 也就是说:它不会等到第一个函数执行完毕就会调用第二个函数。
虽然上面的例子初看很惊艳,但是我没有找到实际的应用场景。。。
前端模块化
前端模块化发展这么久了,目前比较流行的模块化方案主要有下面三种:
- umd 模块(通用模块)
- CommonJs 模块(node模块)
- 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 和模块打包的更多相关文章
- js模块化/js模块加载器/js模块打包器
之前对这几个概念一直记得很模糊,也无法用自己的语言表达出来,今天看了大神的文章,尝试根据自己的理解总结一下,算是一篇读后感. 大神的文章:http://www.css88.com/archives/7 ...
- 一份关于webpack2和模块打包的新手指南(二)
插件 我们已经看到一个内置的webpack插件的例子,在npm run build脚本中调用的webpack -p命令就是使用webpack附带的UglifyJsPlugin插件以生产模式压缩打包文件 ...
- 多模块打包后,扫描不到@controller和@service,实现 ADD DIRECTORY ENTRIES
多模块打包后,扫描不到@controller和@service等Bean. 原因:打包时没有生成目录信息 解决办法: 1.在eclipse或者myeclipse 打包时 勾选 ADD DIRECTOR ...
- Webpack - CommonJs & AMD 模块打包器
Webpack 是一个 CommonJs & AMD 模块打包器.可以把你的 JavaScript 代码分离为多个包,在需要的时候进行加载,支持预处理文件,例如 json, jade, cof ...
- Maven之多模块打包成一个jar包及assembly
一.多模块打包 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- 一份关于webpack2和模块打包的新手指南
webpack已成为现代Web开发中最重要的工具之一.它是一个用于JavaScript的模块打包工具,但是它也可以转换所有的前端资源,例如HTML和CSS,甚至是图片.它可以让你更好地控制应用程序所产 ...
- 【spring cloud】【IDEA】【Maven】spring cloud多模块打包,打包的jar包只有几k,jar包无法运行,运行报错:no main manifest attribute, in /ms-eureka.jar
======================================================================================== 引申:maven打包多 ...
- Zepto自定义模块打包构建
文章转自 http://www.chengxuyuans.com/web_technology/zeptojs-build.html zepto.js 是个好东西,遵循 jQuery API,但比 j ...
- python模块打包方法
http://www.jb51.net/article/92789.htm 一 首先将模块的目录结构整理如下: VASPy/ ├── LICENSE ├── MANIFEST ├── MANIFEST ...
随机推荐
- 关于css中touch-action属性 在移动端开发中遇到的问题
初次接触第一次接触touch-action这个属性 是在之前一个网约车公众号项目中遇到的 当时采用的是vue做框架 cube-ui做组件库 当时在版本迭代的时候增加了余额支付的功能 需要一个密码键盘 ...
- Android 组件化之路 资源冲突问题
比如我现在有3个模块:app模块,user模块,me模块,其中app模块依赖user模块和me模块. 然后我在user模块和me模块的strings.xml中都定义了greet字符串: // user ...
- Git生成公钥.pub 及秘钥 命令
Git生成公钥.pub 及秘钥 命令 ssh-keygen -t rsa -C "******@qq.com" 将.pub公钥里面内容复制到github或者将这文件交给git管理员 ...
- python之堆排序算法代码
以下是个人写的堆排序代码,原理我就不解释了(简单来说就是先建立一个大顶堆,然后进行顶点和最后节点的互换,互换之后需要重新建堆,两两比对,具体的话可以参照其他的,不过代码还是会于注释的. #根据问题进行 ...
- python-文件的修改
python-文件的修改 修改文件的方法 第一种方法: 第二种方法: f=open("my-heart","r") f_new=open("my-he ...
- ceph对接openstack
一.使用rbd方式提供存储如下数据: (1)image(glance):保存glanc中的image: (2)volume(cinder)存储:保存cinder的volume:保存创建虚拟机时选择创建 ...
- 第一节,搭建openwrt开发环境
一,安装VMware虚拟机或者VirtualBox虚拟机 安装过程就不在此赘述了.附上百度搜索来的链接,供大家参考. https://baijiahao.baidu.com/s?id=16233731 ...
- scp 自动带密码参数复制文件到主机
一.安装sshpass工具 [root@zabbix_server scripts]# yum install sshpass 二.运行 [root@zabbix_server scripts]# s ...
- YARN组件详细介绍
一.ResourceManager 内部主要有两个组件: 1.Scheduler:这个组件完全是插拔式的,用户可以根据自己的需求实现不同的调度器,目前YARN提供了FIFO.容量以及公平调度器.这个组 ...
- python socket使用
自学python,先在菜鸟教程网自学,然后买了本书看.又从同事那里淘到了某个培训学校python教学视频,查缺补漏.视频是用python3.0讲的,讲解的很不错,中间有让写作业,这个我很喜欢.这几天看 ...