Slide 1

Slide 1 text

Node.js v12 を使い続けていたのなぁぜなぁぜ Yuta Ide (@sadnessOjisan)

Slide 2

Slide 2 text

アップデートが大変だからです。

Slide 3

Slide 3 text

自己紹介 { “名前”: “Yuta Ide”, “ソーシャル”: “@sadnessOjisan”, “所属”: “Nikkei”, “好きな絵文字”: “🍜” }

Slide 4

Slide 4 text

日経電子版の Node.js 利用状況について

Slide 5

Slide 5 text

の前に、アーキテクチャーについて

Slide 6

Slide 6 text

User → CDN → オリジンサーバー

Slide 7

Slide 7 text

垂直分割のマイクロフロントエンド構成 CDN (Fastly) Node.js Article Detail Search Market Article Index connect by anchor tags … handlebars handlebars VCL + handlebars react この発表における、垂直分割・水平分割の定義 ※垂直分割: ページごとに独立したアプリケーション ※水平分割: 1ページの中に複数アプリケーションが存 在。React, Vue 混在など。よくあるのは共通グローバル ナビヘッダーだけ独立 aggregate

Slide 8

Slide 8 text

改めて、 日経電子版の Node.js 利用状況について

Slide 9

Slide 9 text

We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail Topic Index Search Market Article Index connect by anchor tags We love HTTP and HTML handlebars handlebars handlebars VCL + handlebars オリジンサーバーに関係する 24レポジトリがNode.js v12 で稼働😇

Slide 10

Slide 10 text

v12 であることで困ること ● そもそもEOLなのだから上げないといけない ● Lambda を更新できなくなる ○ バグ対応を入れられなくて本当に困った! ● ライブラリのアップデートができなくなる ● 機能に制限がある ○ Error.prototype.cause ○ TCP dump

Slide 11

Slide 11 text

We adopt micro frontend architecture CDN (Fastly) Node.js Article Detail Topic Index Search Market Article Index connect by anchor tags We love HTTP and HTML handlebars handlebars handlebars VCL + handlebars v12 → v16 → v18→ v20に上げて行くも、 すでに1年が経過😇

Slide 12

Slide 12 text

なぜ 1 年もかかっているのか

Slide 13

Slide 13 text

リポジトリ数が多いから

Slide 14

Slide 14 text

日経に存在する4の世代 ● haishin: JSPで書かれた初期の世代。 ● rnikkei: “R”esponsive 対応のときに刷新された実装。爆速の日経と評された世代。 ● k2: React とモノレポを取り入れた世代 ● web: デプロイサイクルや言語選定の都合上、 k2のモノレポで管理していない世代。

Slide 15

Slide 15 text

日経に存在する4の世代 ● haishin: JSPで書かれた本当の最初期の世代。 ● rnikkei: “R”esponsive 対応のときに刷新された実装。爆速の日経と評された世代。 ● k2: React とモノレポを取り入れた世代 ● web: デプロイサイクルや言語選定の都合上、 k2のモノレポで管理していない世代。 リポジトリ数が最多 アクセス数が最多 rnikkei を置き換える

Slide 16

Slide 16 text

rnikkei の構成技術 ● rnikkei は汎用ビルドツールと汎用 Express Middleware、 汎用UIライブラリ、proxyサーバーから成り立つ、「設定よ り規約」なフレームワーク ● rnikkei-build-tools: クライアントスクリプトのビルド、 lint, format, デプロイなどのスクリプトの集合体。 webpack や babel の設定を持つ。 ● rnikkei-express: 日経電子版開発の決まり事を守るため のmiddlewareやテンプレートやcilent scriptの集合体。 APIへのアクセス、Varyヘッダーの操作関数、グローバル ナビの埋め込み、オンメモリキャッシュなどなど rnikkei-build-tootls rnikkei-express rnikkei-xxx (service) rnikkei-xxx-proxy rnikkei-ui, … (parts) APIGW

Slide 17

Slide 17 text

Let's try…

Slide 18

Slide 18 text

$ node -v 12 $ nvm use v16

Slide 19

Slide 19 text

$ yarn install

