前端工具演变

假如你烘焙过蛋糕(哪怕没有亲自做过,但是也应该听说过),除了基本的面粉,鸡蛋等原材料外,或许你还需要一个电动蛋白打发器,一个烤箱。这是现代的做法,那么在打发器和烤箱发明之前,人们怎么烤蛋糕呢? 没有打发器,只能手动打发,这样的弊端是不仅花费时间长,而且你的手可能也要废掉。没有烤箱,用炭烤,这样就会出现温度不好掌握,或许还得有人一直盯着的问题。

我一直爱把软件开发想成做菜,原材料就是编程语言,菜单是算法逻辑,而做菜的这些工具也是我们在软件开发中使用的各种工具。做菜的工具有历史演变的过程,我们软件开发的工具也是如此。

只是有些工具,现在被大家广泛使用,而有些却只能在一些老文章里面见证他们曾经的辉煌。今天就从前端工具演变来聊聊前端的历史发展。

摸鱼警告:本篇没有干货,纯粹闲聊。

1:没有任何工具的纯手工时代最开始的前端开发,只需要掌握HTML + CSS + JavaScript就好,我们要在一个页面上使用js,除了通过标签外,还可以把js代码放到一个js文件,通过在HTML文件引用这个js文件的方式:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="index.js"></script>
</head>
<body>
</body>
</html>

但是,当我们的业务需求变复杂,项目变大,我们通常会把逻辑相关的代码都放同一个js文件里面,这样慢慢就形成了模块的概念,例如你在做一个超市收银系统,项目里有一个(或者几个)js文件是跟价格计算相关,有些js文件是跟时间格式化相关。现在你正在开发收银小票功能模块,毋庸置疑,这个模块肯定需要用到前面的价格计算和时间格式化模块。这里,就产生了模块访问模块的需求。

很多语言都天然地支持在A文件里面引用B文件的功能,但是javaScript一开始却不是这样。因为javaScript一开始是被设计来只在浏览器(准确地说是用户的浏览器)上运行的语言。处于安全性的考虑,它不被赋予访问文件的权利和功能。

在这个阶段我们要做到在A文件使用B文件提供的功能,只能在HTML文件里面引用相关的js文件,通过在全局暴露相关变量,然后这样就能使用到了。

2:包管理(package management)工具在上面第一点我们提到了模块。在一个稍大的项目中,一般会用到很多前端社区已经成熟的模块和框架。比如,专门用来处理时间格式问题的moment.js,以前可能会用到jQuery等。我们要在项目里面使用他们,得先找到他们在网络上的地址,把相应的文件下载下来,放到我们自己的项目某个目录,然后再在HTML文件里面引用相应的文件路径。

上面的做法很显然是存在效率和不方便的问题,在这种情况下前端的package management工具应运而生。 我们先来了解一下包管理工具为我们做了什么事: 1:帮我们从网络上下载依赖 2:管理依赖的版本 3:有的还具备task runner功能(npm) 这里就要提到几个包管理工具:

bower和npm都是包管理工具,但是又有不同。现在大家听得最多,用的的可能是npm,yarn,bower已经差不多死掉了。

npm vs bower

npm(node package manager)本是nodejs用来管理node依赖的,但是后来也被用于前端的依赖管理。 bower是只被用于管理前端的组件,例如html,css,js的工具,只用在前端。

在依赖结构上二者也不相同。bower是扁平的依赖树,需要用户管理依赖的依赖。而npm采用的是嵌套的依赖树,不需要用户关心依赖的依赖。

bower

bower init //创建bower.json
bower install jquery --save //安装jquery依赖

安装成功之后会,bower会在当前目录下创建一个名叫bower_components/的文件夹。所以通过bower安装的依赖都会放到这个目录下。例如上面的jquery安装成功之后,我们能在bower_components/目录下得到jquery相关文件,然后我们就可以在HTML文件里面引用了:

<script src="bower_components/jquery/dist/jquery.min.js"></script>

npm也是类似的:

npm init //创建package.json文件
npm install jquery --save //安装jquery依赖

安装成功之后会,npm会在当前目录下创建一个名叫node_modules/的文件夹。所以通过npm安装的依赖都会放到这个目录下。例如上面的jquery安装成功之后,我们能在node_modules/目录下得到jquery相关文件,然后我们就可以在HTML文件里面引用了:

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

3:Module bundler工具在上面的第二点里面,我们使用了包管理工具,已经不再需要我们自己手动去网上找依赖,下载到项目库里,但是想要使用,依然需要在HTML文件里面一一引用。我们要怎样才能像别的语言一样在一个js文件里面引用另外一个js文件(模块)呢?

当然自从ES6(ES2015)开始,JavaScript已经有这个功能了,我们可以通过import来引入,export来导出。但是在这之前,我们只能依赖Module bundler工具来做到这一点。

当时比较出名和流行的一下2大解决方案:

  • CommonJs - node.js, Browserify.js
  • AMD(Asynchronous Module Definition)- Require.js

至今仍然有很多人没有弄明白CommonJS和AMD都是一个协议标准,而不是一个具体的库。CommonJs的核心就是module(模块),定义了JavaScript代码怎样引用和导出代码。实现了CommonJs的最出名的就是node.js和Browserify.js,而对应的实现了AMD的比较是Require.js

大家都知道node.js是运行在服务端的JavaScript,不属于我们本篇的范畴,这里不讲。接下来我们来看看

Browserify.js

如果你打开Browserify的官网,可以看到这样一句话:

Browserify lets you require('modules') in the browser by bundling up all of your dependencies.

Browserify提供require()方法在一个js文件里面引入另外一个js文件或者一个js文件export的变量。最终Browserify会根据依赖关系,把所有的js代码都整合到一个js文件里,也就是我们常说的bundle文件。之后就只需要在HTML文件里面引用这一个js bundle文件就行了。

接下来看看具体怎么使用:

step1: 全局安装browserify

npm install browserify -g //全局安卓browserify

step2: 在module/目录下创建一个module.js,有如下示例代码:

function getSum(a, b) {
    return a + b;
}

module.exports = getSum;

step3: 创建main.js文件,在这里面使用module/module.js

var getSum = require('./module/module');
var sum = getSum(10, 10);
console.log('10 + 10 = ', sum);

step4: 利用browserify创建bundle文件:

browserify main.js -o build/bundle.js -d

上面的命令就是:browserify以main.js为源文件,生成bundle文件bundle.js,创建文件夹build/,并把bundle.js放到build/路径下。-o(-output)表示后面跟上输出文件路径, -d表示生成source map.

step5: 在HTMl文件里面引入上一步的bundle.js

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <script src="build/bundle.js"></script>
</head>
<body></body>
</html>

step6: 验证结果

10 + 10 =  20 //控制台得到我们正确地结果

4:task runner工具前端的task可能会有:检查代码格式,预编译,跑测试,压缩代码,起server等。Task Runner就是按照用户自定义的任务流自动地完成一系列的task。

一般task runner工具本身并不具体具体执行某项任务的功能,而是每一个任务都有相应的插件来完成。例如曾经流行过的gruntgulp

但是现在的前端项目也不会再用到grunt和gulp了。现如今,因为项目上一般会用到npm来做依赖管理,而npm自己的script就可以用来run task, 这样也不用额外再多下一个额外的工具了。

原文链接:segmentfault.com

上一篇:解构赋值是深拷贝吗?
下一篇:团队协作分工,人力1+1等于几

相关推荐

官方社区

扫码加入 JavaScript 社区