一个普通的写网页的人如何过渡到ES6 (一) - Tricky's Blog

一个普通的写网页的人如何过渡到ES6 (一)

好像起了一个很无奈的标题,写这篇文章其实是对自己整个学习过程的整理,分享出来也给所有要进步的人一同进步吧。不过前提是你会写网页。

背景

很久以前接触了网页开发,当时还很流行使用 Dreamweaver ,拖拉控件就能够做出一个很简单的 网页

当然,使用 Dreamweaver 有很多的局限性,没办法实现自己要的某一些效果,那就不得不开始学习 Html、Css、Js

当时其实还不会说要把样式文件单独写在 .css 文件里面,把脚本写在 .js 文件里面,反正说白了就好像只知道自己在学 Html 一样,而根本不知道 cssjs 的存在。

那时候对于 动态网页 还停留在:这个网页会动的概念上。

再后来,知道了自己在接触 js 的时候还误将 jQuery 当成一门语言,
因为使用 $('#btn').click(function(){}); 这样的语法很爽。

不知道过了多久才能够明白 库(library) 这一个词。
我才明白自己是在使用 js 的一个库包,叫做 jQuery。

我相信不少人和我一样,特别是初学网页开发,都会经历这么一个过程。
亲戚问到我是学什么的我还可以说我是学 开发网站 的,
实际上,我学的这些 Html/Css/Js 最多可以说是 开发网页

后来了解了服务器端的开发,才明白了什么是 动态网页
还在读书的我开始知道了一些网站开发的工作种类:前端/后端/全栈

我知道我所学的这些 Html/Css/Js 可以归属于 前端
但是好景不长,想要成为一个 前端工程师 ,并不是想象中的那么简单。

自以为会一点 jQuery 就可以写出各式各样的网页(虽然也没错)。
这几年的时间可以说把上面说的东西都挖了好几遍(虽然还有很多地方不懂)。
但是时代在进步,总有新的东西出现,我们还是要不断地学习。

要学什么? ES6 这个词大大地印在眼前,我知道,我要去学 ES6 ,但是当我们翻一下搜索引擎的结果,会看到更多的词,望而却步。

ES6 可以理解为是 Javascript 一个全新的版本,稍微阅读一下相关资料才知道,Javascript 原名叫 ECMAScript 缩写就是 ES,而当前浏览器都兼容的是 ES5,我一直以来在学的其实也就是 ES5 。ES6 为我们提供了一些更加可爱更加好玩的语法。

比如说其中一个点:模板字符串

我们经常在 js 中写这样的代码:

var foo = "helloworld";
var div = "<div>" + foo + "</div>";

这样的代码稍微复杂一点就会变得很难维护,在 es6 里面可以直接使用模板字符串变成这样:

var foo = "helloworld";
var div = `<div> ${helloworld} </div>`;

“什么?ES6 不能在浏览器端直接运行?”
“是啊,得先用babel转一下”

babel是什么鬼?稍微查一下,找到 babel 的官网,又会发现安装 babel 的时候出现了一些看不懂的东西:

看到了一个很熟悉的单词 npm,这个单词好像在学 bootstrap 的时候也有看到。

查一下 npm 你会得到大家的回复告诉你这是一个 包管理器,又是什么鬼?

要使用 npm 的话你得安装 node,??????

再接下来会看到各种各样新的名词,头昏眼花

  • webpack

  • gulp

  • browserify

  • react

  • vue

  • angular

  • es2015/es2016/es2017

网上的教程大都不考虑到 我是一个普通的写网页的人(看,我连工程师都不敢自称)。
就像前面那对问答一样,得先用 babel 转一下,而有些人直接推荐你使用 webpack ,还有些人会说你学一下 vue 就知道了,无从入手。

我就是一个会使用 jQuery 的网页开发者,怎么投入 es6 的怀抱呢?

上述的背景有一部分是编的,真正学习的过程可能更加杂乱,能够这么有条理其实很难得了。能够总结这篇文章出来其实也是花了大量的时间在实践,尝试一下尽量讲的通俗易懂吧。

Node.js

我后来接触到的第一门服务器端/后端语言是 PHP,它可以处理当你点击某个登录按钮后传送过来服务器的信息。在那时候 javascript 还只能用来写前端的页面,但是后来这个叫做 Node.js 的东西出现了,只要在你的电脑(或者说服务器)上安装了 Node.js ,那么你就可以用 Javascript 来写后端程序,它同样可以处理 PHP 能处理的一些东西。

对于前端工程师来说,学习一门语法,然后就可以用于前后端开发,岂不是乐呵呵?

