百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术分类 > 正文

Deno: 你并不总是需要NodeJS

ztj100 2024-11-17 18:13 19 浏览 0 评论

作者:binxiong,CSIG云产一研发工作室Tech Lead

回顾Node

包管理复杂

Node包管理很复杂, 包之间又有可能互相依赖, 互相引用. 且存在多个版本安装混乱的问题.

这时候就又需要借助yarn.lock之类的工具进行管理. 并且根据yarn官方文档说明, yarn会忽略依赖包内的yarn.lock, 仅支持top-level的yarn.lock . 所以可能会导致你的node_modules里面充斥着各种版本, 各种重复的包.

权限风险

由于引用的包都已经安装至node_modules, 并且node运行时无法进行任何的权限控制. 导致有可能第三方包在运行的时候, 会有隐私风险. 比如你只是想读取本地的文件, 可是它一边扫描你运行的文件, 一边通过网络请求将你本地的数据抓取上传, 或者修改删除.

require需要处理多种情况

Y 目录下 require(X) 时:

  1. 如果 X 是内置模块,加载该模块;
  2. 如果 X/ 开头,设置 Y 为文件系统的根部 (root);
  3. X./ , / , ../ 开头时,加载该文件或者加载该目录;
  4. 否则加载 node_modules 目录下的模块: LOAD_NODE_MODULES(X, dirname(Y))

用一幅图来开涮一下node_modules

处理逻辑采用回调函数

