整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

Node.js 学习笔记:构建 Web 服务

例3. 构建 Web 服务器

这部分示例将致力于用 Node.js 模拟一个类似于 Apache 的 Web 服务器,处理浏览器端的请求,将相关的页面响应给浏览器。首先,我们要在code目录下执行mkdir 03_webSever命令来创建用于存放这一组示例的目录。然后执行以下步骤:

  1. 在code/03_webSever目录下执行mkdir www命令,创建网站目录,然后在其中创建index.htm和login.htm两个 HTML 文件以及一个名为style.css的 CSS 文件:

1、index.htm:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>首页</title>
</head>
<body>
<h1>你好,nodejs!</h1>
<p> <a href="login.htm">请登录!</a> </p>
</body>
</html>

2、login.htm:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>登录页面</title>
</head>
<body>
<h1>你已经登录。。。</h1>
<p> <a href="index.htm">回首页!</a> </p>
</body>
</html>

3、style.css:

body { 
background: gray; 
}

2、在code/03_webSever目录下执行touch 03-webServer.js命令,创建脚本文件,并输入如下代码:

const http = require('http')
const fs = require('fs')
const server = http.createServer()

server.on('request', function(req, res) {
const webRoot = './www'
const url = req.url
if ( url === '/' ) {
url = '/index.htm'
}

fs.readFile(webRoot+url, function(err, data) {
if ( err !== null ) {
console.error('错误信息:' + err.message)
return res.end('<h1>404 页面没找到!</h1>')
}
res.end(data)
})
})

server.listen(8080, function(){
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

3、保存所有文件后,在code/03_webSever目录下执行node 03-webServer.js命令,然后打开浏览器并访问http://localhost:8080/,就会看到如下页面:

示例4. 使用art-template模版引擎生成网页

这一部分本示例将以生成个人信息页面为例,演示在服务器端基于 Node.js 使用art-template模板引擎来生成网页。为此,我们需要在code目录下执行mkdir 04_templatingEngine命令来创建用于存放这一组示例的目录。

1. 单模版渲染

首先来示范一下如何使用art-template模版引擎的渲染单一模版文件,请跟着以下步骤来构建示例:

  1. 在code/04_templatingEngine目录下执行npm install art-template --save命令,安装将art-template包安装到当前示例项目中。
  2. 在code/04_templatingEngine目录下执行touch singleTpl.htm命令,创建一个模版文件,并在其中输入以下代码:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>{{ name }}的个人信息</title>
</head>
<body>
<h1>{{ name }}的个人信息</h1>
<table>
<tr><td>姓名:</td><td>{{ name }}</td></tr>
<tr><td>年龄:</td><td>{{ age }}</td></tr>
<tr><td>性别:</td><td>{{ sex }}</td></tr>
<tr>
<td>爱好:</td>
<td>{{ each items }} {{ $value }} {{ /each }}</td>
</tr>
</table>
</body>
</html>

3、在code/04_templatingEngine目录下执行touch 04-useTemplating_engine.js命令,创建一个脚本文件,具体如下:

const http = require('http')
const fs = require('fs')
const template = require('art-template')

class human {
constructor(name, age, sex, items=[])
{
this.name = name
this.age = age
this.sex = sex
this.items = items
}
}

const server = http.createServer()

server.on('request', function(req, res){
const url = req.url
let boy = null
if ( url === '/' ) {
boy = new human('凌杰', '37', '男', ['看书', '看电影','旅游'])
} else if ( url === '/wang' ) {
boy = new human('蔓儿', '25', '女', ['看书', '看电影','写作'])
}

if ( boy === null ) {
return res.end('<h1>404 页面没找到!</h1>')
}

fs.readFile('./singleTpl.htm', function(err, data){
if ( err !== null ) {
return res.end('<h1>404 没找到模版文件!</h1>')
}

const strHtml = template.render(data.toString(), {
name : boy.name,
age : boy.age,
sex : boy.sex,
items: boy.items
})

res.end(strHtml)
})
})

server.listen(8080, function(){
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

4、保存所有文件后,在code/04_templatingEngine目录下执行node 04-useTemplating_engine.js命令,然后打开浏览器并访问http://localhost:8080/wang,就会看到如下页面:

2. 多模版组合渲染

在同一 Web 应用中,所有的页面通常都由相同的头部和底部元素,所以为了减少代码的冗余,提高重用率,开发者们通常会考虑将重复的部分独立成一个单独的模版文件,然后用相互包含的方式组合成页面。下面就继续以art-template模板引擎为例来演示一下如何将多个模版组合渲染成单一的 HTML 页面,其具体步骤如下:

  1. 在code/04_templatingEngine目录下执行touch tpl1.art tpl2.art命令,创建两个模版文件,然后在这两个文件中分别输入以下代码:

1、tpl1.art :

<header>
<h1>查看个人信息</h1>
<br>
</header>

2、tpl2.art :

<footer>
<div>
<p>© 2016 owlman.org;本站系纯HTML5站点。</p>
</div>
</footer>

2、在code/04_templatingEngine目录下执行touch multiTpl.htm命令创建用于组合的 HTML 页面文件,并在其中输入以下代码:

<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>查看个人信息</title>
</head>
<body>
{{ include './tpl1.art' }}
<h2>{{ name }}的个人信息</h2>
<table>
<tr><td>姓名:</td><td>{{ name }}</td></tr>
<tr><td>年龄:</td><td>{{ age }}</td></tr>
<tr><td>性别:</td><td>{{ sex }}</td></tr>
<tr>
<td>爱好:</td>
<td>{{ each items }} {{ $value }} {{ /each }}</td>
</tr>
</table>
{{ include './tpl2.art' }}
</body>
</html>

3、在code/04_templatingEngine目录下执行

cp 04-useTemplating_engine.js 04-useTemplating_engine2.js命令,将之前的代码复制一份,并修改如下:

const http = require('http')
const fs = require('fs')
const template = require('art-template')

template.defaults.root = __dirname // 配置模版的查找根目录

class human {
constructor(name, age, sex, items=[])
{
this.name = name
this.age = age
this.sex = sex
this.items = items
}
}

const server = http.createServer()

server.on('request', function(req, res){
const url = req.url
let boy = null
if ( url === '/' ) {
boy = new human('凌杰', '37', '男', ['看书', '看电影','旅游'])
} else if ( url === '/wang' ) {
boy = new human('蔓儿', '25', '女', ['看书', '看电影','写作'])
}

if ( boy === null ) {
return res.end('<h1>404 页面没找到!</h1>')
}

fs.readFile('./multiTpl.htm', function(err, data){ // 修改了要读取的模版文件
if ( err !== null ) {
return res.end('<h1>404 没找到模版文件!</h1>')
}

const strHtml = template.render(data.toString(), {
name : boy.name,
age : boy.age,
sex : boy.sex,
items: boy.items
})

res.end(strHtml)
})
})

server.listen(8080, function(){
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

4、保存所有文件后,在code/04_templatingEngine目录下执行node 04-useTemplating_engine2.js命令,然后打开浏览器并访问http://localhost:8080,就会看到如下页面:

3. 多模版继承渲染

当然,如果重复的元素只有头部和尾部的话,有时候使用模版继承语法来渲染页面会是一个更好的选择,下面就来继续演示一下art-template模板引擎的继承语法来渲染 HTML 页面,其具体步骤如下:

  1. 在code/04_templatingEngine目录下执行touch baseTpl.art命令,创建父模版文件,然后在该文件中输入以下代码:
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="style.css" />
<title>{{ name }}的个人信息</title>
</head>
<body>
<header>
<h1>查看个人信息</h1>
<br>
</header>

{{ block 'message' }}
{{ /block }}

<footer>
<div>
<p>© 2016 owlman.org;本站系纯HTML5站点。</p>
</div>
</footer>
</body>
</html>

2、在code/04_templatingEngine目录下执行touch extendTpl.htm命令,创建子模版文件,然后在该文件中输入以下代码:

{{ extend 'baseTpl.art' }}

{{ block 'message' }}
<h1>{{ name }}的个人信息</h1>
<table>
<tr><td>姓名:</td><td>{{ name }}</td></tr>
<tr><td>年龄:</td><td>{{ age }}</td></tr>
<tr><td>性别:</td><td>{{ sex }}</td></tr>
<tr>
<td>爱好:</td>
<td>{{ each items }} {{ $value }} {{ /each }}</td>
</tr>
</table>
{{ /block }}

3、在code/04_templatingEngine目录下执行cp 04-useTemplating_engine.js 04-useTemplating_engine3.js命令,将之前的代码复制一份,并修改如下:

// 用Node.js生成动态页面
// 作者:owlman
// 时间:2019年07月12日

const http = require('http')
const fs = require('fs')
const template = require('art-template')

template.defaults.root = __dirname

class human {
constructor(name, age, sex, items=[])
{
this.name = name
this.age = age
this.sex = sex
this.items = items
}
}

const server = http.createServer()

server.on('request', function(req, res) {
const url = req.url
let boy = null
if (url === '/') {
boy = new human('凌杰', '37', '男', ['看书', '看电影','旅游'])
} else if (url === '/wang') {
boy = new human('蔓儿', '25', '女', ['看书', '看电影','写作'])
}

if (boy === null) {
return res.end('<h1>404 页面没找到!</h1>')
}

fs.readFile('./extendTpl.htm', function(err, data) {
if ( err !== null ) {
return res.end('<h1>404 没找到模版文件!</h1>')
}

const strHtml = template.render(data.toString(), {
name : boy.name,
age : boy.age,
sex : boy.sex,
items: boy.items
})

res.end(strHtml)
})
})

server.listen(8080, function(){
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

4、保存所有文件后,在code/04_templatingEngine目录下执行node 04-useTemplating_engine3.js命令,然后打开浏览器并访问http://localhost:8080,就会看到与之前相同的页面。

示例5. Web 表单处理

这一部分示例将致力于演示用 Node.js 处理 Web 表单,我们将会分别示范如何用get和post两种方法来处理表单的请求。首先,我们要在code目录下执行mkdir 05_webForm命令来创建用于存放这一组示例的目录。

1. get 方法

先用一个信息查询程序来演示一下如何处理使用get方法来发送请求的表单。首先,在code/05_webForm目录下执行mkdir get_form命令,并执行以下步骤:

在code/05_webForm/get_form目录下执行npm install art-template命令,将art-template安装到当前示例项目中。
在code/05_webForm/get_form目录下执行touch index.htm,创建一个模版文件,具体如下: <!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>个人信息查询</title>
</head>
<body>
<h1>个人信息查询</h1>
<form action="/query" method="GET">
<label for="message">请输入要查询的姓名:</label>
<input type="text" name="qname" />
<input type="submit" value="查询" />
</form>
<br />
{{ if name }}
<table>
<caption>{{ name }}的个人信息</caption>
<tr><td>姓名:</td><td>{{ name }}</td></tr>
<tr><td>年龄:</td><td>{{ age }}</td></tr>
<tr><td>性别:</td><td>{{ sex }}</td></tr>
<tr>
<td>爱好:</td>
<td>{{ each items }} {{ $value }} {{ /each }}</td>
</tr>
</table>
{{ else if query_error }}
<h2>没有找到相关信息!</h2>
{{ /if }}
</body>
</html>

3、在code/05_webForm/get_form目录下执行touch app.js,创建一个脚本文件,具体如下: const http = require('http')

const fs = require('fs')
const url = require('url')
const template = require('art-template')

class human {
constructor(name, age, sex, items=[])
{
this.name = name
this.age = age
this.sex = sex
this.items = items
}
}

const db = [
new human('凌杰', '37', '男', ['看书', '看电影','旅游']),
new human('蔓儿', '25', '女', ['看书', '看电影','写作']),
new human('张语', '32', '女', ['看书', '旅游','绘画'])
]

const server = http.createServer(function(req, res){
const query = url.parse(req.url, true)
let obj = null
let query_error = false
if ( query.pathname === '/' ) {
query_error = false
}
else if (query.pathname === '/query') {
for(let i = 0; i < db.length; ++i) {
if (db[i].name == query.query["qname"]) {
obj = db[i]
}
}
if ( obj === null ) {
query_error = true
}
} else {
return res.end('<h1>404 页面没找到!</h1>')
}

fs.readFile('./index.htm', function(err, data){
if ( err !== null ) {
return res.end('<h1>404 没找到模版文件!</h1>')
}

let strHtml = null
if ( obj !== null ) {
strHtml = template.render(data.toString(), {
name : obj.name,
age : obj.age,
sex : obj.sex,
items: obj.items,
query_error: query_error
})
} else {
strHtml = template.render(data.toString(), {
name : false,
query_error: query_error
})
}
res.end(strHtml)
})
})

server.listen(8080, function() {
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

4、保存所有文件后,在code/05_webForm/get_form目录下执行node app.js命令,结果如下:

2. post 方法

先来演示如何处理使用post方法来发送请求的表单。首先,在code/05_webForm目录下执行mkdir post_form命令,并执行以下步骤:

  1. 在code/05_webForm/get_form目录下执行npm install art-template命令,将art-template安装到当前示例项目中。
  2. 在code/05_webForm/post_form目录下执行touch index.htm,创建一个模版文件,具体如下:
 <!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>个人信息管理</title>
</head>
<body>
<h1>个人信息管理</h1>
<table>
<caption>个人数据表</caption>
<tr><th>姓名</th><th>年龄</th><th>性别</th><th>爱好</th></tr>
{{ each db }}
<tr>
<td>{{ $value.name }} </td>
<td>{{ $value.age }} </td>
<td>{{ $value.sex }} </td>
<td>{{ each $value.items }} {{ $value }} {{ /each }}</td>
</tr>
{{ /each }}
</table>

<form action="/add" method="POST">
<table>
<caption>录入新人员</caption>
<tr><td>姓名:</td><td><input type="text" name="uname" /></td></tr>
<tr><td>年龄:</td><td><input type="text" name="age"></td></tr>
<tr><td>性别:</td><td><input type="text" name="sex"></td></tr>
<tr><td>爱好:</td><td><input type="text" name="items"></td></tr>
</table>
<input type="submit" value="添加" />
</form>
</body>
</html>

3、在code/05_webForm/post_form目录下执行touch app.js,创建一个脚本文件,具体如下:

const http = require('http')
const fs = require('fs')
const url = require('url')
const querystring = require('querystring')
const template = require('art-template')

class human {
constructor(name, age, sex, items=[])
{
this.name = name
this.age = age
this.sex = sex
this.items = items
}
}

const db = [
new human('凌杰', '37', '男', ['看书', '看电影','旅游']),
new human('蔓儿', '25', '女', ['看书', '看电影','写作']),
new human('张语', '32', '女', ['看书', '旅游','绘画'])
]

const server = http.createServer(function(req, res){
const query = url.parse(req.url, true)
if ( query.pathname === '/' ) {
fs.readFile('./index.htm', function(err, data) {
if ( err !== null ) {
return res.end('<h1>404 没找到模版文件!</h1>')
}

const strHtml = template.render(data.toString(), {
"db": db
})

res.end(strHtml)
})
}
else if ( query.pathname === '/add' ) {
req.on('data', function(chunk) {
const obj = querystring.parse(chunk.toString())
db.push(new human(
obj['uname'],
obj['age'],
obj['sex'],
obj['items'].split(','),
))
})

res.writeHead(302, {
'location': `/`
})

res.end()
} else {
return res.end('<h1>404 页面没找到!</h1>')
}
})

server.listen(8080, function(){
console.log('请访问http://localhost:8080/,按Ctrl+C终止服务!')
})

4、保存所有文件后,在code/05_webForm/post_form目录下执行node app.js命令,结果如下:

毒来了,程序员也要学习啊!何况你的电脑还没中病毒!

以JavaScript和V8引擎为核心,事件驱动架构和可扩展性开箱即用,Node.js已经快速成为创建Web应用和SaaS产品的新事实标准。许多框架,如Express,Sails和Socket.IO,使程序员能够只关注业务逻辑,无需考虑其他问题。

当然,Node.js目前的普及度远低于JavaScript。JavaScript支持许多不同风格的编程方式,包括函数式编程,程序编程和面向对象编程,它允许程序员灵活运用各种编程风格。

但JavaScript是把双刃剑,JavaScript的多重性质意味着几乎一切都是可变的。因此,在编写Node.js代码时,程序员无法清除对象和范围突变的概率。因为JavaScript缺少尾调用优化(允许递归函数重用堆栈帧进行递归调用),所以使用递归进行大量迭代是很危险的。除了这些陷阱之外,Node.js是单线程的,因此开发人员必须编写异步代码。

下面我将分享编写高效和可扩展Node.js代码最重要的10个JavaScript概念:

1、立即调用函数表达式

一个立即调用的函数表达式(IIFE)是一个在创建时可立即执行的函数。它与任何事件或异步执行无关。您可以定义一个IIFE,如下所示:

第一对括号function(){...}将括号内的代码转换为表达式。第二对括号调用表达式生成的函数。IIFE也可以被描述为一个自我调用的匿名函数,最常见的用法是限制通过var或者封装上下文变量的范围,以避免名称冲突。

2、闭包

JavaScript中的闭包是内部函数,即使在外部函数返回控件后也可以访问其外部函数的作用域。闭包使内部函数的变量为私有,一个简单例子如下所示:

count变量分配了一个外部函数,外部函数只运行一次,将计数器设置为零并返回内部函数。 _counter变量只能由内部函数访问,这样就可以像私有变量一样运行。

3、Prototype

每个JavaScript函数都有一个用于附加属性和方法的prototype,此属性不可枚举,它允许程序员将方法或成员函数附加到其对象。JavaScript仅通过prototype属性支持继承。在继承对象的情况下,prototype指向父对象,将方法附加到函数的常见方法是使用prototype,如下所示:

4、私有属性,使用闭包

JavaScript允许程序员使用下划线前缀定义私有属性,如上述示例所示。但这可能妨碍用户直接访问或修改私有属性。使用闭包定义私有属性将解决这个问题,在对象本身上定义需要访问私有属性的成员函数,可以使用闭包制作私有属性,如下所示:

5、Module模式

Module模式是JavaScript中最常用的设计模式,用于实现松散耦合,结构良好的代码。 它允许程序员创建公共和私有两种访问级别,实现Module模式的一种方式如下所示:

Revealing Module模式类似于Module模式,上述示例使用Revealing Module模式编写如下:

6、Hoisting

在代码执行之前,JavaScript将变量和函数声明移动到其范围顶部。无论程序员将代码中的函数和变量声明放在哪里,它们都将由解释器移动到其范围的顶部。这可能是好的,也可能不是。

在执行任何代码之前先处理变量声明。具有讽刺意味的是,未声明的变量在赋予值之前不存在,这将导致所有未声明的变量成为全局变量,虽然函数声明已经悬挂,但函数表达式未被悬停。提升变量和函数时,JavaScript具有优先级。优先级从上到下依次是可变分配、函数声明、变量声明。为了避免错误,程序员应该在每个范围的开始处声明变量和函数。

7、Currying

Currying是使函数更灵活的方法。使用curried函数,程序员可以传递函数期望的所有参数并获取结果,或者只传递部分参数,并接收等待其余参数。一个简单例子如下:

原始功能可以直接将参数逐个传递给一个单独的括号,如下所示:

8、apply,call和bind方法

任何JavaScript程序员必须了解apply,call和bind之间的区别。这三个函数是相似的,因为它们的第一个参数始终要给出调用该方法函数的“this”值或上下文。三个之中,call最简单,它与调用函数上下文相同。以下是一个例子:

apply几乎和call一样。唯一的区别是将参数作为数组传递,而不是单独传递。数组在JavaScript中更容易操作,为处理函数打开了更多可能性。以下是使用apply和call的示例:

bind方法允许将参数传递给函数而不调用。返回一个新的函数,其中的参数在任何其他参数前面都是有界限的。例子如下:

9. Memoization

Memoization是一种优化技术,可以加快函数执行,并在再次发生同一组输入时返回缓存的结果。JavaScript对象的行为就像关联数组,使JavaScript易于记忆。例如,我们可以将递归阶乘函数转换成一个记忆的阶乘函数,如下所示:

10. 方法重载

方法重载允许多个方法具有相同的名称但不同的参数。编译器或解释器根据传递的参数数量确定要调用的函数。JavaScript不直接支持方法重载。但是你可以像下面所示完成一些事情:

当你足够了解Node.js,你会发现很多方法可以解决几乎遇到的所有问题,但一定要采取正确的做法,不然很可能要重写整个逻辑。本文中的10个JavaScript概念是每个Node.js开发人员应该知道的基础知识。但只是冰山一角,希望程序员们可以持续学习。

者按:很多人都在寻找一个能够统一编程语言江湖的“老大哥”,战火也重来没有停止过。Jonny Asmar在hackernoon上发表了一篇文章指出,因为Node的存在,JavaScript具备了多功能性,已经有了坐稳“头把交椅”的势头。文章由36氪编译。

作者写在前面的话:这篇文章已经引起了大量的反对,因为很多人并不认为JavaScript是编程语言中的胜利者。

尽管我承认,我的标题可能会引起争议,可能会更加让人有点击欲望。但我还是想强调,这篇文章并不是说JS是“最好”的语言。

我只是在文章中简单地描述了它所覆盖的领域,以及它能够让简单的前端开发人员做更多事情的方法。

在编程的世界里,有一场旷日持久的战争。自从计算机问世以来,科学家们一直在寻找一种完美的编程语言。一个接一个的新语言被创造出来,以适应某种目的。随着新语言的出现,也会出现新的技术时代,新的技术社区,和大量的开源贡献。当然还会有不可避免的新的限制。自从在Java应用程序和Flash(我曾经是Flash开发者)在互联网上长期占据主导地位以来,我们已经看到有各种各样的语言的涌现,各种各样的语言毫无理由的消失,因为它们已经毫无用武之地。

世界正在朝着不同的方向前进……

那些曾经耀眼的新语言现在已经过时了,开发者越来越少,而新的语言也开始制造噪音。

到现在,JavaScript已经有几十年的历史了。所以,你可能会想,“它将会到何处去?”这篇文章其实不是关于“JavaScript”语言的。也不会去讨论在它之前许多语言的崛起和衰落。同时,也不是关于JavaScript是如何“新鲜有光泽”的。

这篇文章是关于Node的。

真的很有必要,在一开始就区分这一点。因为Node不只是一种语言。而是一个生态系统。

这就是这篇文章的主旨。

不过也不完全是这样。我不打算详细讲述这个生态系统是世界上有史以来最具创新性的开源合作的推动者。这是另一个的话题。

我要说明的是,Node是如何通过遍历现代编程的五个关键领域,赢得了一场关于完美语言的古老战争的。

Web开发

React、Angular、Vue

React、Angular和Vue都是当今最重要的前端框架。总的来说,Facebook,Google和FOSS社区共同开发出了一种令人兴奋的开发交互式用户界面的高效工具。

因此,现在你在网络上做的所有事情都是通过一个高度互动、美观、易用的界面来实现的。这些框架之所以能够完全实现,完全是因为Node生态系统,你已经知道了。

你看,毫无疑问,JavaScript在前端Web开发中占据了主导地位,但React,Angular和Vue已经将它提升到了一个新的高度。

这是用户界面的时代。

前端开发人员不再回避构建复杂的单页面Web应用程序和完整的软件套件的时代。我曾经是一名Web开发人员,现在我是一名软件开发人员。

就这样……JavaScript赢得了Web开发。

移动开发(Mobile)

React Native

这一部分不仅只是阐述Node在Mobile领域的成功,还将提出另一个关键问题:

Node是跨平台的。

这不仅仅是“哦,酷,它也能在我的手机上工作!”,也不仅仅是“哇,我的手机、平板电脑、笔记本电脑和电视都可以使用YouTube!”。

Node跨平台的方式是最重要的。对于开发者来说,这是一个真正的跨平台生态系统。那些真正建立起“噢,酷”和“哇”的东西的人都喜欢这个。

React Native只是Node生态系统中开发的框架的一个例子,它以前所未有的方式弥合了前端开发和移动应用开发之间的鸿沟,这是其他任何框架都没有的。

移动开发的最大压力一直是Web的拉动。但是,通过React Native和Node生态系统,开发者可以构建一个兼容Web、iOS和Android的应用。没有其他语言能提供这种多功能性。

就这样……JavaScript赢得了移动开发。

桌面开发(Desktop)

Electron

当然,并不是所有的事情都发生在Web上。桌面应用程序对于我们当前这个依赖技术的世界的运营中也至关重要。

但是,既然Web现在能够提供功能齐全的应用程序,为什么我们还要开发桌面软件,并对其进行不同的处理呢?

实际上,JavaScript赶上桌面端的性能需求,只是个时间问题。

所以,Electron诞生了。

当然,在桌面编程的时候,还有更高效的语言可以使用,但对于我们今天使用的大多数应用程序来说,JavaScript已经足够了。

多亏了Cheng Zhao和Github,创建了一个能够改变桌面计算面貌的框架。

Electron不仅让桌面应用程序的开发变得更加简单,而且也能兼容Mac, Windows和Linux,它构建的应用可在这三个操作系统上面运行。

虽然Windows仍然是当今最普及的操作系统,Mac的稳定增长已经持续了15年,越来越多的开发者每天都在使用Linux。此外,像树莓派这样的小玩具也会让Linux出现在许多以前只有windows或Mac的家庭中。我认为你可以理解为什么跨操作系统的开发会具有巨大的优势……而这仅仅是个开始。

截止到现在,Node生态系统已经能够完全覆盖Web开发、移动开发和桌面开发。提供了一个能够在这些所有的平台建立相同用户界面的技能组合。

就这样……JavaScript赢得了桌面开发。

后端开发

ExpressJS

我不想在这里介绍NPM(节点包管理器)上提供的无数软件包,这些包可以方便后端开发,因此,我只会提到Express sjs,有一个简单但深刻的理由:

Node是为后端而构建的。

而且,Node生态系统中的JavaScript已经成为了一种多用途的工具,已经被用于开发自己的服务器应用程序。在Node创建之前,JavaScript基本上只支持浏览器。它不需要执行复杂的服务器端操作,如数据库读取、图像转换或压缩。但现在它可以……

而且,正如以上几个例子一样,这种对代码共享和重用显着的简化也产生了一些明显的副作用。

其中一个副作用就是服务器端渲染。

你get到了吗?

服务器端

渲染

这两件事有什么共同点?

传统意义上来说,没什么。但“前端”(JavaScript)或“后端”(PHP、Java、Python、Ruby等)的开发通常是由两个完全独立的团队来维护。

两个团队的人非常不同。

但现在不再是了!

感谢Node,我们现在能够在用户的浏览器需要渲染一件东西之前,在服务器端组装复杂的用户界面。这就是为什么现在Web如此时髦的原因。因为Node已经消除了后端和前端之间的界限。

就这样……JavaScript赢得了后端开发。

游戏开发

Unity 3D

我把这个放到了最后,因为它并不是真正的“Node”,而是JavaScript的东西,我想稍微宽泛一些:

JavaScript的成功不是因为它优于其他语言。它的成功是一个直接的结果,它对几乎每个社区都能够适应。

JavaScript开发者并非纯粹主义者。

我们喜欢我们的语言(不是),版本分散、依赖于转译、跨平台、前沿、不断发展,以及以前没有语言的地方。

就像游戏开发!

当Unity 3D首次推出基于JavaScript的“UnityScript”作为游戏开发工具的时候,我当时就意识到,JavaScript将会做一些非常酷的事情。这是该公司首次进军非Web开发领域。

这是一个明确的迹象,表明JavaScript可以做的不仅仅是打开“飞出”菜单,在页面上调整字体大小。它可以做更多的事情,让你给这篇文章或者一张图片点赞。它可以处理沉浸式的跨平台游戏体验。那些曾经被限制在Chrome、Firefox和Internet Exploder的开发者,突然之间也成了一名游戏开发者。

虽然Unity最近宣布他们将不在支持UnityScript,但我还是要说:

就这样……JavaScript赢得了游戏开发。

好吧,也许不是。

结语

我不知道这个征服会在什么时候停止,但Node正在疯狂爆发。它正在颠覆一个又一个的发展难题,为一个软件开发的世界铺平了道路,在这个世界里,一种语言可以统治所有。我确实觉得我需要重申一下——以防被忽视:

在任何一个领域,JavaScript都不是最佳语言。

JavaScript的优势在于它的多功能性。它来自开放式的社区,它采用了这种无分类、多态的脚本语言,并将其转变为当今最强大的开发生态系统。

如果你有不同的看法,欢迎在留言区互动。

编译组出品。编辑:郝鹏程