JavaScript开发工具简明历史

简介: 译者按: JavaScript开发要用到的工具越来越多,越来越复杂,为什么呢?你真的弄明白了吗?原文: Modern JavaScript Explained For Dinosaurs为了保证可读性,本文采用意译而非直译。

译者按: JavaScript开发要用到的工具越来越多,越来越复杂,为什么呢?你真的弄明白了吗?

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

如果你不是老司机,面对众多JavaScript开发工具,也许会有些搞不清楚状况。因为,JavaScript的生态系统在迅速的变化,新手很难理解这些工具的功能以及它们所解决的问题。对此,我深有体会。

我是1998开始编程的,但是我直到2014才开始学习JavaScript。当我第一次接触Browserify时,有这样一句介绍:

通过将依赖打包,Browserify让你可以在浏览器中使用require(‘modules’)

当时,我完全无法理解这句话,也不知道Browserify到底有什么用。

这篇博客将从历史演进的角度,告诉大家今天的JavaScript开发工具是怎样发展而来,以及它们到底有什么作用。首先,我们将介绍一个非常简单的网页示例,它是由最原始的HTML与JavaScript写的。然后,我们会逐步介绍不同的工具,它们可以解决不同的问题。

原始的JavaScript使用方式

最原始的网页,是用HTML和JavaScript编写的,没有那么多幺蛾子。不过,我们需要手动下载并载入依赖的JavaScript文件。如下,index.html中载入1个JavaScript文件:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript Example</title>
  <script src="index.js"></script>
</head>
<body>
  <h1>Hello from HTML!</h1>
</body>
</html>

<script src="index.js"></script> 载入了同目录的index.js文件:

// index.js
console.log("Hello from JavaScript!");

这样,一个简单的网页就写好了!

现在,假设你需要使用一个第三方库比如moment.js,这个库可以帮助我们处理时间数据。比如:

moment().startOf('day').fromNow();        // 20 hours ago

我们需要在的官网下载moment.min.js,放到同一个目录中,然后在index.html中载入:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Example</title>
  <link rel="stylesheet" href="index.css">
  <script src="moment.min.js"></script>
  <script src="index.js"></script>
</head>
<body>
  <h1>Hello from HTML!</h1>
</body>
</html>

可知,moment.min.js先于index.js载入,这样我们就可以在index.js中调用moment了:

// index.js
console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());

**总结: ** 直接使用HTML和JavaScript库编写网页非常简单,也很容易理解;然而,当JavaScript库更新时,我们需要手动下载并载入新版本,这样确实很烦...

npm:包管理工具

大概2010开始,数个JavaScript包管理工具诞生了,它们旨在通过一个中央仓库,使得下载和更新JavaScript库更加自动化。2013年时,Bower可能是最流行的;到了2015年, npm逐渐占据统治地位;而2016年,yarn开始逐渐引起关注,但是它的底层是基于npm的。还有一点,npm最初是为node.js开发的,并不是为了前端。因此,使用npm管理前端的依赖库显得有点奇怪。

现在,我们来看看如何使用npm安装moment.js吧。

如果你已经安装了nodejs,则npm也应该安装好了。这时,进入index.html所在目录,执行以下命令:

$ npm init

终端会出现数个问题,仅需使用enter键选择默认配置就好了。命令执行之后,会生成一个package.json文件,npm使用这个文件保存所有的项目信息。默认的package.json是这样的:

{
  "name": "your-project-name",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

使用一下命令,即可安装moment.js:

$ npm install moment --save

这个命令会做两件事情:首先,它会下载moment.js,将其保存到node_modules目录中;然后,它会更新package.json,保存moment安装信息。

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.19.1"
  }
}

这样,当我们需要与其他人分享这个项目时,就不需要将node_modules发送给对方了,而只需要给它package.json文件,因为它可以使用npm install安装所有依赖库。

moment.min.js文件位于node_modules/moment/min目录中,因此我们可以在index.html中直接载入moment.min.js

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript Example</title>
  <script src="node_modules/moment/min/moment.min.js"></script>
  <script src="index.js"></script>
</head>
<body>
  <h1>Hello from HTML!</h1>
</body>
</html>

总结: 现在,我们不需要手动下载moment.js了,而可以通过npm自动下载以及更新,这样方便很多;但是,我们需要在node_modules中找到对应的JS文件,然后将它载入HTML,这样很不方便。

