Поговорим о Дено.

внешний интерфейс deno
Поговорим о Дено.

Это 99-я оригинальная статья без воды.Если вы хотите получить больше оригинальных статей, выполните поиск в общедоступном аккаунте и подпишитесь на нас~ Эта статья была впервые опубликована в блоге Zhengcaiyun:Поговорим о Дено.

七彩.png

Что такое дено

deno1

Deno — это простой, современный, безопасныйJavaScript,TypeScript,Webassemblyсреда выполнения.

Deno — это анаграмма от Node, а его произношение — аббревиатура «Tino» от слова «динозавр» (динозавр).

Он построен на:

  • Rust(Нижний слой Deno разработан на Rust, а Node — на C++)
  • Tokio(Механизм событий Deno основан на Tokio, а узел основан на Libuv)
  • TypeScript
  • V8

История Дено

deno演讲.png

Deno произошел от создателя NodeRyan Dahl, что является одной из причин, почему все с нетерпением ждут проекта Deno. В JSConfEu,Dahlв егоречьОн рассказал о некоторых недостатках Node и объяснил, как принимать лучшие решения в отношении архитектуры Node.В конце выступления он объявил о первом прототипе Deno и пообещал создать лучшую и более безопасную среду выполнения.

Недостатки узла

В нативном API отсутствуют промисы

Самая большая особенность Node — управляемая событиями неблокирующая модель ввода-вывода, благодаря которой Node обладает мощными возможностями параллельной обработки и очень подходит для написания сетевых приложений. Большинство операций ввода-вывода в Node практически асинхронны, поэтому генерируется Callback Hell:

// fs.js
const fs = require('fs');
const myFile = '/tmp/test';

fs.readFile(myFile, 'utf8', (err, txt) => {
  if (!err) {
    fs.writeFile(myFile);
  }
});

Чтобы реализовать цепочку, вам нужно переупаковать нативный API с помощью Promise следующим образом:

const fs = require("fs");
const myFile = '/tmp/test';

function readFile_promise(path) {
  return new Promise((resolve, reject) => {
    fs.readfile(path, "utf-8", (err, data) => {
      if (err) {
        reject(err);
      } else {
        resolve(data);
      }
    })
  });
}

readFile_promise(myFile)
  .then((res) => {
    fs.writeFile(myFile, res);
  })

отсутствие безопасности

В Node вы можете вызвать fs.chmod для изменения разрешений на чтение и запись файла или каталога. Обратите внимание, что разрешения среды выполнения Node очень высоки. Если вы импортируете ненадежный пакет в Node, скорее всего, он удалит все файлы на вашем компьютере, поэтому в Node отсутствует безопасная модульная среда выполнения. Если среда песочницы не предоставляется вручную, контейнерная среда, такая как Docker, решает проблемы безопасности.

const fs = require('fs');
//删除hello.txt
fs.unlinkSync('./hello.txt');
// 删除css文件夹
fs.rmdirSync('./css');

Отличия системы сборки от Chrome

v8编译.png

Для начала нам нужно понять, что такое система сборки?

Дети, привыкшие писать ботинок фронтенда, могут не понять, для чего эта штука? Но на самом деле вы всегда будете с ним соприкасаться, но концепция другая. Что касается внешнего интерфейса, мы обычно называем это упакованной сборкой, аналогично тому, что делают такие инструменты, как веб-пакет, накопительный пакет и пакет. Их конечная цель на самом деле состоит в том, чтобы получить несколько целевых файлов, здесь наша цельСкомпилировать V8код.

Система сборки Node V8GYP(Создавайте свои проекты), а Chrome V8 был обновлен доGN(Создать ниндзя). Мы знаем, что V8 разработан Google, что также доказывает, что Node и собственный сын Google Chrome отдаляются друг от друга, а GN строится в 20 раз быстрее, чем GYP, потому что GN написан на C++, который во многом быстрее, чем GYP, написанный на python. Но базовая архитектура Node непоправима.

Сложные шаблоны управления пакетами

deno模块太阳.png