然而,我在这里说 Node.js 并不是为了想要用来写什么后端程序,而是想依赖于它做其它事情。

那么,你首先就需要安装一个 Node.js,安装教程网上就一大堆,这里就不扩展。

安装完了以后,我们可以打开命令行工具,输入 node -v ,以确认我们已经安装了 node.js,如下图所示

然后我们顺便玩玩,输入 node 之后回车,会进入 node 程序,在这里可以做一些简单的运算甚至使用一些 javascript 的语法。

你可以通过按两次 ctrl+c 来退出 node 程序,回到初始的命令行界面。

在这里一定要认识一个经常看到的单词叫做 CLICLI 指的是命令行界面,就是上面图片里这个黑不溜秋的界面。

NPM

在我们安装 Node.js 的时候,它会帮我们安装另一个东西叫做 npm

这到底是什么东西呢?什么叫 做包管理器

上文中提及了,我管 jQuery 叫做 库包 ,在日常的网页开发中,我们会去搜索引擎找一下 jQuery 的官网,然后下载一份 jquery.js 文件放到我们的网页项目的某个文件夹里面。

可是随着项目越来越大,用到的所谓 库包 越来越多,我的浏览器上可是打开了 n 多个库包的官网,就为了下载这些东西。

所以使用 npm 的话,这一切会变得十分简单。比如我需要下载一个jquery,假设我在E盘的根目录有一个文件夹 es6 作为这次学习的目录,打开命令行工具并把路径切换到这个 es6 文件夹,然后输入 npm install jquery,如下图所示

等他执行完毕以后你会发现,在 es6 文件夹下出现了一个 node_modules 的文件夹和一个 package-lock.json 文件。

打开 node_modules 就会发现在那里面有一个 jQuery 的文件夹,仔细找找就能找到 jquery.js 文件在那里面了。

然后在项目中就可以直接使用了

<script src="node_modules/jquery/dist/jquery.js">

是不是很方便呢?

当然强迫症患者会说,我根本就不想要把这个 jquery.js 文件放在这个什么 node_modules 里面。没错,确实很不爽,但是之所以会放在 node_modules 文件夹里面,有它的原因,不过我们就知道可以有这么一种方式吧。

ES6 的 import 语法

我推荐,大家可以先去学一下 ES6 的语法,特别是相对于 ES5 所增加的,网上有很多文档教程。

我这里,只是想说一下,如果我们要使用 ES6 来写页面,而且还要用我们一直所学的 jQuery 。
就必须要先改变我们传统的想法,什么传统的想法呢?

就是我们一直以来,在页面里面引入库包,都是使用 <script> 标签,引入 n 个库包,就会有 n 个 <script> 标签。
而在这其中,如果 A.js 依赖于 B.js ,就必须把 B.js 的标签放在 A.js 标签的前面:

<script src="B.js">
<script src="A.js">

当我们引入的库包很多,在组织顺序这个问题上就很伤脑筋了。
所以,在 es6 里面,我们可以使用它的模块化思想,就上面这个例子,A.js 会依赖于 B.js,我们只需要在 A.js 这个文件里面书写:

//A.js
import b from './B.js'
import $ from 'jquery' //引入jquery

然后,在 html 文件里面,我们只需要引入 A.js 就行了。

<script src="A.js">

也就是 html 里面再也没有各种乱七八糟的引入了,es6 视每个单独的文件为 模块,所以 import 语法让我们的开发更加的便捷。

在上面的代码片段中,我们根本就无需关心 jquery 的路径在哪里,因为系统会帮你在 node_modules 里面找到,但如果是我们自己的代码文件,可以通过 相对路径 来引入。

做个DEMO

所以,让我们一起新建两个文件在刚才的 es6 文件夹里:index.htmla.js

我们就做一个最简单的效果,页面上有一个按钮,一按就弹出 “hello world”。并且用上刚学的 es6 语法。

这是 index.html 的内容:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>try es6</title>
    <script src="a.js"></script>
</head>
<body>
    <button id="mybtn">click me to hello</button>
</body>
</html>

这是 a.js 的内容:

import $ from 'jquery';

$(function(){
    $('#mybtn').click(function(){
        alert('hello world');
    });
});

然后用浏览器打开这个页面,会发现按了按钮也没有任何的反应!接着我们打开开发者工具:

有一句提示 Uncaught SyntaxError: Unexpected token import

显然,浏览器不认识 es6 的 import 语法,那怎么办呢?

Babel

使用 babel 能将使用 es6 语法的脚本转化为 es5 语法,使得浏览器能看懂,那怎么使用呢?

首先,我们得安装它,根据 Babel官网 的提示,打开命令行工具,并输入