顺便分享一个好东西: 如果你需要监控线上JavaScript代码的错误的话,欢迎免费使用Fundebug!

webpack - 打包工具

大多数编程语言都提供了模块管理功能,可以在一个文件中导入另一个文件的代码。然而,JavaScript最初并没有支持这种方式。很长时间以来,组织多个JavaScript文件的代码时,需要使用全局变量。我们在载入moment.min.js时,实际上也定义了一个moment全局变量,因此所有之后载入的JS文件,都可以使用它。

2009年,一个叫做CommenJS的项目出现了,它为JavaScript模块化定义了一个规范,从而允许JavaScript能够和其他编程语言一样在不同文件中引入模块。Node.js是支持CommenJS规范的,它可以使用require直接引用模块:

// index.js
var moment = require('moment');

console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());

这样写非常方便,然而,如果你在浏览器中执行上面的代码,则会收到报错,因为"require未定义"。

这时,我们就需要打包工具了,它们可以将源代码构建成为兼容浏览器的代码,来避免上面提到的问题。简单地说,打包工具可以找到所有require语句,然后将它们替代为各个JS文件中代码,最终生成的一个单独的JS文件。

Browserify是2011年发布,曾经是最流行的打包工具;到了2015年, webpack逐渐成为了最主流的打包工具。

现在,我们来看看如何让require('moment')可以在浏览器中执行。首先,我们需要安装webpack:

$ npm install webpack --save-dev

--save-dev选项表示webpack模块时开发环境中需要的依赖库,而生产环境中并不需要。package.json更新之后是这样的:

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.19.1"
  },
  "devDependencies": {
    "webpack": "^3.7.1"
  }
}

使用一下命令运行webpack:

$ ./node_modules/.bin/webpack index.js bundle.js

bundle.js为生成的打包文件,可以直接在浏览器中使用:

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JavaScript Example</title>
  <script src="bundle.js"></script>
</head>
<body>
  <h1>Hello from HTML!</h1>
</body>
</html>

每次修改index.js之后,我们都需要执行webpack。webpack的命令比较长,这样很麻烦,尤其是我们需要使用一些高级选项时。这时,我们可以将webpack的配置选项写入webpack.config.js文件:

// webpack.config.js
module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js'
  }
};

这样,我们直接运行wepack,而不需要指定任何配置选项,就可以进行打包了:

$ ./node_modules/.bin/webpack

总结: 使用打包工具之后,对于第三方JS库,我们不再需要在HTML中使用<script>载入,也不需要定义全局变量了,而是直接在JS代码中使用require语句。另外,将多个JS文件打包成为一个单独的文件也有利于提高网页性能。然而,每次更新代码时,我们都需要手动运行webpack,这很不方便。

Babel - 新语法特性转码器

转码器可以将代码由一个语言转换为另一个语言,它对于前端开发来说非常重要。浏览器对于语言的新特性支持通常很慢,我们使用新语言特性编写的代码需要转换为兼容的代码才能正常运行。

对于CSS,转码器有SassLess,以及Stylus。对于JavaScript,CoffeeScript 曾经是最流行的,而现在用的最多的是babelTypeScript。CoffeeScript是一门可以编译到JavaScript的语言,旨在优化JavaScript。Typescript也是一门语言,支持最新的ECMAScript,并且支持静态类型检查。而Babel并非一门语言,而只是一个转码器,可以将ES6以及更高版本的JavaScript代码转为ES5代码,从而兼容各个浏览器。很多人选择babel,因为它最接近原生的JavaScript。

现在,我们来看看如何使用Babel。

首先,我们需要安装babel:

$ npm install babel-core babel-preset-env babel-loader --save-dev

我们一共安装了3个模块:babel-core是Babel的核心部分;babel-preset-env定义了转码规则;babel-loader是Babel的webpack插件。

然后,在webpack.config.js中配置babel-loader即可:

// webpack.config.js
module.exports = {
  entry: './index.js',
  output: {
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env']
          }
        }
      }
    ]
  }
};

webpack的配置文件看着有点晕,大致含义是这样的:告诉webpack找到所有js文件(除了node_modules目录中的文件),根据babel-preset-env中的转码规则,使用babel-loader进行转码。至于webpack配置的细节,可以查看文档

现在,我们可以开始使用ES2015特性编程了。index.js中使用了模板字符串

// index.js
var moment = require('moment');

console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());

var name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

我们也可以使用import来代替require

// index.js
import moment from 'moment';