Slide 20

Slide 20 text

gyp-error

Slide 21

Slide 21 text

rnikkei-build-tools の node-sass ● rnikkei-build-tools はクライアントサイドビル ドツールも含む ● Sass のビルドも担当する ● node-sass は node のバージョン次第で gyp-error を引き起こす rnikkei-build-tools の最新版は dart-sass に 切り替わっている (dart)node-sass webpack babel /client/*js /client/*sass /server/*.js /views/*.html pkg.json rnikkei-build-tools 各サービス rnikkei-build-tools は 長く使われ ていたv9 が node-sass, v11 が dart-sass を利用

Slide 22

Slide 22 text

$ yarn upgrade @nikkei/rnikkei-build-tools@11

Slide 23

Slide 23 text

not found

Slide 24

Slide 24 text

2つの npm registry ● AWS で動かしてるVerdaccioが不安定 ● package群はnpmjs.com に移行中 ● 新しめのpackageのversionがVerdaccioの方には存在しない ● Verdaccioの方は不安定でpublishもままならない サービスのリポジトリで利用しているregistryを npmjs.comに切り替える

Slide 25

Slide 25 text

//registry.npmjs.org/:_authToken=${NPM_TOKEN} registry = "https://registry.npmjs.org/" Local, CIに NPM_TOKEN をセットするのを忘れずに .npmrc

Slide 26

Slide 26 text

$ yarn upgrade @nikkei/rnikkei-build-tools@11

Slide 27

Slide 27 text

👍

Slide 28

Slide 28 text

$ yarn lint on CI workflow

Slide 29

Slide 29 text

stylelint error

Slide 30

Slide 30 text

rnikkei-build-tools のバージョンを上げると lint rule が変わる ● ビルドツール自体が stylelint のルールを持っている ● ビルドツールのバージョンを上げるとそのルールが変わり、現行のコードが lint で弾かれる 明らかに治せるところ以外全て ignore

Slide 31

Slide 31 text

“engines”: { “node”: “^16.20.0” } package.json

Slide 32

Slide 32 text

… CMD ["yarn", "start"] Dockerfile

Slide 33

Slide 33 text

NPM TOKEN not found on runtime 😇

Slide 34

Slide 34 text

.npmrc と yarn ● yarn は engines の指定と異なる環境で cli を実行するとエラーで落としてくれる。 Node バージョ ン切り替えが local, ci, container で達成されていることを担保するために yarn に切り替えたい。 ● yarn に切り替えると、その環境変数を使わないスクリプトの実行を yarn run するだけで も、.npmrc の中の環境変数を参照しようとする。 ● 環境変数を実行環境にセットするか、 .npmrc を省く必要がある .npmrc をコンテナに含めない

Slide 35

Slide 35 text

.npmrc .dockerignore

Slide 36

Slide 36 text

ここまでの処理で Node.js v16 が動く準備が整ったので、各種設 定ファイルを v16 へと引き上げる

Slide 37

Slide 37 text

v16 .node-version

Slide 38

Slide 38 text

ln -s .node-version .nvmrc

Slide 39

Slide 39 text

FROM node:16.20.0-bullseye-slim Dockerfile

Slide 40

Slide 40 text

definitions: workspace: &workspace working_directory: ~/workspace docker: - image: cimg/node:16.20.0 environment: CIRCLE_ARTIFACTS: "./tmp/artifact" .circleci/config.yaml

Slide 41

Slide 41 text

v18 に上げよう

Slide 42

Slide 42 text

v18 .node-version

Slide 43

Slide 43 text

yarn build

Slide 44

Slide 44 text

node:internal/crypto/hash:69 this[kHandle] = new _Hash(algorithm, xofLen); ^ Error: error:0308010C:digital envelope routines::unsupported at new Hash (node:internal/crypto/hash:69:19) at Object.createHash (node:crypto:133:10) at module.exports Node.js v18.17.1 error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command. Exited with code exit status 1 CircleCI received exit code 1

Slide 45

Slide 45 text

v16->v18におけるcryptoモジュールの変更 ● webpack が内部で呼び出す Hash 関数のアルゴリズムが Node 本体のアップデートによる OpenSSL の更新によって使えなくなった ● nodejs 17: digital envelope routines::unsupported webpack/webpack#14532 (comment) やその前後の会話から Webpack4 での正攻法の解決はできないことが分かった ○ webpack の設定でハッシュ関数を選択できるようになるのは v5 以降 ○ このあたりの設定をwebpack側が面倒を見てくれるのは v6 以降 ● OpenSSL のモジュールを content hash の生成くらいにしか使っておらず、ビルドスクリプトは開 発時にしか使っておらず、ユーザーがセキュリティ的な脅威を受けるわけではないので、 NODE_OPTIONS=--openssl-legacy-provider を使って誤魔化す Node v20 以降も使える保証は?😇

Slide 46

Slide 46 text

yarn build

Slide 47

Slide 47 text

👍

Slide 48

Slide 48 text

ここまでくると v20 へのアップデートは 詰まらない

Slide 49

Slide 49 text

v20 .node-version

Slide 50

Slide 50 text

yarn build

Slide 51

Slide 51 text

👍

Slide 52

Slide 52 text

デプロイ?

Slide 53

Slide 53 text

動作確認

Slide 54

Slide 54 text

目grep ドライアイが悪化した気がする

Slide 55

Slide 55 text

playwright 途中で日経IDの認証方法が変わって大変 だった よく壊れる

Slide 56

Slide 56 text

Autify GUIで作れるE2Eテストツール。 良い。

Slide 57

Slide 57 text

これで終わり?

Slide 58

Slide 58 text

1年かからなくね?

Slide 59

Slide 59 text

これを24レポジトリでやります!!!!!!! (ツール含めたら 40 レポジトリ!!!)

Slide 60

Slide 60 text

どのように進めたか?

Slide 61

Slide 61 text

v16移行開始 reg test 整備 アップデートマニュア ル整備 v16移行実施 マニュアルやテスト の修正 v18移行実施 マニュアルやテスト の修正 v20移行開始 2022/12- 2023/4- 2023/7- 2023/10- Aさん Bさん Cさん Dさん

Slide 62

Slide 62 text

と、これ通りには行かず、 移行して失敗して移行手順書作り直しての繰り返し

Slide 63

Slide 63 text

大変でした!!!!!!!!!!!

Slide 64

Slide 64 text

お疲れ様です!!!!!

Slide 65

Slide 65 text

勝利!完!

Slide 66

Slide 66 text

🤔

Slide 67

Slide 67 text

Node.js は半年ごとにバージョン上がっていくけど、 EOLのたびに毎回この儀式するのですか?

Slide 68

Slide 68 text

😵

Slide 69

Slide 69 text

はい(やりたいとは言っていない)

Slide 70

Slide 70 text

未来のことを考えよう

Slide 71

Slide 71 text

辛さの根源は過剰なマイクロサービスにある ● 前提: 私たちのチームは20人前後の体制 ● 1, 2 個の Node バージョンをあげるくらいなら辛くない ● マイクロフロントエンドという構成の都合上、サービス数が多い ● サービスごとに、他のサービスに影響を与えることなく実装を変えれるのは嬉しい一方で、 20個以 上のサービスを1チームで運用するのは大変 ● rnikkei 構想時は問題なかったかもしれないが、リリースから7年が経ち、サービスもビジネスも拡 大していくに連れて、1チームでマイクロサービス全てを管理するのが難しくなっている

Slide 72

Slide 72 text

メンテナンスコストを下げよう ● 動作確認のコストをもっと下げる。 Playwright 改善、Autify をもっと拡充させる。 ● 別々になっているレポジトリを統合してモノレポ化、可能ならモノサービス化までしたい。 (rnikkei-build-tools の要求する規約に耐えれるかが争点) ● JSON API など、Node.js以外の選択肢を取れるものに限っては、可能なタイミングでメンテナン スしやすい別言語で置き換える。コンパイルでバグの有無をある程度担保できる Rust、標準ライ ブラリが大きな力を持つ Go で置き換えた実績も有る。

Slide 73

Slide 73 text

We are hiring.