——是百家争鸣,仍是五代十国纷争前端
去年看到一篇文章 是写前端更新迭代的新技术,今天无心间又看到原创人翻译过来的文章啦 。这里贴下来 给你们灌一碗毒鸡汤ios
嘿,我最近接到一个 Web 项目,不过老实说,我这两年没怎么接触 Web 编程,据说 Web 技术已经发生了一些变化。据说你是这里对新技术最了解的 Web 开发工程师?ajax
准确地说,我是一名「前端工程师」。不过你算是找对人了。我对今年的技术别提多熟了,前端可视化、音乐播放器、能踢足球的无人机,你尽管问吧。我刚去 JS 大会和 React 大会逛了一圈,没有什么新技术是我不知道的。
厉害。是这样的,我要开发一个网页,用来展现用户的最新动态。我想我应该经过后端接口获取数据,而后用一个 table 来展现数据,用户能够对数据进行排序。若是服务器上的数据变化了,我还须要更新这个 table。个人思路是用 jQuery 来作。数据库
可别用 jQuery!如今哪还有人用 jQuery。如今是 2016 年了,你绝对应该用 React。
哦,好吧,React 是什么?npm
React 是一个很是厉害的库,Facebook 的牛人写的。它能让页面更可控,性能极高,并且使用起来很简单。
听起来确实不错。我能用 React 展现服务器传来的数据吗?编程
固然能够,你只须要添加两个依赖,一个是 React,一个是 React DOM
额,等下,为何是两个库?后端
React 是我说的库,React DOM 是用来操做 DOM 的。由于这些 DOM 是用 JSX 写的,因此须要一个专门的库来操做。
JSX?JSX 是什么?浏览器
JSX 是对 JS 的扩展,它看起来跟 XML 差很少,能够用来写 HTML,你能够认为 JSX 是一种更优雅的 HTML 写法。
为何不用 HTML 了……?服务器
如今但是 2016 年啊,没有直接写 HTML 的。
对哦。好吧,加了这两个依赖,是否是就能够开始用 React 了?babel
不行哦。你须要添加 Babel,而后才能用 React。
Babel 是另外一个库?
嗯,Babel 是一个转译工具,Babel 能把你写的 JS 转译成任意版本的 JS。你不必定非要用 Babel,可是若是你不用的话,你就只能写 ES5 的语法了。你知道的,如今是 2016 年,你怎么能不使用 ES2016+ 的语法呢?ES2016+ 多么酷啊。
ES5 是啥?ES2016+ 又是啥?我有点晕。
ES5 就是 ECMAScript 5。大部分人都会使用 ES5,由于大部分浏览器都支持 ES5。
ECMAScript 是啥……
你晓得的,JS是1995年诞生的,而JS的标准是1999制定出来的。那时候 JavaScript 还叫作 Livescript,只能运行在网景的浏览器里。那时真是混乱的年代,如今好了,咱们有了 JS 的 7 个版本的规范。
7 个版本?那 ES5 和 ES2016+ 是?
分别是第 5 个版本和第 7 个版本。
诶,那第六个版本呢?
你说的是 ES6。每一个版本都是上一个版本的超集,因此你直接使用最新的 ES2016+ 就行了。
对哦。为何不用 ES6 呢?
好吧,你能够用 ES6,可是你就用不到 async 和 await 这么酷的语法了。用 ES2016+ 比较好。用 ES6 的话你就只能用 generator 来控制异步任务流了。
不知道你在说什么……你说了太多我听不懂的名词了。我只是想从服务器取点数据,我之前用 jQuery 挺好的,从 CDN 引入 jQuery,我就能用 AJAX 获取数据了,如今不能这样作吗?
大哥,都 2016 年了,没人用 jQuery 好吗。全部人都知道用 jQuery 只会造出「意大利面条」同样的代码(不可维护)
好吧,因此我如今要加载三个库才能获取并展现数据。
对的,其实你能够用「模块管理器」把这三个库「打包」成一个文件。
哦,什么是模块管理器……
不一样平台的模块管理器不一样啦。前端的模块管理器通常指管理 AMD 或者 CommonJS 模块的东西。
好……吧,什么是 AMD 和 CommonJS?
是两个定义。咱们有不少方式来描述 JS 中多个库或类的交互方式,好比 exports 和 requires。你能够按照 AMD 或者 CommonJS 的 API 来书写 JS,而后用 Browserify 将它们打包。
听起来颇有道理。不过,什么是 Browserify?
是一个工具,用来将 CommonJS 形式的 JS 文件打包起来,放到浏览器里运行。用 npm 仓库的人发明了 CommonJS。
npm 仓库是什么……
是一个公开的仓库,用于放置可依赖的模块。
就像一个 CDN 么?
不太同样。它更像是一个数据库,每一个人都能在上面发布代码,也能下载上面的代码。你能够在开发的时候将这些代码下载到本地来使用,必要的时候也能上传到 CDN。
听起来像是 Bower!
是的,不过如今是 2016 年了,没有人用 Bower 了……
好吧,我知道了,因此我应该用 npm 来安装依赖。
对的。我举个例子吧,若是你要使用 React,你直接用 npm 安装 React,而后在代码里导入 React 就能够了。大部分 JS 库都能这么安装。
嗯,Angular 也能够。
Angular 是 2015 年的事情了。不过今年 Angular 还没死,还有 VueJS 和 RxJS 等等,你想学一学么?
仍是用 React 吧。我刚才已经学了够多东西了。因此我用 npm 安装 React 而后用 Browerify 来打包就行了?
是的。
这么作看起来有点过于复杂啊。
确实。这就是为何你应该使用 Grunt、Gulp 或者 Broccoli 这样的任务管理工具,它们能自动运行 Browserify。不对,你如今能够用 Mimosa。
你在说什么……
任务管理工具。不过咱们如今已经不用了。去年咱们还在用,后来改为了 Makefiles,可是如今咱们用的都是 Webpack。
我觉得只有 C/C++ 项目才会用 Makefiles。
是的,不过显然咱们作 Web 开发的,喜欢先把事情搞复杂,而后回归到最朴素的状态。每一年咱们都是这么搞的。你就看着吧,过不了两年,咱们就能够在网页上写汇编了。
唉,你刚才说的 Webpack 是什么?
另外一种模块管理工具,同时也是一个任务管理工具。你能够认为它是 Browserify 的增强版。
哦,好吧,为何 Webpack 是增强版?
额,可能并无增强吧。Webpack 告诉你应该如何管理你的依赖,Webpack 容许你使用不一样的模块管理器,不仅是 CommonJS,甚至支持 ES6 模块。
这都是哪跟哪啊,我都被绕晕了。
你们都被绕晕了,不过等 SystemJS 出来了就行了。
天呐,又一个 JS 库,这是什么鬼?
呵呵,不像 Browserify 和 Webpack 1.x,SystemJS 是一个动态的模块加载器。
等下,刚才不是说应该把全部依赖打包成一个文件吗?
话是这么说,可是等 HTTP/2 普及以后,不打包反而更好。
那为何咱们不直接在页面里添加 React 的三个依赖文件呢?
不行。你能够从 CDN 加载这些文件,可是你仍是要在本地用 Babel 转译。
唉,这么鹾?
是的,你不能在生产环境上运行 babel,你应该在发布到生产环境以前,运行一系列的任务,包括压缩、混淆、内联化CSS、延迟加载script……
我懂了我懂了。既然我不能直接用 CDN,那么我应该怎么作?
我会考虑用 Webpack + SystemJS + Babel 来转译 Typescript。
Typescript?咱们不是在说 JavaScript 吗?!
Typescript 也是 JavaScript 呀,它比 JS 更好用,是 JS 的超集,它是基于 ES6 的,就是咱们刚才谈论的 ES6,你还记得吧。
ES2016+ 已是 ES6 的超集了,怎么又冒出来一个 Typescript?
是这样的,Typescript 能让咱们写出「强类型」的 JS,从而减小运行时的错误。2016年,咱们应该让 JS 支持强类型了。
显然 Typescript 能够作到。
Flow 也能够作到,区别是 Typescript 须要编译,而 Flow 只是检查语法。
唉,Flow 是?
是一个静态类型检查器,就是 Facebook 的人写的。使用 OCaml 写的,函数式编程很叼的。
OCaml?函数式编程?
现在大牛都用这些东西,都2016年了,你懂的,函数式编程、高阶函数、柯里化、纯函数这些概念。
不知道你在说什么。
一开始你们都不知道。这么说吧,你只须要知道函数式编程比面向对象编程厉害,2016 年咱们就指着函数式编程了。
等下,我大学里学过面向对象编程,当时我以为它还不错。
Java 在被 Oracle 买下来以前也挺不错啊。个人意思是,面向对象之前是不错,如今依然有人用它,可是如今全部人都发觉状态变换是很难维护的,因此你们都开始用「不可变对象」和函数式编程了。Haskell 的人已经用这套东西用了好久了,不过幸运的是 Web 开发领域里有 Ramda 这样的库,让咱们用 JS 就能够进行函数式编程了。
你刚刚是否是又抛出了几个名词?Ramnda 又是什么?
不是 Ramnda,是 Ramda,跟 Lambda 表达式有点像。是 David Chambers 写的库。
谁?
David Chambers,大神一个。blablabla
我不得不打断你一下了。这些东西看起来都不错,可是我以为它们都太复杂,并且不必。我只是想获取数据而后展现,我很肯定这种状况下我不须要掌握这些知识。
回到 React 吧,用 React 我怎么从服务器获取数据?
额,React 没有提供这个功能,你只能用 React 展现数据。
服了啊。那我怎么获取数据?
你用 Fetch API 就能够了。
啥玩意?这个 API 的名字很烂啊。
我也以为是啊。Fetch API 是浏览器提供的异步请求接口。
哦,那不就是 AJAX。
AJAX 只是使用 XMLHttpRequest 对象,可是 Fetch API 可让你用 Promise 风格来发起异步请求,帮你摆脱「回调地狱」。
回调地狱?
是的,每次你发起一个异步请求,就得等待它响应。这时你就得在函数里使用一个函数,这种嵌套调用就是回调地狱。
好吧。Promise 解决了这个问题么?
是的。用 Promise 来管理回调,你就能够写出更易读的代码,更容易测试的代码。甚至能够同时发起多个请求,而后等待它们所有返回。
Fetch 也能作到吗?
是的。但前提是你的用户使用了新版的浏览器,否则的话你就须要加一个 Fetch 的 「polyfill」,或者使用 Request、Bluebird 或者 Axios 这些库。
天呐我到底须要多少个库?
这是 JS,同一件事情有上千个库在作。咱们了解库,并且咱们有最好的库,咱们有海量的库,要什么有什么。
你刚才说的几个库都是干什么的?
这几个库操做 XMLHttpRequest 而后返回 Promise 对象。
好像 jQuery 的 ajax 方法作的是一样的事吧……
从 2016 年起咱们就不用 jQuery 了。用 Fetch,大不了加个 Polyfill,要否则用 Bluebird、Request 或者 Axios 都行。而后用 await 和 async 管理 Promise,这样才能控制好异步任务。
这是你第三次说 await 了,那是什么东西?
await 能让你拦住一个异步调用,让你更好地控制异步返回的数据,大大加强了代码的可读性。await 很是好用,你只须要在 Babel 里添加 stage–3 配置,或者添加 syntax-async-functions 和 transform-async-to-generator 插件就能够了。
听起来像是疯了。
没疯。为了使用 await,把 Typescript 编译以后再用 Babel 转译一道的人才是疯了。
啥玩意?Typescript 不支持 await?
下个版本就支持了。
我已经无话可说了。
你看其实很简单。用 Typescript 写代码,用 Fetch 发起异步请求,全部代码编译成 ES6,而后用上 Babel 的 stage–3 配置项,把 ES6 转译成 ES5。全部代码用 SystemJS 加载。若是你用不了 Fetch,就加个 polyfill,或者用 Bluebird、Request 或者 Axios,这样你就能够用 await 来处理 Promise 了。
看来咱们俩对于「简单」的理解是不一样的。好吧,有了这些,我终于能够获取数据而后用 React 展现数据了,对吧?
你的网页须要处理状态变动吗?
唔,不用吧。我只是想展现数据。
那就好,否则我就得跟你解释 Flux,以及 Flux 的一些实现,好比 Flummox、Alt、Fluxible。不过说真的你应该用 Redux。
你说的这些我就当耳旁风了。再说一次,我只想展现数据。
这样啊,若是你只是想展现数据,其实你不须要 React。你只须要一个模板引擎。
你逗我呢?
我只是告诉你你能够用什么技术。
别说了,真的。
我想说,即便只是用一个模板引擎,我仍是会用 Typescript + SystemJS + Babel 的。
我只是想在页面上展现数据,你就告诉我用哪一个模板引擎就行了。
有不少,你用过哪个?
额,过久没用了,不记得了。
jTemplates、jQote 仍是 PURE?
额,不记得,还有别的么?
Transparency? JSRender? MarkupJS? KnockoutJS? 这一个支持双向绑定。
还有吗?
PlatesJS? jQuery-tmpl? Handlebars? 还有些人在用。
有点像。有哪些跟最后一个比较像的?
Mustache, underscore? 我记得连 Lodash 都有一个模板引擎,不过这是 2014 年的事情了。
额,也许是再新一点的库?
Jade? DustJS?
没用过
DotJS? EJS?
没用过。
Nunjucks? ECT?
没用过。记不起来了,要是你的话,你用哪一个?
我应该会用 ES6 原生的模板字符串
我猜猜,只有 ES6 支持。
对的。
须要用 Babel
对的。
须要用 npm 安装
对的。
须要用 Browserify 或者 Webpack,或者 SystemJS
对的。
若是没用 Webpack 的话,我还须要一个任务管理工具。
对的。
可是因为我要用函数式编程和强类型语言,因此我首先要用上 Typescript 或者 Flow。
对的。
若是我要用 await,那我就必须用 Babel 转译。
对的。
而后我就能用上 Fetch、Promise 和各类炫酷的东西。
嗯,别忘了加上 Fetch 的 Polyfill,由于 Safari 不支持 Fetch。
你猜怎么着,咱们就聊到这吧。我不作了,我不作 Web 了,我也不想再碰 JS 了。
没事,过不了几年,咱们都会用 Elm 或者 WebAssembly 了。
我要回后端去了,我受不这些变更、版本更新、编译和转译了,JS 社区若是以为有人能跟上它的脚步,那这个社区就是疯了。
我理解你。我建议你去 Python 社区。
为何?
据说过 Python 3 吗?
完。
译者注:最后一句「据说过 Python 3 吗?」是讽刺 Python 3 发布已经 8 年了,Python 社区却依然在使用 Python 2.7。而 JS 社区正好相反,把尚未实现的语言特性都用到生成环境中了!
译者:方应杭
这里注明该文章为方应杭翻译过来的 尊重原创~