前端全栈之路Deno篇(二):几行代码打包后接近100M?别慌,带你掌握Deno2.0的安装到项目构建全流程、剖析构建物并了解其好处

简介: 在使用 Deno 构建项目时,生成的可执行文件体积较大,通常接近 100 MB,而 Node.js 构建的项目体积则要小得多。这是由于 Deno 包含了完整的 V8 引擎和运行时,使其能够在目标设备上独立运行,无需额外安装依赖。尽管体积较大,但 Deno 提供了更好的安全性和部署便利性。通过裁剪功能、使用压缩工具等方法,可以优化可执行文件的体积。

在使用 Deno 进行构建时,发现生成的可执行文件体积较大。相比之下,使用 Node.js 构建的项目通常非常小,尤其是在不安装依赖包的情况下,体积通常不到 1MB。然而,Windows 下 Deno 生成的可执行文件体积接近 100 MB,这让我不禁思考:为什么 Deno 打包的产物会如此庞大?是否有可以优化的空间?这种情况让我开始深入研究Deno 的打包方式及其内部结构,希望能够找到一些优化策略或者理解它如此设计的原因。

最后你会发现,这100M包含了所有的资源以及运行时,再也不需要在部署设备安装nodejs或者docker啦

推荐前置阅读: Deno2.0与Bun对比,谁更胜一筹?可能Deno目前更适合serverless业务

Deno 安装

Windows

使用 PowerShell:

irm https://deno.land/install.ps1 | iex

Linux

curl -fsSL https://deno.land/install.sh | sh

更多安装方式请参考 Deno 安装文档

创建项目

  1. 创建一个干净的 📁 目录(可选)。
  2. 在目录中创建一个 test.js 文件。
  3. 编写以下代码,例如:
// 一个简单的应用代码,每隔10秒更新目录下一个文件内的时间戳数据,包含时间读取和文件操作权限
const filePath = `${
     Deno.cwd()}/timestamp`;

async function updateTimestamp() {
   
  while (true) {
   
    const timestamp = new Date().toISOString();
    try {
   
      await Deno.writeTextFile(filePath, timestamp);
      console.log(`Timestamp updated: ${
     timestamp}`);
    } catch (err) {
   
      console.error(`Failed to update timestamp: ${
     err}`);
    }
    await new Promise(resolve => setTimeout(resolve, 10000)); 
  }
}

updateTimestamp();

构建可执行文件

使用 deno compile 命令进行构建:

deno compile --output test ./test.js

在 Windows 下会生成 test.exe

运行可执行文件

方式一:双击执行文件

可以通过双击来运行生成的 test.exe 文件。由于示例代码会持续运行进程,因此可以看到命令窗口。如果是非持续运行的程序,可能只会闪一下。

运行过程中会请求权限:
权限提示

输入 y 允许权限请求后:
在这里插入图片描述
在这里插入图片描述

方式二:命令行授权运行

可以通过命令行一次性授权并运行:

.\test.exe --allow-all

构建物分析

构建物的组成

将生成的 test.exe 文件解压后可以看到它的组成部分:
解压 exe

可以看到两个主要部分:.text (49 MB) 和 .rdata (29 MB),它们占据了可执行文件的大部分空间。

深入分析

Deno 打包后的可执行文件之所以如此庞大,是因为它包含了以下部分:

  1. V8 引擎:Deno 基于 V8 引擎来执行 JavaScript 代码,因此 V8 作为 Deno 运行时的一部分被打包在可执行文件中。
  2. Deno 运行时: Deno 运行时自身也包含了许多功能,如权限管理、模块加载等。这些功能都需要包含在打包的可执行文件中,以确保应用在不同环境中正常运行。

为什么如此设计?

Deno 的设计理念之一是让构建后的可执行文件能够在目标设备上独立运行,无需再额外安装Deno 或其他依赖。这种 "一次构建,到处运行" 的模式使得可执行文件在部署时更加方便,但同时也增加了文件的体积。相比于传统的 Node.js 应用, Deno 将运行时和引擎都集成到可执行文件中,因此文件体积较大。

与 Node.js、Bun 以及 Docker+Node.js 部署的对比

在构建和部署 JavaScript 应用程序时, Deno、Node.js、Bun 以及使用 Docker 打包的 Node.js 应用都有各自的优缺点。下面我们来对比这些不同的工具和方法。

1. Node.js

