らんだむな記憶

blogというものを体験してみようか!的なー

nvm と TypeScript

息抜き用に nvm を導入して node.js を放り込む。

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash

でインストール。~/.bashrc に

export NVM_ROOT="$HOME/.nvm"
if [ -d "${NVM_ROOT}" ]; then
    export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HO    ME}/nvm")"
    [ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
fi

と記載して、nodenv でも nvm でも存在するほうを使えるようにしておく。

なお、ubuntu - "which nvm" is gone - Stack Overflow にあるように

source ~/.nvm/nvm.sh

によって nvm 関数としてコマンドが使えるようになる形なので、which nvm はコマンドのインストール位置を返したりはしない。ちょっと驚いた・・・。

さて、適当に

nvm install --lts

で最新の LTS が入った。

$ which node
/home/xxx/.nvm/versions/node/v16.13.2/bin/node

まぁ、そりゃここに入るよね、と。

$ nvm use system

でシステムの・・・というか、例えば /opt/conda/bin/node が最初から入っているのならそちらが見えるようになる。
nvmのデフォルトのバージョンの変え方 - Qiita のように

$ nvm alias default v16.13.2

とすればデフォルトが指定したバージョンになる。なるほど。

$ nvm ls

で一覧を確認できる。~/.nvm/versions/node/v16.13.2/lib/node_modules はまだ綺麗な状態で良い。

$ mkdir js_work
$ cd js_work

で実験場を作ってみる。

$ npm list -g
/home/xxx/.nvm/versions/node/v16.13.2/lib
├── corepack@0.10.0
└── npm@8.1.2
$ npm list
/home/xxx/js_work
└── (empty)

実質空っぽ。
あまりよく分かってないけど、

$ npm init -y
Wrote to /home/xxx/js_work/package.json:

{
  "name": "js_work",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}

なんか json ができた。
ついでなので TypeScript を導入する。TypeScript: JavaScript With Syntax For Types. を参考に、

$ npm install typescript --save-dev

を実行する。

$ npm list
js_work@1.0.0 /home/xxx/js_work
└── typescript@4.5.5

という感じになった。

npm list -g
/home/xxx/.nvm/versions/node/v16.13.2/lib
├── corepack@0.10.0
└── npm@8.1.2

は変化なし。なるほど。--save-dev の部分は npm-install | npm Docs を参考にしても良いがあっさりしすぎた説明でよく分からないので、【npm初心者】なんんとなく使っていた npm install の --save-dev ついて調べてみた とかを参考にすると良さそう。

node_modules/.bin/tsc --init

こんなこともしとくと良さそう?

とりあえず TypeScript-Handbook/TypeScript in 5 minutes.md at master · microsoft/TypeScript-Handbook · GitHub をやってみよう。warning が出ているので、person:string という感じで any ではなく明示的に型を与えておく。

[greeter.ts]

function greeter(person:string) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.textContent = greeter(user);
$ node_modules/.bin/tsc greeter.ts 

でトランスパイルする。

[greeter.js]

function greeter(person) {
    return "Hello, " + person;
}

var user = "Jane User";
document.body.textContent = greeter(user);

わりと普通に見られるものが出てきた・・・。最初だけだ・・・。もっと汚いのがどんどん出てくるぞ・・・
これを Node.js とは | Node.js にあるサーバから配信したいのだが、node.js - NodeJS Not loading External javascript - Stack Overflow みたいにファイルのリクエストに応えるロジックの実装が必要でそれは面倒くさいので、フラットに展開して・・・

[server.js]

const http = require('http');

const hostname = '0.0.0.0';
const port = 8080;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/html');
  res.write('<!DOCTYPE html> \
    <html> \
    <head><title>TypeScript Greeter</title></head> \
    <body> \
      <script> \
        function greeter(person) { \
          return "Hello, " + person; \
        } \
        var user = "Jane User"; \
        document.body.textContent = greeter(user); \
      </script> \
    </body> \
    </html>');
  res.end();
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

気持ちだけの実装として上記のようにして、

$ node server.js

してブラウザで眺めてまったりしてみた。
・・・というのは何か面倒くさかったので、Express を使って

[server.js]

const express = require('express')
const path = require('path')
const app = express()

app.use(express.static(path.join(__dirname, 'public')))

app.listen(8080, '0.0.0.0')

にして、public の下に index.htmlgreeter.js を配置したら楽だった。また、nodemon を使って、

$ nodemon server.js

したらホットリロードができてとても便利だった。