npm install babel

这个过程就像安装 jquery 一样简单,也会被安装到 node_modules 里面,但是需要注意的是 babel 是一个开发时我们开发者用的工具,而不是最终会输出给浏览器使用或者给其他页面代码使用的库包

如果稍微对 npm 进行学习,知道 package.json 是什么东西,看完这句话你应该能明白,在 npm install 的时候,后面的参数要跟 --save 还是 --save-dev

好,接下来我们就使用 babel 转换一下代码,在命令行中输入:

babel a.js -o a_es5.js

这句话的意思就是把 a.js 转化成 es5 之后输出到 a_es5.js 这个文件里面。执行完毕以后,在我们的项目里面应该能看到多出来的 a_es5.js 这个文件。

现在重新在浏览器中打开这个页面。哦,不对,我们的 html 代码引用的是 a.js,所以我们要改一下,改成这个我们转化好的文件:

<script src="a_es5.js"></script>

好了,在浏览器中打开它,还是会报错!
TIM图片20171010192022.png

而且会发现,这个 a_es5.js 根本就没有发生什么变化,那到底是为什么呢?
查了一下官网的资料才发现,原来还要写一个配置文件,用来告诉 babel 到底怎么转换,从 es6 转还是从 es7/8/9/10/11/12.... 转。

所以在我们的 es6 目录下还要新建一个 .babelrc 的文件,并且在里面输入:

{
  "presets": ["env"]
}

对,就三行代码,虽然我也觉得很麻烦,但是这一步还是很有必要的。

但我们还少了一步,其实这个括号里面的 env 是属于 babel 的一个插件,很多时候都管它叫做 babel预设(presets)。所以我们也一样要通过 npm 来安装:

npm install babel-preset-env

babel 官网的插件页 你可以看到总共有哪几种预设。

进行完上面的预设配置以后,我们再次运行 babel a.js -o a_es5.js 进行编译,

然后在编辑器中偷偷打开 a_es5.js 瞧瞧:

'use strict';

var _jquery = require('jquery');

var _jquery2 = _interopRequireDefault(_jquery);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

(0, _jquery2.default)(function () {
    (0, _jquery2.default)('#mybtn').click(function () {
        alert('hello world');
    });
});

嗯,这次总算发生了转化。虽然转化后的代码我们都看不懂了,但是无关紧要,能运行就是了对吧,打开浏览器!

怎么还是有错误!

Browserify

babel 转化的过程中,把那些 import 转化成了 require,然而我并不知道 require 是一个什么东西。

如果需要详细了解,大家可能还需要阅读什么是 AMD,CommonJs 规范。

在这个过程中我只知道,浏览器觉得 require 是一个未定义的函数,那我们怎么使得它变成一个定义了的函数呢?

这个时候就需要用到 Browserify 了。

Browserify 官网的说明:Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.

大概意思就是,浏览器并不支持 require 函数,有了 browserify 你就可以大胆的写 require 这个函数了。

看这个说明的时候就能明白,它能够帮我们处理掉上面我们遇到的错误了。

还是一样,npm install browserify,先把它给安装好。

然后还是在命令行使用 browserify a_es5.js -o a_es5_killRequire.js 干掉那些 require

一切顺利,记得把html文件中的引用改成 a_es5_killRequire.js,然后我们继续在浏览器中打开页面:

哇!运行成功!es6 抱抱!

总结

当我们写了一个es6语法的脚本之后

  1. 用 babel 把 es6 转化为 es5

  2. 用 browserify 干掉 require

  3. 运行你的页面

虽然我们的目的是想过渡到 es6,但是在当前的环境下接触 es6 还是不得不接触很多很多的工具,有了这些工具就可以帮我们更好地进行 es6 开发,当然,es6 本身和这些工具没什么关系,所以在学习 es6 和这些工具的时候不要把这些工具作为es6体系的一部分~就算没有这些工具,总有一天 es6 也会被浏览器默认支持!同样,这些工具离开 es6 也能干很多事情。

所以我们现在在学习的内容是 es6相关的工具

其实这一节最后的 browserify 还没体现出他的厉害之处,下一节尝试一下稍微复杂的代码。

Q:是不是我写的 es6 里面没有什么 import ,更不用说什么转化为 require 了,就可以不用 browserify 了?
A:在 es6 里面有很多全新出炉的函数,浏览器并没有实现,也许还需要借助其他的工具来转化代码,但是如果就 import 而言,是的,如果代码中没有 import,当然可以不用 browserify 。

建议大家回头再去看看 es6 的语法,特别是 import 和 export 这部分的,然后再学一学一些 npm 的一些命令。

  JavaScript ES6