Node.js 12:服务端JavaScript的未来
Posted 前端之巅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Node.js 12:服务端JavaScript的未来相关的知识,希望对你有一定的参考价值。
自 2009 年首次发布以来,Node.js 一直是一项改变游戏规则的技术。概括来说,它允许开发人员使用 javascript 在服务端运行脚本,在页面发送到用户的 Web 浏览器之前生成动态 Web 内容。Node.js 是“JavaScript 无处不在”的潮流代表;在这种潮流推动下,服务端和客户端脚本不再需要使用不同的语言编写,开发 Web 应用只用一种编程语言就够了。
如果你像我一样也是 JavaScript 和 Node.js 的粉丝,你会很高兴看到它们正在迎来全方位的改进。
“全方位改进”是什么意思呢?其实就在几个月前,Node.js 12 版刚刚发布了。
2019 年 4 月 23 日 Node.js 12 正式发布,全球各地的 JavaScript 爱好者都欢欣鼓舞。需要明确的是,这不只是一个普通的旧版本更新,而是一个有诸多重要内容更新的关键版本升级。具体升级内容如下。
每次的新版本 JavaScript V8 引擎都会带来一些性能调整和改进,此外这次还有一些非常值得注意的升级。具体有:
零成本异步堆栈跟踪——通过异步调用框架丰富 error.stack 属性,而无需为 V8 引擎添加额外的运行时。
参数不匹配的调用更快——以前 V8 必须用统一的方式处理参数过多或过少的函数调用,造成性能损失。现在引擎变得更聪明了,知道什么时候可以跳过这一步,从而将调用开销减少了 60%。
更快的异步函数和 Promise——实际上现在使用异步要比 Promise 快两个微拍(microtick),因为对 Promise 不熟悉的开发者可以使用语法风格更加同步的 async/await。
更快的 JavaScript 解析——在网页启动时,解析 JS 的耗时只有引擎总耗时的 10%不到。最新发布的 JavaScript 解析器在桌面端的解析速度提高了 30%。
TLS(传输层安全),是 Node 处理加密流通信的方法。
随着 Node.js 12 的发布,TLS 也升级到了 1.3 版;虽然版本号只多了一点,但这次实际上是重大更新,加入了很多性能和安全性增强功能。听起来有些不可思议,但 TLS 1.3 实际上是比 TLS 1.2 更简单的协议,比后者更安全、更易配置,并且可以更快地在应用程序之间协商会话。
Node 应用可以在 TLS 1.3 的帮助下更好地保护终端用户隐私,同时减少 HTTPS 握手所需的时间来提高请求性能。
小结:为所有用户提供更好的安全性并减少服务之间的通信延迟,我认为这是一大进步。
下面来谈一些底层改进。以前,JavaScript 堆大小默认等于浏览器 V8 引擎设置的堆大小上限,前者可以手动调整。Node.js 12 发布开始,JS 堆大小将根据可用内存来自动配置,这样 Node 就不会尝试使用比可用内存更多的内存空间了,避免了耗尽内存导致进程被迫终止的问题。
新版在处理大量数据时不会再出现内存不足错误——以前经常会出现这种问题。需要的话,开发者还可以使用旧的 --max-old-space-size 标志手动设置上限,但新功能出现后手动设置大小的需求应该就没那么多了。
很多人(包括我自己)都不知道,Node 中之前使用的 http_parser 库非常难以维护和改进,这就是 llhttp 诞生的原因。该项目是一个 http_parser 到 TypeScript 的端口,然后通过 llparse 运行以生成 C 或 bitcode 输出。
测试表明 llhttp 比 http_parser 快 156%(https://github.com/nodejs/llhttp#performance);前者的代码量更少,并且所有性能优化都是自动生成的——相比之下 http_parser 需要手动优化代码。
从 Node.js 12 开始,官方决定将默认解析器切换到 llhttp,开始对其进行全面测试。我们希望它在用途各异的众多应用中都能维持出色的性能表现。
谈到调试的话题,Node.js 12 引入了一个新的实验性功能,允许用户根据需要或在发生某些触发事件时生成报告。
这种实时报告可以帮助开发者诊断生产中的问题,包括崩溃、性能下降、内存泄漏、高 CPU 使用率、意外错误等等——这些都是通常需要数小时甚至数天才能调试、诊断和修复的东西。
这个版本中关于堆的另一项特性是 Node.js 12 内置的集成堆转储,它可以加速调试过程。
现在开发者无需安装新模块来调查内存问题——只需通过命令行或 API 调用告诉 Node 你需要哪种 JSON 格式的诊断摘要,然后解析你能处理的所有信息即可。
底层改进说完了。此外,对于 Node 生态系统中的开发人员和模块开发者来说也有一些改进值得一提。
新版进一步完善了为 Node 创建和构建原生模块的流程,包括更好地支持原生模块与 worker 线程的结合,N-API 也升级到了第 4 版,让开发者可以更容易为原生异步函数配置自己的线程。
总的来说,这意味着 Node 专属模块的创建者和维护者可以像纯 JavaScript 模块的创建者一样轻松地维护这些模块。之前维护人员需要为模块支持的所有 Node.js 版本各做一份二进制文件,而新版 N-API 大大简化了这部分工作。
虽然 Node 10 开始就引入了 Worker 线程,但到了 12 版中,启用 Worker 线程不再需要标志——实验阶段快要结束了。在 Node.js 11.7.0 之前,开发者需要在命令行中使用 --experimental-worker 标志启动 node 才能访问 Worker 线程模块。
$ node -e "require('worker_threads'); console.log('success');"
internal/modules/cjs/loader.js:605
throw err;
^
Error: Cannot find module 'worker_threads'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:603:15)
at Function.Module._load (internal/modules/cjs/loader.js:529:25)
at Module.require (internal/modules/cjs/loader.js:657:17)
at require (internal/modules/cjs/helpers.js:22:18)
at [eval]:1:1
at Script.runInThisContext (vm.js:123:20)
at Object.runInThisContext (vm.js:312:38)
at Object. ([eval]-wrapper:6:22)
at Module._compile (internal/modules/cjs/loader.js:721:30)
at evalScript (internal/bootstrap/node.js:720:27)
$
$ node --experimental-worker -e "require('worker_threads'); console.log('success');"
success
$
在执行 CPU 密集型 JavaScript 操作时 Worker 的表现非常出色;但它对 I/O 密集型任务没什么帮助,这种时候 Node 内置的异步 I/O 操作比 Worker 更高效。
Node.js 11 引入了内置的代码缓存支持,将 Worker 线程的启动时间减少了近 60%: https://github.com/nodejs/node/pull/24950
Node 12 在此基础上更进一步,在构建时 提前 为内置库生成代码缓存,允许主线程使用代码缓存来处理用 JavaScript 编写的内置库的初始加载过程。
结果主线程的启动速度又提升了 30%,你的应用为用户加载的速度也能变得更快了: https://github.com/nodejs/node/pull/27161
重头戏留到最后介绍。对我来说最令人兴奋的功能之一是ES6 模块支持——这也是我们很多人一直在等待的东西。这个功能仍然是实验性的,Node 团队正在收集测试反馈。这个功能意味着开发者只要动动手指就能够实现从前端到后端 JavaScript 的无缝过渡。
ES2015 import 语句可以将 Javascript 文件引用为相对链接./examples.js、绝对链接 file:///opt.app/examples.js、包名称 example-package 或包中的路径 example-package/lib/examples.js。
// relative urls
‘./examples.js’
// absolute URLs
‘file:///opt.app/examples.js’
// package names
‘example-package’
// paths within packages
example-package/lib/examples.js
.js 文件中的导入和导出语法现在也都能用了。自 ES6 发布以来,开发人员终于可以像在传统 JS 中那样指定默认导出 import test from './examples'、命名导出 import {example1, example2} from './examples' 和命名空间导出 import * as samples from './examples' 了。
// default imports / exports
import test from ‘./examples’
// named imports / exports
import {example1, example2} from ‘./examples’
// namespace exports
import * as samples from ‘./examples’
将“type”: “module”添加到项目的 package.json 中,且 Node.js 将项目中的所有.js 文件视为 ES 模块。这种方法允许 Node 将 package.json 用于包级元数据和配置,做法类似 Babel 等捆绑和配置工具。
使用.mjs 结尾的文件会被显式视为模块,使用.cjs 结尾的文件会被视为 CommonJS。这些是仍然使用 require 和 module.exports 语法类型的文件。
现在这些功能不再需要标志就能使用,真是太棒了。
最后要谈的是新版 Node 的运行需求变动。
Node.js 12 通过内部改进和 V8 引擎的升级引入了许多新功能,最低运行需求也随之变化。对于 macOS 和 Windows 以外的平台而言,新版代码库现在至少需要 GCC 6 和 glibc 2.17。使用这套新工具链编译的版本会包含编译时性能和安全性增强。
如果你使用的是 Mac 或 Windows 系统应该就没问题了:Windows 系统版本需求没变,Mac 用户至少需要 Xcode 8 和 10.10“Yosemite”系统来运行新版 Node。来自 nodejs.org 的 Linux 兼容版本将支持 Enterprise Linux 7、Debian 8 和 Ubuntu 14.04,但可能需要在原生不支持 GCC 6 的系统上使用自定义工具链。我相信你会很快找出所需要的东西。
Node.js 的历史只有 10 年,现在还是单线程的,也没有像其他一些编程语言那样广泛应用,但 Node 拥有一些其他编程语言难以企及的优势:它是用 JavaScript 构建的 ,并且既可以在客户端也能在服务端运行。
致力于支持和改进 Node 的团队和企业是业界最优秀的。Node 正在持续从核心 JavaScript 和其他语言中学习,挑选合适的部分并吸纳到自身当中,为开发人员和应用程序打造一个不断进步的平台。
Node.js 12 带来了一些非常令人兴奋的改进,例如 ES6 模块支持、更好的应用程序安全性和更快的启动速度等。虽然直到2019 年 10 月它才会进入 LTS(长期支持)模式,但我还是要深入研究这些新功能,看看团队还能想到哪些内容来继续改进这个平台,使其成为更加出色的服务端解决方案。
英文原文: https://blog.logrocket.com/node-js-12/
以上是关于Node.js 12:服务端JavaScript的未来的主要内容,如果未能解决你的问题,请参考以下文章
在Javascript(node.js,express.js,ejs)中访问服务器端变量[关闭]
在 Node.js / 服务器端 javascript 中防止 XSS
在 Node.js / 服务器端 javascript 中使用 .NET DLL
如何使用 node.js 在服务器端使用纯 JavaScript 读取 JSON 文件?
是否可以使用 Node.js 或其他一些服务器端 JavaScript 方法开发 Google App Engine 网络应用程序?