All Posts

是时候升级一下你的 nvm-windows 了

是时候升级一下你的 nvm-windows 了

一直以来都使用 nvm-windows 来管理 Node 版本。从没出过问题。今天团队小伙伴来反馈我们的一个内部命令行工具在 Node 6.10.0 上无法安装。于是决定安装一个 6.10.0 调查一下。 于是执行: nvm install v6.10.0 结果输出: $ nvm install v6.10.0 Node.js vv6.10.0 is not yet released or available. 似乎是哪里不对了。 于是下意识的 nvm ls available 一下看看: $ nvm ls available Showing the 15 latest available releases. STABLE | UNSTABLE --------------------------- v8.9.1 | v8.7.0 v8.9.0 | v7.9.0 v8.8.1 | v7.7.4 v8.8.0 | v7.7.3 v7.10.1 | v7.7.2 v7.10.0 | v7.7.1 v7.8.0 | v7.7.0 v6.12.0 | v6.

为 React 编写单元测试之一 —— 测试框架的选择

为 React 编写单元测试之一 —— 测试框架的选择

最近和小伙伴们在尝试做把项目中经常用到的 React 组件整理成一套 React 组件库。为了保证代码质量且方便日后维护,我们决定为组件编写单元测试。接下来几篇文章会聊聊在这个过程中我们遇到的问题以及一些思考。 正文开始 要写单元测试,首先面临的一个问题就是“我该使用哪个测试框架”? 如果你去 Google 上搜索“how to test react component”,在结果页面中你大概会来来回回看到以下几个名词/概念: Jest Enzyme Mocha全家桶(套餐内容大概率是:Mocha + Chai + Sinon + Istanbul) react-test-renderer react-dom/test-utils 首先让我们来看看这些库的功能和定位,然后再来做选择。 🃏 Jest Jest 是 Facebook 开发的一款 JavaScript 测试框架。在 Facebook 内部广泛用来测试各种 JavaScript 代码。其官网上主要列出了以下几个特点: 轻松上手 使用 create-react-app 或是 react-native init 创建的项目已经默认集成了 Jest 现有项目,只需创建一个名为 __test__ 的目录,然后在该目录中创建以 .spec.js 或 .test.js 结尾的文件即可 内置强大的断言与 mock 功能 内置测试覆盖率统计功能 内置 Snapshot 机制 虽然 Jest 官网介绍中多次 React,但实际上 Jest 并不是和 React 绑定的。你可以使用它测试任何 JavaScript 项目。

为 GitLab 代码库配置 Specific Runner

为 GitLab 代码库配置 Specific Runner

最近要为团队内一个项目搭建持续集成。项目代码托管在公司内部的 GitLab 上,于是很自然的选择使用 GitLab 自带的 CI/CD 功能。 在 GitLab 的 CI/CD 流程中具体执行任务的节点叫做 runner。GitLab 中有两种类型的 runner: Shared Runners 由 GitLab 管理员配置的公有 runner。多个项目公用。作为开发人员无需配置,可以直接使用。 Specific Runners 开发人员为每个代码库单独配置的专属 runner。只能执行所属代码库的任务。需要开发人员手动搭建。 由于我厂的 GitLab 并没有配置任何 Shared Runner。所以只能选择在自己的台式机上手动搭建。 具体流程如下: Step 1 下载 runner 可执行文件 根据你的环境下载 x86 或者 amd64 版本。 创建 D:\GitLab-Runner 目录,将刚刚下载好的文件复制到该目录并重命名为 gitlab-runner.exe。 Step 2 以管理员身份运行 Git Bash Step 3 访问代码库的配置页获取配置信息 进入代码库主页,依次点击 Settings => CI / CD => Runners settings。 这里展开的信息中有两个字段需要我们记下来。分别是一个 URL 和一个 Token。 Step 4 注册 runner 进入 D:\GitLab-Runner 目录执行命令:

React 全新的 Context API

React 全新的 Context API

Context API 可以说是 React 中最有趣的一个特性了。一方面很多流行的框架(例如react-redux、mobx-react、react-router等)都在使用它;另一方面官方文档中却不推荐我们使用它。在 Context API 的文档中有下面这段话: The vast majority of applications do not need to use context. If you want your application to be stable, don’t use context. It is an experimental API and it is likely to break in future releases of React. 为何会出现这种情况呢?这还得让我们从现有版本 Context API 要解决的问题已经它自身的缺陷说起。 现有版本 Context API 的使用场景以及缺陷 我们都知道在 React 中父子组件可以通过 props 自顶向下的传递数据。但是当组件深度嵌套时,从顶层组件向最内层组件传递数据就不那么方便了。手动在每一层组件上逐级传递 prop 不仅书写起来很繁琐同时还会为夹在中间的组件引入不必要的 prop。这时 Context API 就派上用场了。你只需要在外层组件上声明要传递给子组件的 Context:

聊聊 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 两个方法。这是为什么呢?

2017年8月每日一文节目回看

从上个月底开始坚持每天为组内的小伙伴推荐一篇技术文章。内容涵盖各种前端话题,比如 React, Node.js, ES6, React Native, 职业生涯等等。一来可以开阔小伙伴们的视野,二来可以锻炼小伙伴们的英文阅读能力。 从这个月开始,每月最后一天会把当月推荐过的文章列表归档出来。大家可以选择自己感兴趣的话题阅读啦。 20170831 Keep Your Bundle Size Under Control 20170830 Understand async/await better 20170828 How to get the most out of the JavaScript console 20170824 ASYNC/AWAIT WILL MAKE YOUR CODE SIMPLER 20170823 Error handling Promises in JavaScript 20170822 Singletons versus Dependency Injection 20170821 Working with Environment Variables in Node.js 20170818 Rx.js: Operators, Part I 20170817 How to use Memoize to cache JavaScript function results and speed up your code 20170816 Building A Simple AI Chatbot With Web Speech API And Node.

在项目中启用 ESLint 与 Stylelint 检查

多人参与的项目中,经常会多人交叉编辑多个文件。这就导致了各个文件中充斥着各种编码风格。 最最常见的就有: 使用空格还是Tab 一次缩进是 2 个空格还是 4 个空格 还是 8 个空格 字符串使用单引号还是双引号 JavaScript 一行结尾到底要不要加分号 关键字前后要不要加空格 等等等等 不同风格混杂在一起极大的影响代码的可读性与质量。因此在多人项目中维护一致的代码风格就很重要了。 本文就简单介绍一下如何通过 ESLint 和 Stylelint 为代码库配置针对 JavaScript 与 CSS(SCSS)的代码风格检查。 配置 ESLint 安装 eslint yarn add --dev eslint // or npm install --save-dev eslint 创建配置文件 ./node_modules/.bin/eslint --init 该命令会在项目目录中创建一个 .eslintrc.json 文件。默认生成的配置文件可能看起来是这个样子: { "rules": { "semi": ["error", "always"], "quotes": ["error", "double"] } } rules 里定义的就是你想要检查的规则了。例如上边示例中就配置了分号和引号的使用。 完整的配置文档可以在这里找到。 配置 npm script 配置好以后就可以通过命令

Service Worker 基础知识

本文旨在帮你快速了解 service worker 的基本知识点,让你对 service worker 有一个大致的了解。为以后开发一个简单的 PWA 应用打下基础。 关于 service worker 的几个基本知识点 它是一个可编程的网络代理,让你可以控制页面请求的处理方式。 它是一个 JavaScript Worker,因此它无法直接操作 DOM。但可以通过 postMessage 接口与页面通信。同时,service worker 中的代码不会阻塞页面响应。 它在闲置时被终止,在需要时被启动。并不是常驻内存。因此你不能在 onfetch 或是 onmessage 回调中依赖全局状态。 被设计成完全异步。因此在 service worker 中无法使用同步 API (例如同步 XHR,localStorage等)。接口重度依赖于 promise。 只能在 HTTPS 页面加载(唯一的例外:localhost/127.0.0.1,方便调试)。 Service worker 的作用域 一个 service worker 的默认作用域是这个 service worker 脚本所在的目录。例如 https://example.com/sw.js 脚本默认就是 https://example.com 下的所有页面。 你也可以在注册 service worker 时明确指定作用域: navigator.serviceWorker.register('sw.js', { scope: './abc' }); 假设以上代码在 https://example.com 页面里执行,则意味着该 service worker 的作用域就是 https://example.

[译] 在大型应用中使用 Redux 的五个技巧

Redux 是一个很棒的用于管理应用程序“状态”的工具。单向数据流以及对不可变数据的关注使得推断状态的变化变得很简单。每次状态变化都由一个 action 触发,这会导致 reducer 函数返回一个变更后的新状态。由于客户要在我们的平台上管理或发布广告资源,在 AppNexus 使用 Redux 创建的很多用户界面都需要处理大量数据以及非常复杂的交互。在开发这些界面的过程中,我们发现了一些有用的规则和技巧以维持 Redux 易于管理。以下的几点讨论应该可以帮助到任何在大型,数据密集型应用中使用 Redux 的开发者: 第一点: 在存储和访问状态时使用索引和选择器 第二点: 把数据对象,对数据对象的修改以及其它 UI 状态区分开 第三点: 在单页应用的不同页面间共享数据,以及何时不该这么做 第四点: 在状态中的不同节点复用通用的 reducer 函数 第五点: 连接 React 组件与 Redux 状态的最佳实践 1. 使用索引保存数据,使用选择器读取数据 选择正确的数据结构可以对程序的结构和性能产生很大影响。存储来自 API 的可序列化数据可以极大的受益于索引的使用。索引是指一个 JavaScript 对象,其键是我们要存储的数据对象的 id,其值则是这些数据对象自身。这种模式和使用 hashmap 存储数据非常类似,在查询效率方面也有相同的优势。这一点对于精通 Redux 的人来说不足为奇。实际上,Redux 的作者 Dan Abramov 在它的 Redux 教程中就推荐了这种数据结构。 设想你有一组从 REST API 获取的数据对象,例如来自 /users 服务的数据。假设我们决定直接将这个普通数组存储在状态中,就像在响应中那样。当我们需要获取一个特定用户对象时会怎样呢?我们需要遍历状态中的所有用户。如果用户很多,这可能会是一个代价高昂的操作。如果我们想跟踪用户的一小部分,例如选中和未选中的用户呢?我们要么需要把数据保存在两个数组中,要么就要跟踪这些选中和未选中用户在主数组中的索引(译者注:此处指的是普通意义上的数组索引)。 然而,我们决定重构代码改用索引的方式存储数据。我们可以在 reducer 中以如下的方式存储数据: { "usersById": { 123: { id: 123, name: "Jane Doe", email: "jdoe@example.

Chrome 开发者工具中的命令菜单

大家对命令菜单(Command Menu)应该都不陌生。目前主流的编辑器中都内置了对该功能的支持。在 Sublime Text 和 Visual Studio Code 中你都可以通过快捷键 Ctrl + Shift + P 呼出命令菜单(在 Mac 上是 Cmd + Shift + P)。 在呼出的菜单中输入关键字选择自己需要的命令(支持模糊搜索哦),按回车即可执行命令。极大的提高了效率。 举个例子,以下的操作是为文件设置 JavaScript 的语法高亮: 很方便吧。 如果你已经习惯了这种操作方式,那么今天要告诉你一个好消息。Chrome 开发者工具现在也支持命令菜单了!激活的方式还是 Ctrl + Shift + P。 激活后,长这个样子: 熟悉的配方,熟悉的味道。有木有! 滚动菜单,查看支持的命令,基本涵盖了我们日常开发用到的所有功能。 举几个实用的小例子吧(这些例子不同命令菜单一样可以实现,但命令菜单可以极大的提高效率)。 1. 搜索所有资源文件 激活命令菜单,输入 search,选择 Search all files,回车。在弹出的输入框中输入关键字就可以在所有页面引入的资源文件中搜索该关键字了。还支持正则表达式哦。 2. 禁用/开启页面 JavaScript 激活命令菜单,输入 js,选择 Disable JavaScript。再次选择,即可开启。 3. 隐藏 HTML 中的注释 激活命令菜单,输入 comment,选择 Hide HTML Comments。 更多快捷功能,自己去发现吧!