ReasonML——新的前端强类型语言简介

1011次阅读  |  发布于4年以前

背景介绍

从有前端到现在,JavaScript 语言一直都是实现前端逻辑的首选。但是,由于 JavaScript 是一个弱类型语言,很难进行相关的类型检测。因此在构建大型应用时,使用 JavaScript 难免会遇到一些隐式类型转换等相关的问题,从而导致程序的 bug。

在当前的选择中,有两个流派,都能够解决 JavaScript 弱类型语言带来的弊病,给前端带来强类型语言的支持。

作为最近被大家关注的越来越多的强类型语言,ReasonML 的发展也是需要我们持续关注的。

ReasonML 起源

说了这么多背景,我们来正式介绍下 ReasonML 这门语言。首先,让我们来看下[官网][1]对于 ReasonML 的介绍。

Reason lets you write simple, fast and quality type safe code while leveraging both the JavaScript & OCaml ecosystems.
Reason利用 JavaScript 和 OCaml 语言的生态,让你编写简单、快速和高质量类型安全的代码。

从这个介绍中我们可以知道, ReasonML 是从 OCaml 语言衍生出来的,可以支持 JavaScript 的新的强类型语言。首页介绍中,还提到了这个语言的三个特点:

ReasonML 入门介绍

听了这么多关于 ReasonML 的介绍,我们来简单的看下相关的语法。通过相关的语法和示例,我们能够帮助我们更好的理解这门语言。

我们就使用官方的一些简单的示例来快速入门这个语言。

安装与编译

因为目前浏览器无法直接识别强类型语言,因此我们需要通过编译器,将强类型语言编译成 JavaScript 以后才能够在前端浏览器或者 Node.js 中运行。

首先,我们来看下如何进行安装:

npm install -g bs-platform

首先,我们通过 NPM 来对编译平台 bs-platform 进行全局安装,安装完成后,我们就可以使用这个 cli 自带的命令了。

安装完成后,我们需要初始化一个项目,因此我们需要执行以下命令:

bsb -init my-new-project -theme basic-reason

通过这个命令,我们就创建了一个名字为 my-new-project 的项目文件了。

这个时候,我们进入这个项目文件夹中,看看这里面到底初始化了哪些东西。首先我们来看下 package.json 文件。

{
  "name": "my-new-project",
  "version": "0.1.0",
  "scripts": {
    "build": "bsb -make-world",
    "start": "bsb -make-world -w",
    "clean": "bsb -clean-world"
  },
  "keywords": [
    "BuckleScript"
  ],
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "bs-platform": "^4.0.18"
  }
}

接下来,我们先来看下 src/Demo.re 文件的内容。

Js.log("Hello, BuckleScript and Reason!");

我们需要重点关注的就是,我们可以通过 npm run build 命令来编译整个项目,它会将 src/Demo.re 编译成 src/Demo.re.js 文件。让我们来看下编译出来的内容是什么样子的。

// Generated by BUCKLESCRIPT VERSION 4.0.18, PLEASE EDIT WITH CARE
'use strict';

console.log("Hello, BuckleScript and Reason!");

/*  Not a pure module */

大家可以看到,我们通过 ReasonML 的编译器,将 ReasonML 的代码编译成了 JavaScript。

语法介绍

说完了构建编译相关的流程,我们来正式看下 ReasonML 这门语言的语法。

ReasonML 的类型系统可以自动进行类型推断,在本文介绍中我会尽可能详细的进行介绍,但是如果没有声明具体类型,大家可以自主进行推断。

我们可以通过下面这个表格来快速看下当前的数据结构:

数据类型 示例
字符串 "Hello"
字符 'x'
整型数字 23, -23
浮点型数字 23.0, -23.0
整型数字加法 23 + 1
浮点型数字加法 23.0 +. 1.0
整型数字除法/乘法 2 / 23 * 1
浮点型数字除法/乘法 2.0 /. 23.0 *. 1.0
浮点型数字求幂 2.0 ** 2.0
字符串组合 "Hello " ++ "World"
比较运算符 >, <, >=, =<
布尔运算符 !, &&, ||
引用(浅)比较,结构(深)比较 ===, ==
不可变列表 [1, 2, 3]
不可变前置声明(Immutable Prepend) [item1, item2, ...theRest]
元组(Tuple) [1, "string"]
数组 [|1, 2, 3|]
记录(Records) type player = {score: int}; {score: 100}
对象 type tesla = {var red = "red"; pub color = red;}; tesla#color
注释 /* Comment here */

这里面有一些内容需要详细介绍下差别。

关于语法相关的内容,我只是简单介绍了一下核心的数据结构,有很多内容没有介绍到,如果大家想要系统的学习 ReasonML 的话,可以看一下官方文档

与 JavaScript 兼容方式

如果我们需要在 ReasonML 中使用 JavaScript 代码,我们可以按照如下的方法:

[%bs.raw {| console.log('here is some javascript for you') |}];

上面的代码经过编译后,可以得到如下的 JavaScript 代码。

'use strict';
console.log('here is some javascript for you');

这个方法与全局注入变量的方式类似,会直接将上述代码替换成编译后的 JavaScript 代码。因此我们可以这么用:

let x = [%bs.raw {| 'here is a string from javascript' |}];

得到的代码为:

var x = ( 'here is a string from javascript' );

与 JavaScript 语法差异

许多的语法差异我们在上述语法介绍中都已经介绍过了,如果需要详细的比对,可以看官方文档中的语法比较

总结

ReasonML 是一门比 TypeScript 约束严格的多的强类型语言(TypeScript 编译报错可以选择忽略掉,不影响使用)。强类型语言对于大型的项目开发来说,确实可以带来明显的优势。但是,我们能不能够大规模使用 ReasonML 呢?

先说下个人的基本判断:持续关注,不建议在大型应用场景中使用。

从 ReasonML 目前的情况来看,它与 TypeScript 非常相似。

TypeScript 由于对 JavaScript 的生态完全兼容,所以即使我们需要进行部分代码的重写,我们仍然可以快速的复用 JavaScript 的强大生态。

而由于 ReasonML 来说,这个方面就会明显相差不少。与此同时,ReasonML 的相关语法与 JavaScript 相差较大,因此对于前端工程师的学习成本来说,也有一定的提提升。

综上所述,如果大家需要在前端使用强类型语言来构建大型项目,建议选择 TypeScript 语言。

如果在迁移 TypeScript 中有什么问题,可以看下我之前写的一篇文章——旧项目 TypeScript 改造问题与解决方案记

作者介绍与转载声明

黄珏,2015年毕业于华中科技大学,目前任职于美团基础研发平台大象业务部,独立负责大象 Web SDK 的开发与维护。

本文未经作者允许,禁止转载。

Copyright© 2013-2019

京ICP备2023019179号-2