console.log("Hello from JavaScript!");
console.log(moment().startOf('day').fromNow());

var name = "Bob", time = "today";
console.log(`Hello ${name}, how are you ${time}?`);

修改index.js之后,运行webpack重新构建代码:

$ ./node_modules/.bin/webpack

其实,现在大多数浏览器都支持了ES2015特性,所以你可以测试一下IE9。在bundle.js中,我们可以看到转码后的代码:

// bundle.js
// ...
console.log('Hello ' + name + ', how are you ' + time + '?');
// ...

总结: 有了Babel,我们就可以放心地使用最新的JavaScript语法了。但是使用模板字符串这样简单的语法显然没什么意思,所以不妨试试async/await。不过,现在我们还有两个问题需要解决:bundle.js应该需要压缩,这样才能提高性能,这一点很简单;每次修改代码,都需要手动运行webpack,这样很不方便,下一步我们来解决这个问题。

npm scripts - 任务管理工具

任务管理工具可以将一些重复性的任务自动化,比如合并文件、压缩代码、优化图片以及运行测试等。

2013年时,Grunt是最流行的任务管理工具,其次是Gulp。现在,直接使用npm的scripts功能的开发者似乎越来越多了,这样不需要安装额外的插件。

修改package.json,即可配置npm scripts:

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress -p",
    "watch": "webpack --progress --watch"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.19.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.7.1"
  }
}

我们定义了2个scripts,即build和watch。

运行build,即可构建代码了(- -progress选项可以显示构建进程,-p选项可以压缩代码):

$ npm run build

运行watch,则一旦javascript修改了,就会自动重新运行wepback,这样开发就方便多了:

$ npm run watch

还有,我们可以webpack-dev-server,它可以提供一个网页服务器,而且能够自动重载页面:

$ npm install webpack-dev-server --save-dev 

修改package.json:

{
  "name": "modern-javascript-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --progress -p",
    "watch": "webpack --progress --watch",
    "server": "webpack-dev-server --open"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "moment": "^2.19.1"
  },
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-preset-env": "^1.6.1",
    "webpack": "^3.7.1"
  }
}

运行:

$ npm run server

这时,浏览器会自动打开localhost:8080,并访问index.html。当我们修改index.js时,代码会自动重新构建,并且页面也会自动刷新。这样我们修改代码之后,就可以看到浏览器中的效果,而不需要任何额外的操作。

正如前文提到过,npm scripts或者其他任务管理工具可以做的事情还有很多,感兴趣的话,可以看看这个视频

结论

简单总结一下:刚开始我们用HTML和JS写代码;后来我们用包管理工具来安装第三方库;然后我们用打包工具实现模块化;再后来我们用转码器从而使用最新语法;最后我们用任务管理工具来自动化一些重复的任务。对于新手来说,这一切都显得非常头疼,更头疼的是这一切还在不断变化之中。

当然也有好消息,各个框架为了方便初学者,都会提供工具,把所有配置都弄好: Ember有ember-cli,Angular有angular-cli, React有create-react-app, Vue有vue-cli。这样,似乎你什么都不用管,只需要写代码就可以了。然而,现实是残酷的,总有一天你需要对Babel或者Webpack进行一些个性化配置。因此,理解每一个工具的作用还是非常有必要的,希望这篇博客可以帮助大家。

img_bb31b8cb2adb7b52a50d9e91733778b7.jpe

版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/11/29/history-of-javascript-tools/

目录
相关文章
|
3月前
|
Web App开发 JavaScript 前端开发
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念
Node.js 是一种基于 Chrome V8 引擎的后端开发技术,以其高效、灵活著称。本文将介绍 Node.js 的基础概念,包括事件驱动、单线程模型和模块系统;探讨其安装配置、核心模块使用、实战应用如搭建 Web 服务器、文件操作及实时通信;分析项目结构与开发流程,讨论其优势与挑战,并通过案例展示 Node.js 在实际项目中的应用,旨在帮助开发者更好地掌握这一强大工具。
76 1
|
2月前
|
Web App开发 JavaScript 前端开发
Node.js开发
Node.js开发
78 13
|
3月前
|
存储 JavaScript 前端开发
深入浅出Node.js后端开发
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将以Node.js为例,深入探讨其背后的哲学思想、核心特性以及在实际项目中的应用,旨在为读者揭示Node.js如何优雅地处理高并发请求,并通过实践案例加深理解。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和思考。
|
3月前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
本文将带你领略Node.js的魅力,从基础概念到实践应用,一步步深入理解并掌握Node.js在后端开发中的运用。我们将通过实例学习如何搭建一个基本的Web服务,探讨Node.js的事件驱动和非阻塞I/O模型,以及如何利用其强大的生态系统进行高效的后端开发。无论你是前端开发者还是后端新手,这篇文章都会为你打开一扇通往全栈开发的大门。
|
3月前
|
Web App开发 开发框架 JavaScript
深入浅出Node.js后端开发
在这篇文章中,我们将一起探索Node.js的奇妙世界。无论你是刚接触后端开发的新手,还是希望深化理解的老手,这篇文章都适合你。我们将从基础概念开始,逐步深入到实际应用,最后通过一个代码示例来巩固所学知识。让我们一起开启这段旅程吧!
|
2月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带领读者从零基础开始,一步步深入到Node.js后端开发的精髓。我们将通过通俗易懂的语言和实际代码示例,探索Node.js的强大功能及其在现代Web开发中的应用。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的见解和技巧,让你的后端开发技能更上一层楼。
|
3月前
|
JavaScript 前端开发 API
深入理解Node.js事件循环及其在后端开发中的应用
本文旨在揭示Node.js的核心特性之一——事件循环,并探讨其对后端开发实践的深远影响。通过剖析事件循环的工作原理和关键组件,我们不仅能够更好地理解Node.js的非阻塞I/O模型,还能学会如何优化我们的后端应用以提高性能和响应能力。文章将结合实例分析事件循环在处理大量并发请求时的优势,以及如何避免常见的编程陷阱,从而为读者提供从理论到实践的全面指导。
|
3月前
|
Web App开发 JavaScript 前端开发
深入浅出Node.js后端开发
本文将带你走进Node.js的世界,从基础到进阶,逐步解析Node.js在后端开发中的应用。我们将通过实例来理解Node.js的异步特性、事件驱动模型以及如何利用它处理高并发请求。此外,文章还会介绍如何搭建一个基本的Node.js服务器,并探讨如何利用现代前端框架与Node.js进行交互,实现全栈式开发。无论你是初学者还是有一定经验的开发者,这篇文章都将为你提供新的视角和深入的理解。
91 4
|
3月前
|
前端开发 JavaScript 关系型数据库
基于 Vue2.0 + Nest.js 全栈开发的后台应用
Vue2 Admin 是一个基于 Vue2 和 Ant Design Pro 开发的前端项目,配合 Nest.js 构建的后端,提供了一个完整的全栈后台应用解决方案。该项目支持动态国际化、用户权限管理、操作日志记录等功能,适合全栈开发者学习参考。线上预览地址:https://vue2.baiwumm.com/,用户名:Admin,密码:abc123456。
|
3月前
|
开发框架 JavaScript 前端开发
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势
TypeScript 是一种静态类型的编程语言,它扩展了 JavaScript,为 Web 开发带来了强大的类型系统、组件化开发支持、与主流框架的无缝集成、大型项目管理能力和提升开发体验等多方面优势。通过明确的类型定义,TypeScript 能够在编码阶段发现潜在错误,提高代码质量;支持组件的清晰定义与复用,增强代码的可维护性;与 React、Vue 等框架结合,提供更佳的开发体验;适用于大型项目,优化代码结构和性能。随着 Web 技术的发展,TypeScript 的应用前景广阔,将继续引领 Web 开发的新趋势。
66 2

热门文章

最新文章

  • 1
    当面试官再问我JS闭包时,我能答出来的都在这里了。
    64
  • 2
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    32
  • 3
    Node.js 中实现多任务下载的并发控制策略
    35
  • 4
    【2025优雅草开源计划进行中01】-针对web前端开发初学者使用-优雅草科技官网-纯静态页面html+css+JavaScript可直接下载使用-开源-首页为优雅草吴银满工程师原创-优雅草卓伊凡发布
    27
  • 5
    【JavaScript】深入理解 let、var 和 const
    49
  • 6
    【04】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架二次开发准备工作-以及建立初步后端目录菜单列-优雅草卓伊凡商业项目实战
    48
  • 7
    【03】Java+若依+vue.js技术栈实现钱包积分管理系统项目-若依框架搭建-服务端-后台管理-整体搭建-优雅草卓伊凡商业项目实战
    61
  • 8
    【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
    59
  • 9
    如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
    72
  • 10
    【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
    58