В экосистеме NPM, которая поставляется с Node, из-за ее сильной зависимости от семантического управления версиями и сложных графов зависимостей необходимо иметь дело с package.json и node_modules. Хотя дизайн node_modules может соответствовать большинству сценариев, он все еще имеет различные дефекты, особенно в области фронтенд-инжиниринга, что вызвало множество проблем. Особенно, когда разные версии зависимостей пакетов несовместимы, следуют различные проблемы, поэтому на сцену выходят yarn lock и npm lock.

Тем не менее, есть еще много сценариев, которые не могут быть покрыты блокировкой, например, когда мы устанавливаем зависимость в первый раз, даже если сторонняя библиотека содержит файл блокировки, npm install | и yarn install не будет читать третий -партийная библиотека Зависимые блокировки, которые могут вызывать ошибки при первом создании проекта. Более того, из-за кросс-зависимости node_modules переполнен различными дублированными версиями пакетов, что приводит к огромной трате места, а также к медленной установке зависимых пакетов, и требует все более сложных алгоритмов чтения файлов.

Чтение файлов затруднено

Узел используетrequireЧто касается других файлов сценариев, внутренняя логика выглядит следующим образом:

当 Node 遇到 require(X) 时,按下面的顺序处理。
(1)如果 X 是内置模块(比如 require('http'))
  a. 返回该模块。
  b. 不再继续执行。

(2)如果 X 以 "./" 或者 "/" 或者 "../" 开头
  a. 根据 X 所在的父模块,确定 X 的绝对路径。
  b. 将 X 当成文件,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
      X
      X.js
      X.json
      X.node
  c. 将 X 当成目录,依次查找下面文件,只要其中有一个存在,就返回该文件,不再继续执行。
      X/package.json(main字段)
      X/index.js
      X/index.json
      X/index.node
      
(3)如果 X 不带路径
  a. 根据 X 所在的父模块,确定 X 可能的安装目录。
  b. 依次在每个目录中,将 X 当成文件名或目录名加载。

(4) 抛出 "not found"

Видно, что логика чтения запроса очень сложна, хотя пользоваться им приятно, но не обязательно.

Архитектура Дено

deno源码.png

  1. Deno использует Rust в качестве начальной записи, выполняет код C++ через Rust FFI, а затем вводит экземпляры V8 в C++.

  2. Инициализировать объекты V8 и внедрить внешние методы C++, такие как send, recv и т. д.

  3. Внедрите объекты Deno в глобальную область видимости V8, чтобы открыть некоторые базовые API Deno для JavaScript.

  4. Через метод C++, связанный с V8, вызывается соответствующий метод Rust для выполнения базовой логики.

Нетрудно обнаружить, что Deno на самом деле похож на фреймворки RN и Flutter, потому что по сути он также запускает движок JS, но этот движок JS — V8 и не отвечает за привязку пользовательского интерфейса. Поэтому суть архитектуры — воспроизведение идей и реорганизация модулей.

Особенности Дено

Безопасность

deno-sec.png

В отличие от Node, Deno по умолчанию выполняет код в песочнице, что означает, что среда выполнения не имеет доступа к следующим разрешениям:

  • Файловая система
  • Интернет
  • переменная среды

Вы можете включить разрешения, которые отключены по умолчанию, в качестве аргументов командной строки, например:

// 授予从磁盘读取和侦听网络的权限
deno run --allow-read --allow-net https://deno.land/std/http/file_server.ts

// 授予从磁盘filepath读取白名单文件的权限
deno run --allow-read=/etc https://deno.land/std/http/file_server.ts

// 授予所有权限
deno run --allow-all https://deno.land/std/http/file_server.ts

Или программно управлять разрешениями, например:

// 检测是否有读取权限
const status = await Deno.permissions.query({ name: "write" });
if (status.state !== "granted") {
  throw new Error("need write permission");
}

// 读取log文件
const log = await Deno.open("request.log", "a+");

// 关闭读写权限
await Deno.permissions.revoke({ name: "read" });
await Deno.permissions.revoke({ name: "write" });