const fs = require('fs');
fs.readFile('README.md', (err, data) => {
    if (err) { // error handling }
    else { // data handling }
});

总结

  • 不修改npm源的情况下, 为中心化组件库
  • 使用回调进行逻辑处理
  • 无法控制第三方库进行的读取, 网络权限
  • require处理复杂
  • 无法直接运行typescript
  • Version>13.2.0后, 支持ES modules, 之前使用CommonJS

背景介绍

Deno是一个可以运行JavaScript, Typescript的执行环境. 前者能力由V8引擎提供, 后者由Rust语言创造.

因为Rust支持WebAssembly, 所以可以直接使用wasm库和代码

Deno架构

  1. Deno使用Rust启动
  2. 因为V8由C++编写, 所以通过Rust去执行C++代码来初始化V8对象. 这一部分使用Rust FFI调用rusty_v8执行
  3. 这样Deno就可以执行JavaScript代码了
  4. 运行ts的时候, 会通过内置的tsc和swc进行预编译, 并且提供一份缓存.
  5. Tokio提供事件处理

Deno的包管理

提供三种方式引入资源文件

// 从 URL 导入
import XXXX from "https://cdn.bootcdn.net/abc.js";
// 从相对路径导入
import * as Service from "./service.js";
// 从绝对路径导入
import X from "/index.js";

在Node当中的一些引用语法, 在Deno当中并不得到支持

// 模块类的引入方法
import x from "x";
// 不标明根目录的路径
~~import x from "x/index.js";~~  // 通过[import maps](https://deno.land/manual/linking_to_external_code/import_maps)可以解决这样的引用
~~~~// 没有标明文件后缀
import index from "./index";
// import maps来解决相对路径引用问题
{
  "imports": {
    "fmt/": "https://deno.land/std@0.141.0/fmt/"
  }
}

import { red } from "fmt/colors.ts";

console.log(red("hello world"));

deno run --import-map=import_map.json color.ts

Deno的权限控制

  • -allow-env= 允许环境访问,例如读取和设置环境变量。
  • -allow-hrtime 允许高精度时间,高精度时间能够在计时攻击和特征识别中使用。
  • -allow-net= 允许网络访问。您可以指定一系列用逗号分隔的域名,来提供域名白名单。
  • -allow-ffi 允许加载动态的依赖, 注意, 也不在沙箱中运行. 谨慎使用, 并且该API并不稳定.
  • -allow-read= 允许读取文件系统。您可以指定一系列用逗号分隔的目录或文件,来提供文件系统白名单。
  • -allow-run= 允许运行子进程。请注意,子进程不在沙箱中运行,因此没有与 deno 进程相同的安全限制,请谨慎使用。
  • -allow-write= 允许写入文件系统。您可以指定一系列用逗号分隔的目录或文件,来提供文件系统白名单。
  • A, --allow-all 允许所有权限,这将禁用所有安全限制

Deno支持Promise进行逻辑处理

// read-file.ts - Deno
try {
    const data = await Deno.readFile('README.md');
    // Handle the data
} catch (e) {
    // Handle the error
}

从上述代码可以看到. Deno支持 top-level await, 意味着你可以不依赖async function直接使用await语法.

内置命令

  • bundle Bundle module and dependencies into single file
  • cache Cache the dependencies
  • compile UNSTABLE: Compile the script into a self contained executable
  • completions Generate shell completions
  • coverage Print coverage reports
  • doc Show documentation for a module
  • eval Eval script
  • fmt Format source files
  • help Prints this message or the help of the given subcommand(s)
  • info Show info about cache or info related to source file
  • install Install script as an executable
  • lint Lint source files
  • lsp Start the language server
  • repl Read Eval Print Loop
  • run Run a JavaScript or TypeScript program
  • test Run tests
  • types Print runtime TypeScript declarations
  • uninstall Uninstall a script previously installed with deno install
  • upgrade Upgrade deno executable to given version

总结

  • 不断扩充的组件库
  • 原生支持promise进行逻辑处理
  • 原生支持typescript
  • 原生支持ES modules
  • 允许进行文件系统, 网络访问等权限控制, 用来执行沙盒代码
  • 可编译为一个可执行文件
  • 兼容浏览器API, 比如支持window对象

与我们的业务结合

import {
  emptyDir,
  emptyDirSync,
  ensureDirSync,
  ensureFileSync,
} from "https://deno.land/std@0.132.0/fs/mod.ts";

if(!Deno?.args?.[0]) {
  console.error("请输入TED文件目录");
  Deno.exit(1);
}

const tedPath = Deno.args[0]

for await(const f of Deno.readDir(tedPath)) {
  if(f.isFile) continue;
  if(f.name.includes("a-b-c")) {
      for await(const y of Deno.readDir(`${tedPath}/${f.name}`)) {
          if(y.isFile) continue;
          if(y.name.includes("c-d")){
              ensureFileSync(`${tedPath}/${f.name}/${y.name}/TCE/sync.sh`);
              const text = await Deno.readTextFile("./sync.sh");
              const s = await Deno.writeTextFile(`${tedPath}/${f.name}/${y.name}/TCE/sync.sh`, text);
          }
      }
  }
}

deno run --allow-read --allow-write test.ts /path

我们使用了typescript脚本, 进行了ted项目的批量修改.

一些疑问

组件库支持情况?

支持主流库, 如lodash, i18next, billboardjs等, 官方也提供了安装地址, https://deno.land/x

如果贡献, 使用第三方库?

自行开发第三方组件很简单, 只需要上传到托管js的服务器, 或者直接放在github即可. 也可以在官方发布组件.

能否使用node_modues?

不能直接使用node_modules, 但是有一些组件库做了层级适配, 可以间接使用

既然都在使用远程依赖的文件, 如果文件被篡改怎么办? 是否安全?

官方给的解决方案是, 使用cache的lock功能, 将文件锁定deno cache --lock=lock.json --lock-write src/deps.ts

实现一个简单HTTP web server

// handler.ts
export function handler(req: Request): Response {
  return new Response("Hello, World!");
}

// entry.ts

import { handler } from './handler.ts';
import { serve } from "https://deno.land/std@0.141.0/http/server.ts";

serve(handler, { port: 4242 });

deno run --allow-net ./entry.ts

Web框架介绍

在deno中也有对应的web框架, 叫做oak. 使用方法基本上和KOA是一致的, 官网文档也说明了, 是受到KOA启发而做的.

import { Application } from "https://deno.land/x/oak/mod.ts";

const app = new Application();

// Logger
app.use(async (ctx, next) => {
  await next();
  const rt = ctx.response.headers.get("X-Response-Time");
  console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`);
});

// Timing
app.use(async (ctx, next) => {
  const start = Date.now();
  await next();
  const ms = Date.now() - start;
  ctx.response.headers.set("X-Response-Time", `${ms}ms`);
});

// Hello World!
app.use((ctx) => {
  ctx.response.body = "Hello World!";
});

await app.listen({ port: 8000 });

进行react渲染

Deno默认支持jsx, tsx的语法, 使用它就可以创建一个基于Deno的react app了.

它采用了和npm方式完全不同的模块管理.

可以从它的模板依赖代码看到, 它完全采用的是远程的代码.

import { serve } from "https://deno.land/std@0.140.0/http/server.ts";import { h, ssr, tw } from "https://crux.land/nanossr@0.0.1";const Hello = (props) => (  <div class={tw`bg-white flex h-screen`}>    <h1 class={tw`text-5xl text-gray-600 m-auto mt-20`}>      Hello {props.name}!    </h1>  </div>);await serve((req) => {  const url = new URL(req.url);  const name = url.searchParams.get("name") ?? "world";  return ssr(() => <Hello name={name} />);});

总结

受限文章长度, deno的事件处理, 在rust当中也可以作为独立的应用使用, 以及如何和wasm结合使用都没有展开来说.

简单来说, deno是一个轻量, 自由的库. 我总结的适用场景可以是, 1. 脚本文件, 2. 做一个 data mock server, 3. 前端的监控或者是自动化测试脚本编写工具.

当然作为一个还在不断发展的库, deno还有更多的可能性, 我这里只是总结了几种场景.

相关推荐

Whoosh,纯python编写轻量级搜索工具

引言在许多应用程序中,搜索功能是至关重要的。Whoosh是一个纯Python编写的轻量级搜索引擎库,可以帮助我们快速构建搜索功能。无论是在网站、博客还是本地应用程序中,Whoosh都能提供高效的全文搜...

如何用Python实现二分搜索算法(python二分法查找代码)

如何用Python实现二分搜索算法二分搜索(BinarySearch)是一种高效的查找算法,适用于在有序数组中快速定位目标值。其核心思想是通过不断缩小搜索范围,每次将问题规模减半,时间复杂度为(O...

路径扫描 -- dirsearch(路径查找器怎么使用)

外表干净是尊重别人,内心干净是尊重自己,干净,在今天这个时代,应该是一种极高的赞美和珍贵。。。----网易云热评一、软件介绍Dirsearch是一种命令行工具,可以强制获取web服务器中的目录和文件...

78行Python代码帮你复现微信撤回消息!

来源:悟空智能科技本文约700字,建议阅读5分钟。本文基于python的微信开源库itchat,教你如何收集私聊撤回的信息。...

从零开始学习 Python!2《进阶知识》 Python进阶之路

欢迎来到Python学习的进阶篇章!如果你说已经掌握了基础语法,那么这篇就是你开启高手之路的大门。我们将一起探讨面向对象编程...

白帽黑客如何通过dirsearch脚本工具扫描和收集网站敏感文件

一、背景介绍...

Python之txt数据预定替换word预定义定位标记生成word报告(四)

续接Python之txt数据预定替换word预定义定位标记生成word报告(一)https://mp.toutiao.com/profile_v4/graphic/preview?pgc_id=748...

假期苦短,我用Python!这有个自动回复拜年信息的小程序

...

Python——字符串和正则表达式中的反斜杠(&#39;\&#39;)问题详解

在本篇文章里小编给大家整理的是关于Python字符串和正则表达式中的反斜杠('\')问题以及相关知识点,有需要的朋友们可以学习下。在Python普通字符串中在Python中,我们用'\'来转义某些普通...

Python re模块:正则表达式综合指南

Python...

Python中re模块详解(rem python)

在《...

python之re模块(python re模块sub)

re模块一.re模块的介绍1.什么是正则表达式"定义:正则表达式是一种对字符和特殊字符操作的一种逻辑公式,从特定的字符中,用正则表达字符来过滤的逻辑。(也是一种文本模式;)2、正则表达式可以帮助我们...

MySQL、PostgreSQL、SQL Server 数据库导入导出实操全解

在数字化时代,数据是关键资产,数据库的导入导出操作则是连接数据与应用场景的桥梁。以下是常见数据库导入导出的实用方法及代码,包含更多细节和特殊情况处理,助你应对各种实际场景。一、MySQL数据库...

Zabbix监控系统系列之六:监控 mysql

zabbix监控mysql1、监控规划在创建监控项之前要尽量考虑清楚要监控什么,怎么监控,监控数据如何存储,监控数据如何展现,如何处理报警等。要进行监控的系统规划需要对Zabbix很了解,这里只是...

mysql系列之一文详解Navicat工具的使用(二)

本章内容是系列内容的第二部分,主要介绍Navicat工具的使用。若查看第一部分请见:...

取消回复欢迎 发表评论: