Posts List

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

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

本文来和大家聊聊 pkg.module 字段的功能以及使用场景。 在谈 pkg.module 之前,让我们先来了解一个和它有着紧密关系的概念 —— Tree Shaking。 什么是 Tree Shaking? 让我们通过两个小例子来了解。 假设我们有以下两个文件: // math.js exports.add1 = function (x) { return x + 1; } exports.add2 = function (x) { return x + 2; } // app.js import { add1 } from './math'; add1(100); app.js 文件通过 import 引入了 math.js 中的 add1 方法。 我们通过 webpack 命令打包: webpack --entry ./app.js --output-filename app.bunble.js 在生成的 app.bundle.js 文件中我们可以看到以下内容: 这里我们可以看到虽然我们只用到了 math.js 文件中的 add1 方法,但是在最终生成的 bundle 文件中却包含了 add1 和 add2 两个方法。这是为什么呢?

[译] 6个Async/Await完胜Promise的原因

原文地址:https://hackernoon.com/6-reasons-why-javascripts-async-await-blows-promises-away-tutorial-c7ec10518dd9 友情提醒:NodeJS自从7.6版开始已经内置了对async/await的支持。如果你还没用过该特性,那么接下来我会给出一系列的原因解释为何你应该立即开始使用它并且会结合示例代码说明。 async/await快速入门 为了让还没听说过这个特性的小伙伴们有一个大致了解,以下是一些关于该特性的简要介绍: async/await是一种编写异步代码的新方法。在这之前编写异步代码使用的是回调函数和promise。 async/await实际是建立在promise之上的。因此你不能把它和回调函数搭配使用。 async/await和promise一样,是非阻塞的。 async/await可以使异步代码在形式上更接近于同步代码。这就是它最大的价值。 语法 假设有一个getJSON方法,它返回一个promise,该promise会被resolve为一个JSON对象。我们想要调用该方法,输出得到的JSON对象,最后返回"done"。 以下是使用promise的实现方式: const makeRequest = () => getJSON() .then(data => { console.log(data) return "done" }) makeRequest() 使用async/await则是这样的: const makeRequest = async () => { console.log(await getJSON()) return "done" } makeRequest() 使用async/await时有以下几个区别: 在定义函数时我们使用了async关键字。await关键字只能在使用async定义的函数的内部使用。所有async函数都会返回一个promise,该promise最终resolve的值就是你在函数中return的内容。 由于第一点中的原因,你不能在顶级作用域中await一个函数。因为顶级作用域不是一个async方法。 // this will not work in top level // await makeRequest() // this will work makeRequest().then((result) => { // do something }) await getJSON()意味着直到getJSON()返回的promise在resolve之后,console.

[译]什么是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使用场景: function getUsername(userId) { return database.users.get({id: userId}) .then(function(user) { return user.name; }); } 到目前为止,一切顺利。我们假设database.users.get会返回一个Promise,并且该Promise最终会返回一个带有name属性的对象。 以下是同样的代码,但是引入了Promise.try: var Promise = require("bluebird"); function getUsername(userId) { return Promise.try(function() { return database.users.get({id: userID}); }).then(function(user) { return user.name; }); } 可以看到,我们的调用链以Promise.try而不是database.users.get开始。像使用.then一样,我们执行Promise.try方法并传递给它一个直接返回database.users.get调用的函数。 这样做有什么意义呢? 以上的代码看起来似乎是多余的。但实际上它有以下几个优点: 更好的错误处理 同步代码中的异常不论出现在何处都会以rejection的形式向Promise链后端传递。 更好的兼容性 你可以始终使用你自己喜欢的Promise实现,而不用担心第三方代码在使用哪个。 更好的代码阅读体验 所有的代码在水平方向上将处于同一个缩进层级,这将使你阅读代码变得更容易。 接下来我会逐一介绍这些优点: 1. 更好的错误处理 Promise的一个被大力宣扬的优点就是用户可以用同一种方式同时处理同步异常和异步异常 —— 同步异常会被捕获并且会作为一个rejected Promise向后传递。但事实真的是这样吗?让我们看看以下这个上文示例的小变种: function getUsername(userId) { return database.users.get({id: userId}) .then(function(user) { return uesr.

在JDF项目中使用ES6新特性

Note: 目前虽然JDF已经支持使用ES6开发脚本,但线上使用还在前期摸索阶段,请大家根据自己项目实际情况评估使用情况 最近利用业余时间给JDF增加了ES6代码的支持。背后的原理是在项目构建阶段利用Babel将.babel文件转译成ES5代码。关于Babel的更多使用方法可以参考其官网的配置文档。 下面开始正式介绍在利用ES6特性开发前的准备工作: - 升级JDF到最新版本(>= 1.8.2) - 进入JDF项目目录,安装基本的Babel preset和plugin。关于preset和plugin的更多说明请参考文档 npm install babel-preset-es2015 npm install babel-plugin-transform-es3-member-expression-literals npm install babel-plugin-transform-es3-property-literals 配置项目的.gitignore文件,忽略node_modules目录。在文件中添加以下内容: **/node_modules/ 引入es6-base.js(包含 es5-shim和babel-polyfill) 至此,所有的准备工作就完成了。接下来就可以利用ES6的各种新特性开发了。需要注意的是所有包含了ES6特性的脚本文件扩展名必须是.babel,否则JDF是不会对其进行编译的。 最后是一份简单的FAQ: Q: ES6都有哪些新特性,有没有推荐的学习资料? 当然有,中文版的有阮一峰出品的ECMAScript 6入门。 英文的有: - ES6 In Depth来自Mozilla团队博客的一系列文章,每篇讲解一个新特性。建议按时间顺序阅读。 - Understanding ECMAScript 6来自Nicholas C. Zakas大神的一本ES6小书。 Q: 我想使用额外的Babel plugin或preset该怎样配置? 只需在package.json中指定需要额外引入的plugin或preset,例如: "babel": { "plugins": ["syntax-async-functions","transform-regenerator"], "presets": ["stage-0"] } 并在JDF项目的目录中安装相关npm package即可。 Q: .babel文件编译出来的代码我看不懂,出了问题如何调试呢? 我们看到的经过Babel转译后的JS是这样的: 这里包含了大量的Babel生成的代码,非常不利于调试。不过不用担心,JDF在本地开发模式中启用了sourceMap,你只需在Chrome开发者工具中的Sources Tab中在你要调试的JS文件目录下找到同名的.babel文件即可。相关JS中的报错信息,都会被映射到转译前的.babel文件的对应位置。 关于sourceMap的更多信息请参考这里。