Node.js 是最广泛使用的 JavaScript 运行时,它依赖于 V8 引擎来执行 JavaScript 代码。使用 Node.js 部署应用程序通常需要先安装 Node.js 环境,然后通过 npm 或 yarn 安装项目的依赖项。Node.js 的优势在于其成熟的生态系统和广泛的社区支持。

然而,Node.js 应用程序部署时需要依赖环境,这意味着必须在目标服务器上安装 Node.js,或者通过容器化的方式来确保环境一致性。此外,Node.js 本身并不直接支持将应用程序打包为单个可执行文件,因此需要其他工具(如 pkg)来实现类似的效果。

2. Bun

Bun 是一种新兴的 JavaScript 运行时,旨在提供比 Node.js 更快的执行速度和更简单的开发体验。Bun 集成了包管理器 📦、JavaScript 运行时和捆绑工具,旨在简化整个开发流程。与 Node.js 相比,Bun 的包管理速度更快,且在性能上进行了优化。

不过,Bun 目前仍在快速发展中,生态系统相对较小,还没有 Node.js 那样广泛的第三方库支持。此外,Bun 的稳定性和兼容性在某些场景下可能还需要进一步验证。

3. Deno

Deno 的主要特点在于安全性和自包含的可执行文件。与 Node.js 不同, Deno 默认禁止网络、文件系统等敏感操作,除非明确授权,这种权限管理的机制使得应用程序更加安全。此外,Deno 可以将应用程序编译为单个自包含的可执行文件,这在部署时非常方便,无需在目标服务器上安装 Deno 运行时。

然而,正因为 Deno 将运行时和 V8 引擎都打包在可执行文件中,导致生成的文件体积非常大。对于一些对文件体积敏感的场景, Deno 的这种设计可能不是最优选择。

4. Docker + Node.js

使用Docker 容器来部署 Node.js 应用是一种非常流行的方法,尤其是在需要环境隔离和一致性的时候。通过 Docker,可以将应用程序及其所有依赖打包在一个容器中,确保在任何支持Docker 的平台上都可以一致地运行。

使用 Docker 部署的优势在于环境的隔离和可移植性,开发者可以确保在本地测试的应用在生产环境中具有相同的依赖和配置。然而,Docker 容器的镜像体积相对较大,这取决于所使用的基础镜像和应用程序的依赖项。此外,使用Docker 还需要一定的运维技能来管理容器的生命周期。

总结对比

  • Node.js:适合需要广泛生态支持的应用,部署时需要环境依赖。
  • Bun:更快的包管理和执行速度,但生态系统还不成熟。
  • Deno:提供安全性和自包含的可执行文件,部署简单,但文件体积较大。
  • Docker + Node.js:提供环境一致性和隔离,适合复杂的生产环境,但镜像体积较大。

根据具体的应用场景和需求,开发者可以选择最适合的工具和方法来进行部署。

可优化的方向

虽然Deno 的可执行文件包含了完整的运行时和引擎,使其体积庞大,但我们可以考虑以下优化方向:

  1. 裁剪功能:如果应用不需要某些运行时功能,可以探索是否有办法裁剪掉不必要的部分,减少最终可执行文件的体积。
  2. 压缩工具:使用压缩工具如 UPX 对生成的可执行文件进行压缩,可以有效减小文件体积。
  3. 模块化设计:在开发时尽可能减少使用第三方库和不必要的模块,保持代码精简,从源头上控制构建物的大小。

结论

Deno 打包的可执行文件体积较大是其设计使然,目的是为了在不同环境中实现独立运行和无依赖的便利性。虽然它的文件体积相比传统 Node.js 应用较大,但可以通过裁剪功能、压缩工具等方式进行一定程度的优化,以适应不同的应用场景需求。

构建成可执行文件后,你的后端应用就可以在没有运行时的设备允许了,尤其是ecs、轻量应用服务器,实现一键部署~

相关文章
|
18天前
|
Cloud Native 前端开发 JavaScript
前端开发者必看:不懂云原生你就OUT了!揭秘如何用云原生技术提升项目部署与全栈能力
【10月更文挑战第23天】随着云计算的发展,云原生逐渐成为技术热点。前端开发者了解云原生有助于提升部署与运维效率、实现微服务化、掌握全栈开发能力和利用丰富技术生态。本文通过示例代码介绍云原生在前端项目中的应用,帮助开发者更好地理解其重要性。
51 0
|
4天前
|
前端开发 JavaScript
前端界的革命:掌握这些新技术,让你的代码简洁到让人惊叹!
前端技术的快速发展带来了许多令人惊叹的新特性。ES6及其后续版本引入了箭头函数、模板字符串等简洁语法,极大减少了代码冗余。React通过虚拟DOM和组件化思想,提高了代码的可维护性和效率。Webpack等构建工具通过模块化和代码分割,优化了应用性能和加载速度。这些新技术正引领前端开发的革命,使代码更加简洁、高效、可维护。
9 2
|
4天前
|
前端开发 JavaScript 测试技术
前端工程师的必修课:如何写出优雅、可维护的代码?
前端工程作为数字世界的门面,编写优雅、可维护的代码至关重要。本文从命名规范、模块化设计、注释与文档、遵循最佳实践四个方面,提供了提升代码质量的方法。通过清晰的命名、合理的模块划分、详细的注释和持续的学习,前端工程师可以写出高效且易于维护的代码,为项目的成功打下坚实基础。
11 2
|
10天前
|
监控 前端开发 JavaScript
探索微前端架构:构建可扩展的现代Web应用
【10月更文挑战第29天】本文探讨了微前端架构的核心概念、优势及实施策略,通过将大型前端应用拆分为多个独立的微应用,提高开发效率、增强可维护性,并支持灵活的技术选型。实际案例包括Spotify和Zalando的成功应用。
|
9天前
|
监控 前端开发 JavaScript
前端开发的终极奥义:如何让你的代码既快又美,还不易出错?
【10月更文挑战第31天】前端开发是一个充满挑战与机遇的领域,本文从性能优化、代码美化和错误处理三个方面,探讨了如何提升代码的效率、可读性和健壮性。通过减少DOM操作、懒加载、使用Web Workers等方法提升性能;遵循命名规范、保持一致的缩进与空行、添加注释与文档,让代码更易读;通过输入验证、try-catch捕获异常、日志与监控,增强代码的健壮性。追求代码的“快、美、稳”,是每个前端开发者的目标。
23 3
|
11天前
|
前端开发 JavaScript 开发者
前端开发的终极技巧:如何让你的代码既简洁又高效,还能减少bug?
【10月更文挑战第30天】前端开发充满挑战与创新,如何编写简洁高效且少bug的代码是开发者关注的重点。本文介绍五大技巧:1. 模块化,提高代码复用性;2. 组件化,降低代码耦合度;3. 使用现代框架,提高开发效率;4. 统一代码规范,降低沟通成本;5. 利用工具,优化代码质量。掌握这些技巧,让前端开发更高效。
23 1
|
15天前
|
前端开发 JavaScript API
前端框架新探索:Svelte在构建高性能Web应用中的优势
【10月更文挑战第26天】近年来,前端技术飞速发展,Svelte凭借独特的编译时优化和简洁的API设计,成为构建高性能Web应用的优选。本文介绍Svelte的特点和优势,包括编译而非虚拟DOM、组件化开发、状态管理及响应式更新机制,并通过示例代码展示其使用方法。
32 2
|
21天前
|
JavaScript 前端开发 测试技术
前端全栈之路Deno篇(五):如何快速创建 WebSocket 服务端应用 + 客户端应用 - 可能是2025最佳的Websocket全栈实时应用框架
本文介绍了如何使用Deno 2.0快速构建WebSocket全栈应用,包括服务端和客户端的创建。通过一个简单的代码示例,展示了Deno在WebSocket实现中的便捷与强大,无需额外依赖,即可轻松搭建具备基本功能的WebSocket应用。Deno 2.0被认为是最佳的WebSocket全栈应用JS运行时,适合全栈开发者学习和使用。
|
16天前
|
前端开发 API UED
深入理解微前端架构:构建灵活、高效的前端应用
【10月更文挑战第23天】微前端架构是一种将前端应用分解为多个小型、独立、可复用的服务的方法。每个服务独立开发和部署,但共同提供一致的用户体验。本文探讨了微前端架构的核心概念、优势及实施方法,包括定义服务边界、建立通信机制、共享UI组件库和版本控制等。通过实际案例和职业心得,帮助读者更好地理解和应用微前端架构。
|
18天前
|
前端开发 JavaScript 开发者
揭秘前端高手的秘密武器:深度解析递归组件与动态组件的奥妙,让你代码效率翻倍!
【10月更文挑战第23天】在Web开发中,组件化已成为主流。本文深入探讨了递归组件与动态组件的概念、应用及实现方式。递归组件通过在组件内部调用自身,适用于处理层级结构数据,如菜单和树形控件。动态组件则根据数据变化动态切换组件显示,适用于不同业务逻辑下的组件展示。通过示例,展示了这两种组件的实现方法及其在实际开发中的应用价值。
25 1