// 打印log内容
const encoder = new TextEncoder();
await log.write(encoder.encode("hello\n"));

Встроенные инструменты

deno恐龙标志

В настоящее время Deno предоставляет следующие встроенные инструменты, которые очень полезны при работе с JavaScript и TypeScript. Просто выполните следующую команду:

  • deno bundler(Он поставляется с функциями упаковки и встряхивания дерева, которые могут упаковать наш код в один файл)
  • deno compile(Создайте проект Deno как полностью автономный исполняемый файл)
  • deno installe(Мы можем использовать наш код для создания исполняемых файлов для прямого использования)
  • deno info(см. дерево зависимостей для всех модулей)
  • deno doc(генерирует документацию из комментариев в исходном коде)
  • deno fmt(рекурсивно форматировать каждый файл в каждом подкаталоге)
  • deno repl(запускает цикл чтения-оценки-печати, который позволяет интерактивно создавать состояние программы в глобальном контексте)
  • deno test(модульное тестирование файла с именем .test )
  • deno lint(детектор кода)

Поддержка TypeScript

tsbanner.jpeg

Запуск кода TypeScript с помощью Deno не требует этапа компиляции и громоздких файлов конфигурации — Deno делает это за вас автоматически.

исходный кодМы обнаружили, что Deno на самом деле интегрирует компилятор TypeScript и небольшой узел компилятора для моментальных снимков времени выполнения. преобразованныйосновной кодследующим образом:

// globalThis.exec 这个函数在/cli/tsc/99_main_compiler.js中
// 其主要作用就是把TypeScript转换成JavaScript
let exec_source = format!("globalThis.exec({})", request_str);

  runtime
    .execute("[native code]", startup_source)
    .context("Could not properly start the compiler runtime.")?;
  runtime.execute("[native_code]", &exec_source)?;

Некоторое время назад обсуждение смены TS обратно на JS в Deno было очень оживленным, но это не значит, что Deno отказался от TypeScript, это по-прежнему безопасная среда выполнения TS/JS.

Например:

// index.ts
const str: string = 'hello word';
console.log(str);

Вы можете запустить его прямо из командной строки и вывести приветственное слово:

deno run index.ts

Поддерживает стандарт модуля ES

Deno использует браузерную реализацию модуля ES.ES ModuleС ней должен быть знаком каждый.Это официальная стандартизированная модульная система JavaScript, и ее реализация в браузере выглядит следующим образом:

// 从 URL 导入import React from "https://cdn.bootcdn.net/ajax/libs/react/17.0.1/cjs/react-jsx-dev-runtime.development.js";// 从相对路径导入import * as Api from "./service.js";// 从绝对路径导入import "/index.js";

Следует отметить, что Deno не поддерживает следующие обозначения:

import foo from "foo.js";import bar from "bar/index.js";import zoo from "./index"; // 没有后缀

Совместимый API браузера

chromebanner.png

Deno снижает осведомленность, согласовываясь с API-интерфейсами браузера.

  • Модульная система: Из вышеприведенного введения видно, что Deno полностью реализуется браузером.
  • Безопасно по умолчанию
  • Возвращает обещания для асинхронных операций
  • Использовать бинарный дескриптор ArrayBuffer
  • Есть глобальная переменная окна
  • Поддерживает веб-стандарты, такие как выборка, webCrypto, worker и т. д., а также поддерживает функции обработки событий, такие как onload, onunload, addEventListener и т. д.
console.log(window === this, window === self, window === globalThis); // true true true

Обещает поддержку

promisebanner.png

Все асинхронные операции в Deno всегда возвращают Promise, а await поддерживается глобально.

// 读取异步接口数据const response = await fetch("http://my.json.host/data.json");console.log(response.status)console.log(response.statusText);const jsonData = await response.json();// 读取文件const decoder = new TextDecoder("utf-8");const data = await Deno.readFile("hello.txt");console.log(decoder.decode(data));

Децентрализованный пакет

У Deno нет package.json, node_modules, так как же он управляет пакетами? Давайте посмотрим на следующий пример:

// index.jsimport { white, bgRed } from "https://deno.land/std/fmt/colors.ts";console.log(bgRed(white("hello world!")));// 命令行执行> deno run index.jsDownload https://deno.land/std/fmt/colors.tsCompile https://deno.land/std/fmt/colors.tshello world!

Мы видим, что при выполнении будетDownloadа такжеCompileДва шага, поэтому у нас будет несколько вопросов:

1. Вам нужно загружать его каждый раз, когда вы его запускаете?

О: Не нужно каждый раз качать, есть механизм кеширования.

> deno run index.jshello world!

2. Где находятся файлы загрузки и компиляции?

A: Мы можем просматривать зависимости с помощью встроенного инструмента deno info, описанного выше.

> deno info index.jslocal: /Users/xxx/Desktop/index.tstype: TypeScriptemit: /Users/xxx/Library/Caches/deno/gen/file/Users/xxx/Desktop/index.ts.jsdependencies: 0 unique (total 41B)file:///Users/xxx/Desktop/index.ts (41B)

3. Что делать, если зависимый код обновился?

A: Когда модуль зависимостей будет обновлен, мы можем передать--reloadЧтобы обновить кеш, например:

> deno run --reload index.js// 通过白名单的方式更新部分依赖> deno run --reload=https://deno.land index.js

4. Как быть с несколькими версиями?

Ответ: На данный момент хорошего решения нет, различать версии можно только по тегу git.

Deno импортирует код через URL-адрес и может размещать модули в любом месте в Интернете. И по сравнению с Node, требующим чтения файлов, он более легкий и компактный и может распространять пакеты Deno без централизованного реестра. Нет необходимости в файле package.json и списке зависимостей, так как все модули загружаются, компилируются и кэшируются при запуске приложения.

Начало работы с Дено

Установить

Использование Shell (macOS и Linux):

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

Использование PowerShell (Windows):

iwr https://deno.land/x/install/install.ps1 -useb | iex

бегатьdeno --version, если он выводит версию Deno, установка прошла успешно.

> deno --versiondeno 1.8.1 (release, aarch64-apple-darwin)v8 9.0.257.3typescript 4.2.2

реальный боевой опыт

deno-getting-started.jpeg

Hello Word

Создайте локально файл index.ts со следующим содержимым:

// index.tsconsole.log("Welcome to Deno 🦕");

Откройте терминал и введите следующую командную строку:

> deno run index.ts

Приведенный выше вывод «Добро пожаловать в Deno 🦕».

HTTP-запрос

Создайте локально файл http.ts со следующим содержимым:

const url = Deno.args[0]; // 取得第一个命令行参数,存储到变量 url。const res = await fetch(url); // 向指定的地址发出请求,等待响应,然后存储到变量 res。const body = new Uint8Array(await res.arrayBuffer()); // 把响应体解析为一个 ArrayBuffer,等待接收完毕,将其转换为 Uint8Array,最后存储到变量 body。await Deno.stdout.write(body); // 把 body 的内容写入标准输出流 stdout。

Откройте терминал и введите следующую командную строку:

deno run --allow-net=api.github.com http.ts https://api.github.com/users/answer518

Приведенное выше выводит объект json.

Удаленный импорт

Импорт из удаленного модуляaddа такжеmultiplyметод:

import {  add,  multiply,} from "https://x.nest.land/ramda@0.27.0/source/index.js";function totalCost(outbound: number, inbound: number, tax: number): number {  return multiply(add(outbound, inbound), tax);}console.log(totalCost(19, 31, 1.2)); // 60console.log(totalCost(45, 27, 1.15)); // 82.8

Поддержка WASM

// wasm.tsconst wasmCode = new Uint8Array([  0, 97, 115, 109, 1, 0, 0, 0, 1, 133, 128, 128, 128, 0, 1, 96, 0, 1, 127,  3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0,  5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 145,  128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 4, 109, 97,  105, 110, 0, 0, 10, 138, 128, 128, 128, 0, 1, 132, 128, 128, 128, 0, 0,  65, 42, 11]);const wasmModule = new WebAssembly.Module(wasmCode);const wasmInstance = new WebAssembly.Instance(wasmModule);const main = wasmInstance.exports.main as CallableFunction;console.log(main().toString());

