labunix's blog

labunixのラボUnix

nodejs 18.xをdebian bullseyeに入れてみる。

■nodejs 18.xをdebian bullseyeに入れてみる。

$ lsb_release -d
Description:    Debian GNU/Linux 11 (bullseye)

■普通に入れるとこうなる。
 ブラウザ上に制限されていたJavaScriptをOSでも使えるようにしたJavaScipt実行環境。

$ apt-cache search ^nodejs$
nodejs - evented I/O for V8 javascript - runtime executable

$ sudo apt-get install -y nodejs

$ node --version
v12.22.12

■nodejsのパッケージマネージャを入れる。
 「Node Package Manager」はライブラリやパッケージを管理できる。

$ apt-cache search ^npm$
npm - Node.js 用パッケージマネージャ

$ sudo apt-get install -y npm

■aws lambdaの18.xに対応するようにしたい。
 lambdaでも12.xも選べるので不便とまでは言えないけれど。。。

 バージョン固定の主な理由は(作られたものが)動かなくなると困るということだろうけど、
 バージョン固定と引き換えにセキュリティに責任が持てる場合のみ実施すること(サポート指定とか)。

 バージョンアップのテストをしなくていいことと、セキュリティの担保をしなくていいはイコールにならないので、
 メンテナンスが不要ということにはならない点に注意する。

$ curl -sL https://deb.nodesource.com/node_18.x/pool/main/n/nodejs/ | \
    awk '/amd64/&&/deb-1nodesource1/{gsub("<a .*\042>|</a>","",$0);print $0 | "sort -V"}'
nodejs_18.0.0-deb-1nodesource1_amd64.deb           20-Apr-2022 15:55     26M
nodejs_18.1.0-deb-1nodesource1_amd64.deb           03-May-2022 15:55     26M
nodejs_18.2.0-deb-1nodesource1_amd64.deb           17-May-2022 16:54     26M
nodejs_18.3.0-deb-1nodesource1_amd64.deb           02-Jun-2022 15:53     27M
nodejs_18.4.0-deb-1nodesource1_amd64.deb           16-Jun-2022 14:49     27M
nodejs_18.5.0-deb-1nodesource1_amd64.deb           07-Jul-2022 17:06     27M
nodejs_18.6.0-deb-1nodesource1_amd64.deb           13-Jul-2022 22:33     27M
nodejs_18.7.0-deb-1nodesource1_amd64.deb           27-Jul-2022 14:36     27M
nodejs_18.8.0-deb-1nodesource1_amd64.deb           24-Aug-2022 17:28     27M
nodejs_18.9.0-deb-1nodesource1_amd64.deb           12-Sep-2022 15:21     27M
nodejs_18.9.1-deb-1nodesource1_amd64.deb           23-Sep-2022 21:17     27M
nodejs_18.10.0-deb-1nodesource1_amd64.deb          03-Oct-2022 21:15     27M
nodejs_18.11.0-deb-1nodesource1_amd64.deb          14-Oct-2022 19:28     27M
nodejs_18.12.0-deb-1nodesource1_amd64.deb          25-Oct-2022 23:03     27M
nodejs_18.12.1-deb-1nodesource1_amd64.deb          07-Nov-2022 15:35     27M
nodejs_18.13.0-deb-1nodesource1_amd64.deb          13-Jan-2023 18:14     27M
nodejs_18.14.0-deb-1nodesource1_amd64.deb          02-Feb-2023 21:27     27M
nodejs_18.14.1-deb-1nodesource1_amd64.deb          17-Feb-2023 01:11     27M
nodejs_18.14.2-deb-1nodesource1_amd64.deb          21-Feb-2023 22:12     27M
nodejs_18.15.0-deb-1nodesource1_amd64.deb          09-Mar-2023 14:42     27M

$ echo | awk -v PKG=nodejs_18.9.0-deb-1nodesource1_amd64.deb '{print "curl -o "PKG" https://deb.nodesource.com/node_18.x/pool/main/n/nodejs/"PKG}' | sh

$ head -3 nodejs_18.9.0-deb-1nodesource1_amd64.deb
!<arch>
debian-binary/  1662763179  0     0     100644  4         `
2.0

$ sudo apt install ~/nodejs_18.9.0-deb-1nodesource1_amd64.deb

■公式のインストールのメリットはaptが使えること。

$ curl -fsSL https://deb.nodesource.com/setup_18.x | lsec -sep "#" "## To install"
## To install the Yarn package manager, run:
     curl -sL $yarn_key_url | gpg --dearmor | sudo tee $local_yarn_key >/dev/null
     echo \"deb [signed-by=$local_yarn_key] $yarn_site stable main\" | sudo tee /etc/apt/sources.list.d/yarn.list
     sudo apt-get update && sudo apt-get install yarn
"""

}
[sudo -E]に違いは見えなかったので、UbuntuとDebianの違いというよりrootとsudo の違いの様子。
 これでaptの管理下に入る。
 ※私の環境では自分のことならなにかあれば直せますし、
  rootからのプロキシ経由の通信は認めていないのでsudoで作業しています。
  心配なら公式通り、rootで作業しましょう。

$ curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - &&\
sudo apt-get install -y nodejs

$ node --version
v18.15.0

$ cat /etc/apt/sources.list.d/nodesource.list
deb [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x bullseye main
deb-src [signed-by=/usr/share/keyrings/nodesource.gpg] https://deb.nodesource.com/node_18.x bullseye main

$ sudo apt-get install -y npm
$ npm --version
8.1.3

■プロジェクトを作ってjson-serverを立ててみる。

$ mkdir 1stPJ
$ cd 1stPJ/
$ npm init
$ du package.json
4       package.json

$  npm search json-server --json | jq -r '.[0] | {"name":.name,"description":.description}'
{
  "name": "json-server",
  "description": "Get a full fake REST API with zero coding in less than 30 seconds"
}

■マニュアルページを参照。早速そのままじゃ動かないとか先が思いやられる。。。
 左ペインでページ遷移するたび「Other versions」で「18.x LTS」って変えるのめんどい。
 URLに反映されないし、今時のUI/UXはこんなもんなのだろうか。。。
 左ペイン「Options」から「View on Single page」一択のようだ。

 https://nodejs.org/docs/latest-v18.x/api/synopsis.html

$ npm install json-server
$ du -hs node_modules/
47M     node_modules/

$ sdiff -l hello-world.js{,.org}
const http = require('http');                                 | const http = require('node:http');
                                                              (
const hostname = '127.0.0.1';                                 (
const port = 3000;                                            (
                                                              (
const server = http.createServer((req, res) => {              (
  res.statusCode = 200;                                       (
  res.setHeader('Content-Type', 'text/plain');                (
  res.end('Hello, World!\n');                                 (
});                                                           (
                                                              (
server.listen(port, hostname, () => {                         (
  console.log(`Server running at http://${hostname}:${port}/` (
});                                                           (
■とりあえず動かしてみる。

$ node hello-world.js
Server running at http://127.0.0.1:3000/

$ curl --noproxy 127.0.0.1 -sL http://127.0.0.1:3000/
Hello, World!

■マニュアルが12.Xのままなので、
 ブランチからもってきてpandocを介してテキストブラウザから見るか、
 直接URL叩いてブラウザで参照する。

$ dpkg -l | awk '/^ii/&&/nodejs-doc/{print $3}'
12.22.12~dfsg-1~deb11u3

$ git clone https://github.com/nodejs/node.git -b v18.x
$ sudo apt-get install -y pandoc
$ pandoc ~/node/doc/api/cli.md | w3m -T text/html

$ chromium https://github.com/nodejs/node/tree/v18.x

■全部テキストでいいじゃんって人はあらかじめ変換してしまえばよい。

$ find ~/node/doc/api -type f -name "*.md" | awk '{print "pandoc -t plain "$1" > "$1".txt"}'  | sh
$ find ~/node/doc/api -type f -name "*.md.txt" | sed -e 's%.*/%%g' | column
string_decoder.md.txt           https.md.txt                    path.md.txt                     globals.md.txt
perf_hooks.md.txt               fs.md.txt                       esm.md.txt                      net.md.txt
domain.md.txt                   querystring.md.txt              repl.md.txt                     webstreams.md.txt
wasi.md.txt                     modules.md.txt                  index.md.txt                    cli.md.txt
dgram.md.txt                    vm.md.txt                       async_hooks.md.txt              punycode.md.txt
permissions.md.txt              console.md.txt                  http2.md.txt                    cluster.md.txt
packages.md.txt                 debugger.md.txt                 url.md.txt                      readline.md.txt
zlib.md.txt                     util.md.txt                     timers.md.txt                   module.md.txt
async_context.md.txt            process.md.txt                  addons.md.txt                   stream.md.txt
inspector.md.txt                os.md.txt                       child_process.md.txt            tracing.md.txt
tty.md.txt                      synopsis.md.txt                 n-api.md.txt                    webcrypto.md.txt
tls.md.txt                      v8.md.txt                       crypto.md.txt                   events.md.txt
assert.md.txt                   dns.md.txt                      diagnostics_channel.md.txt      buffer.md.txt
embedding.md.txt                worker_threads.md.txt           http.md.txt                     intl.md.txt
documentation.md.txt            report.md.txt                   corepack.md.txt                 policy.md.txt
test.md.txt                     deprecations.md.txt             errors.md.txt

■公式のドキュメントページも同様に。
 「require('node:http');」は間違いだけど。。。

$ curl -sL https://nodejs.org/docs/latest-v18.x/api/all.html | pandoc -t plain > nodejs_manual.txt

$ awk '/^Open hello|^Save/{print NR}' nodejs_manual.txt
4170
4188

$ awk '(NR>=4170&&NR<=4188)' nodejs_manual.txt
Open hello-world.js in any preferred text editor and paste in the following
content:

const http = require('node:http');

const hostname = '127.0.0.1';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello, World!\n');
});

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

Save the file, go back to the terminal window, and enter the following command: