Tree Shaking 与 package.json 文件中的 module 字段

本文来和大家聊聊 pkg.module 字段的功能以及使用场景。 在谈 pkg.module 之前,让我们先来了解一个和它有着紧密关系的概念 —— Tree Shaking。 什么是 Tree Shaking? 让我们通过两个小例子来了解。 假设我们有以下两个文件:

app.js 文件通过 import 引入了 math.js 中的 add1 方法。 我们通过 webpack 命令打包:

在生成的 app.bundle.js 文件中我们可以看到以下内容: 这里我们可以看到虽然我们只用到了 math.js 文件中的 add1 方法,但是在最终生成的 bundle 文件中却包含了 add1 和 add2 两个方法。这是为什么呢? 这是因为在 CommonJS 规范(math.js 文件的模块格式即为 CommonJS)中,模块只能通过 exports 对象向外暴露属性。所有要暴露的方法、变量等都只能作为 exports 对象的一个属性出现。 由于在 JavaScript 中访问对象的属性是在是太灵活了,例如: 所以打包工具并不知道我们代码中最终会用到模块中的哪些方法。为了安全起见,整个模块的代码都被包含在了最终生成的 […]

JavaScript Promise

[译] 什么是Promise.try,它为何重要?

原文地址 http://cryto.net/~joepie91/blog/2016/05/11/what-is-promise-try-and-why-does-it-matter/ 在#Node.js#频道里经常困扰大家的一个话题是Bluebird提供的Promise.try方法。大家并不清楚该方法的功能也不知道为何要使用它。同时,几乎所有的关于Promsie的指南中针对该方法错误的演示使得这种情况没有任何改善。 在本文中,我会尝试解释究竟什么是Promise.try以及为何你应该使用它。我假设你已经对Promise有所了解并且知道.then在Promise中的作用。 即使你在使用一个不同的Promsie实现(例如ES6 Promise),本文还是可以帮到你。文章末尾我会解释如何在非Bluebird环境中实现相同的功能。 究竟什么是Promise.try呢? 简单来说,除了不需要跟在一个前置Promise之后以外,Promise.try很像.then。这么说还是有一些含糊不清,所以让我们先看一个示例。 以下是一段典型的Promise使用场景:

到目前为止,一切顺利。我们假设database.users.get会返回一个Promise,并且该Promise最终会返回一个带有name属性的对象。 以下是同样的代码,但是引入了Promise.try:

可以看到,我们的调用链以Promise.try而不是database.users.get开始。像使用.then一样,我们执行Promise.try方法并传递给它一个直接返回database.users.get调用的函数。 这样做有什么意义呢? 以上的代码看起来似乎是多余的。但实际上它有以下几个优点: 更好的错误处理 同步代码中的异常不论出现在何处都会以rejection的形式向Promise链后端传递。 更好的兼容性 你可以始终使用你自己喜欢的Promise实现,而不用担心第三方代码在使用哪个。 更好的代码阅读体验 所有的代码在水平方向上将处于同一个缩进层级,这将使你阅读代码变得更容易。 接下来我会逐一介绍这些优点: 1. 更好的错误处理 Promise的一个被大力宣扬的优点就是用户可以用同一种方式同时处理同步异常和异步异常 —— 同步异常会被捕获并且会作为一个rejected Promise向后传递。但事实真的是这样吗?让我们看看以下这个上文示例的小变种:

在这个改动后的版本中,我们在输入user.name的时候手误,现在它成了uesr.name。由于uesr是未定义的,所以它不可能有任何属性,因此该行代码会产生异常。接着就如你期望的一样,这个异常会被.then捕获并被转变成一个rejected Promise。 但是如果database.users.get同步的抛出了异常呢?如果在第三方的代码里存在拼写错误或是其他问题呢?Promises的错误捕获机制的前提是使用者编写的所有同步代码都要放在.then中,这样它就可以将这些同步代码放入一个try/catch块中执行。 但是…我们代码中的database.users.get并不在.then块中。因此Promise就不能访问这部分代码也就不能将它们包裹在try/catch中。这就导致同步异常不能被转变为异步异常。我们又回到了原点,不得不处理两种形式的异常 —— 同步的和异步的。 现在,让我们回过头来看看使用了Promise.try的示例:

我前边说过Promise.try很像.then,但是它不需要跟在Promise后边。除此之外,它还会捕获database.users.get中的同步异常,就像.then一样! 通过引入Promise.try,我们已经把代码的错误处理改造为可以覆盖所有的同步异常,而不是只能捕获第一次异步操作(第一次.then调用)之后的异常了。 补充信息: Promises/A+ 在我们继续讨论Promise.try的下一个优点之前,让我们看看什么是Promises/A+以及它扮演的角色。Promises/A+网站上对它的介绍是: An open standard for sound, interoperable JavaScript promises—by implementers, for implementers. 换种说法,它是一份可以保证不同的Promises实现(Bluebird,ES6,Q,RSVP, […]

© 2018 JDC. All Rights Reserved.