Откройте терминал и введите следующую командную строку:

> deno run wasm.ts

Выше выводится число 42.

REST-сервис

// restful.tsimport { Application, Router } from "https://deno.land/x/oak/mod.ts";const books = new Map<string, any>();books.set("1", {  id: "1",  title: "平凡的世界",  author: "路遥",});const router = new Router();router  .get("/", (context) => {    context.response.body = "Hello world!";  })  .get("/book", (context) => {    context.response.body = Array.from(books.values());  })  .get("/book/:id", (context) => {    if (context.params && context.params.id && books.has(context.params.id)) {      context.response.body = books.get(context.params.id);    }  });const app = new Application();app.use(router.routes());app.use(router.allowedMethods());await app.listen({ hostname: '127.0.0.1', port: 8000 });

Введите в терминал следующую команду:

> deno run  --allow-net restful.ts

локальный доступhttp://localhost:8000/book/1вернет данные книги с идентификатором 1.

служба статических ресурсов

// static.tsimport { Application } from "https://deno.land/x/oak/mod.ts";const app = new Application();app.use(async (context) => {  await context.send({    root: Deno.cwd(), // 静态资源的根路径  });});await app.listen({ hostname: "127.0.0.1", port: 8000 });

Введите в терминал следующую команду:

> deno run  --allow-net --allow-read static.ts

локальный доступhttp://localhost:8000/static.tsвернет исходный код static.ts.

заключительные замечания

Deno действительно отличный проект, но это не«Node.js следующего поколения». Сам Райан Даль сказал:«Node.js никуда не денется». А Deno все еще находится в стадии разработки, и его функции нестабильны, поэтому его не рекомендуется использовать в производственных средах. Тем не менее, это уже полезный инструмент, и есть много новых функций, которых нет в Node, вы можете попробовать его.

Рекомендуемое чтение

SpreadJS для исследования визуализации данных

Схема кэширования списка страниц H5

Карьера

ZooTeam, молодая, увлеченная и творческая команда, связанная с отделом исследований и разработок продукции Zhengcaiyun, базируется в живописном Ханчжоу. В настоящее время в команде более 40 фронтенд-партнеров, средний возраст которых составляет 27 лет, и почти 30% из них — инженеры полного стека, настоящая молодежная штурмовая группа. В состав членов входят «ветераны» солдат из Ali и NetEase, а также первокурсники из Чжэцзянского университета, Университета науки и технологий Китая, Университета Хандянь и других школ. В дополнение к ежедневным деловым связям, команда также проводит технические исследования и фактические боевые действия в области системы материалов, инженерной платформы, строительной платформы, производительности, облачных приложений, анализа и визуализации данных, а также продвигает и внедряет ряд внутренних технологий. Откройте для себя новые горизонты передовых технологических систем.

Если вы хотите измениться, вас забрасывают вещами, и вы надеетесь начать их бросать; если вы хотите измениться, вам сказали, что вам нужно больше идей, но вы не можете сломать игру; если вы хотите изменить , у вас есть возможность добиться этого результата, но вы не нужны; если вы хотите изменить то, чего хотите достичь, вам нужна команда для поддержки, но вам некуда вести людей; если вы хотите изменить установившийся ритм, это будет "5 лет рабочего времени и 3 года стажа работы"; если вы хотите изменить исходный Понимание хорошее, но всегда есть размытие того слоя оконной бумаги.. , Если вы верите в силу веры, верьте, что обычные люди могут достичь необыкновенных вещей, и верьте, что они могут встретить лучшего себя. Если вы хотите участвовать в процессе становления бизнеса и лично способствовать росту фронтенд-команды с глубоким пониманием бизнеса, надежной технической системой, технологиями, создающими ценность, и побочным влиянием, я думаю, что мы должны говорить. В любое время, ожидая, пока вы что-нибудь напишете, отправьте это наZooTeam@cai-inc.com