Skip to content

Instantly share code, notes, and snippets.

@yano3nora
Last active April 25, 2024 08:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save yano3nora/042ae11d401527b1a71ad9963a63df2f to your computer and use it in GitHub Desktop.
Save yano3nora/042ae11d401527b1a71ad9963a63df2f to your computer and use it in GitHub Desktop.
Deno - Modern JS/TS Runtime by Ryan Dahl (Node.js Author). #js

Overview

deno.com/runtime
denoland/deno - github.com

とりあえず ↓ を読む。

Effective Deno - zenn.dev

ふんわり理解だけど今んとこ 「 typescript で外部依存少なめな小さい部品を作りたい 」 なら使えそう。

Getting Started

CLI Command 一覧は Built-In Tooling あたり

# install
$ brew install deno
$ deno --version
> deno 1.33.2 (release, x86_64-apple-darwin)
> v8 11.4.183.1
> typescript 5.0.3

# upgrade example
$ chmod 711 $(where deno) # https://github.com/denoland/deno/issues/14829
$ deno upgrade --version 1.0.1

# zsh setting (completions)
$ mkdir ~/.zsh
$ deno completions zsh > ~/.zsh/_deno
$ exec $SHELL -l

# test `deno run`
$ deno run https://deno.land/std/examples/welcome.ts

# repl
$ deno repl

# type check, lint, fmt, bench, test
$ deno check main.ts
$ deno lint main.ts
$ deno fmt main.ts
$ deno bench main.ts
$ deno test

# hot reload with --watch flag
# https://deno.com/manual@v1.33.2/getting_started/command_line_interface#watch-mode
$ deno test --watch
$ deno run --watch main.ts

deno init & deno.json

Starting a new project
Configuration File
TypeScript Configration
denoland/deno#15300 (comment)
denoland/deno#17099

  • init で deno.json 設定ファイルと main.ts main_test.ts などの hello world script が生成される
    • tsconfig, lint, test, scripts (task), dependencies (imports) など全部入りなので適当に調整していく
  • 初回の依存 download (deno run か deno cache --reload) で deno.lock 生成される
    • 以降は --lock lock-write flag の使い分けで依存管理する感じ
  • npm 依存がっつり or deno 全振りかを決めてから setup していくのがよさそう
    • npm 依存多いなら package.json compatibility 管理に倒しちゃってもいいかも
    • そうでないなら下手に node っぽくせずちゃんと deno 標準にのっかるのがよさそう

vscode-deno

vscode-deno

Deno: Initialize Workspace Configuration.vscode/settings.json 生成。

.vscode/settings.json

  • vscode-deno は default で on にならない
  • あと deno の lint, fmt はカスタム前提じゃない
  • ので deno 標準機能使うならある程度 settings.json をこねる感じになる

... ってことで、deno project では .gitignore から .vscode/settings.json 外しておいたほうが良さそう。

!.vscode/settings.json

language Server

ts 同様に language server は以下コマンドで restart できる。

Deno: Restart Language Server

deno test

Testing

こんな。

$ deno test --watch
// main.test.ts

import { assertEquals } from "https://deno.land/std@0.186.0/testing/asserts.ts"
import { isNumber } from "./src/is-number.ts"
import { error2json } from "./src/error2json.ts"

Deno.test('is-number', async test => {
  await test.step('string literal be fail', () => {
    assertEquals(isNumber('1'), false)
  })
  await test.step('number literal be true', () => {
    assertEquals(isNumber(1), true)
  })
})

deno fmt

Formatter
How can I deno fmt on file save? #328
VSCodeで保存時に deno fmt するには

  • deno lint は rule custom できない、多分やるつもりない
  • 代替としては eslint など別途使う or deno fmt で file save ごとに直す
  • single quote 強制や semi colon 抜きくらいならできた

vscode-deno で formatOnSave で deno.jsonfmt rule を読むという感じ。

// .vscode/settings.json
{
  "deno.enable": true,
  "deno.lint": true,
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "denoland.vscode-deno"
}
// deno.json
{
  "fmt": {
    "options": {
      "singleQuote": true,
      "semiColons": false
    }
  }
}

これで auto import とか時点では from "hoge"; とかになってるやつをファイル保存で from 'hoge' とかに整形できる。

Modules

Basics > Modules
Import Maps
package.json compatibility
Integrity Checking & Lock Files

  • deno は コードベースに依存先の cdn/package 名を書いとく という方式をとっている
    • 基本 import/export (esm) 方式で .ts など拡張子を省略するなとのこと
  • で、初回実行時に local pc の global な cache 空間に DL され以降はそこから読まれる
    • node の node_modules (local) にドカンと DL する方式とは全く異なる
    • 依存は URL, ファイルパスで行い、コード上の import を mapping するという考え
    • 再ロードしたいときは deno cache --reload を使えとのこと
  • cdn はざっくり ↓ から選ぶ、どっぷり deno 使うわけじゃなければ npm 互換がよさそう
  • version 固定については deno.lockvendor のいずれかの戦略から選ぶ感じ
    • まず前提として、初回実行時に cache されて以降は cdn 側の「中身」が変わらない限り大丈夫
    • ので ci で deno cache --reload (+ deno.lock 生成) して deno run --lock=deno.lock でよき
      • 更新時には deno cache --reload --lock=deno.lock --lock-write かな?
    • 本番に出す前に deno vendor で全依存を download & git 管理する
      • Vendoring Dependencies
      • 多分 deno vendor mod.ts して deno run --no-remote --import-map=vendor/import_map.json mod.ts するイメージ
      • 多分 ci で cdn 落ちてたら困るケースならこっち

npm package How to

How to create a RESTful API with Prisma and Oak

ちゃんと読んでないけど、npm package をガッツリつかった開発はまだ production ready じゃなさそう。

deno_std

deno_stdを使ってみよう
どのバージョンのdeno_stdを使えばいいの?

  • deno 公式 lib 集で多分 go の standard library のまねっこ
  • io, fs, path, testing など便利系が揃ってる
  • まだ beta & deno 本体と独立した version 管理なので、指定 ver に気をつける
import { posix } from "https://deno.land/std/path/mod.ts"
posix.join("dist", "index.html");
// => unix なら dist/index.html に、win なら dist\index.html になるとか

Installer

Script Installer

Publish deno.land

自作ツールをdeno.land/xに上げる

  • git repo から web hook を使って tag ごとに publish みたいなことするらしい
  • 勝手に api reference を組んでくれるので、それだけでも便利

dnt - Develop & Publish NPM Library

denoland/dnt - github.com
Deno を使って Node でも Deno でも動くライブラリを作る
dntでDeno-firstなデュアルモジュールを作る

  • dual package (cjs / mjs) 対応な npm library の開発環境 & publish が高速でできる
    • cjs は top level await 使えないとか一部制限あり
  • deno module を作って dnt で node 用コードを build し publish する流れ
    • ignore してる .npm に build してそいつを publish する感じ
  • typescript の type declare (型宣言) も作ってくれるしゅごい

こんな感じかな。

// main.ts
export * from './a-func.ts'
export * from './b-func.ts'
import { build, emptyDir } from 'https://deno.land/x/dnt@0.35.0/mod.ts'

await emptyDir('./npm')
await build({
  entryPoints: ['./main.ts'],
  outDir: './npm',
  shims: { deno: true },
  package: {
    name: '@', // TODO
    version: Deno.args[0].replace(/^v/, ''),
    description: '', // TODO
    publishConfig: { access: 'public' }, // if scoped package
  },
  postBuild() {
    Deno.copyFileSync('LICENSE', 'npm/LICENSE')
    Deno.copyFileSync('README.md', 'npm/README.md')
  },
})
{
  "tasks": {
    "dev": "deno test --watch",
    "build": "deno run -A build.ts",
    "link": "(cd npm && npm link)",
    "publish:dry": "(cd npm && npm publish --dry-run)",
    "publish:run": "(cd npm && npm publish)"
  },
  "test": {
    "exclude": ["npm/"]
  },
  "lint": {
    "exclude": ["npm/"]
  },
  "fmt": {
    "exclude": ["npm/"]
  }
}
// .vscode/settings.json
{
  "deno.enable": true,
  "deno.lint": true,
  "deno.enablePaths": [
    "./",
    "!./npm/"
  ],
  "editor.formatOnSave": true,
  "editor.defaultFormatter": "denoland.vscode-deno"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment