Hexo 内部探訪 (2) 準備 npm linkメモ

npm linkを使いこなすには

npm linkという、ありがたい仕組みがあって、非公開のモジュール(または開発中のバージョン)を、node_modulesの中に配置することができる。
基本的には、シンボリック・リンクである。

ここまでは、すぐに把握できたけど、実はうまく動作させるための、さらなる条件があった。

モジュールを読み込む側と、読み込まれる側のモジュールが、ファイルシステム上で同階層になるように配置されている必要があるのだった。

私の場合だけど、開発中のリポジトリは、ある場所にまとめてある。
例:~/repository/hexo-tag-google-photos-album/
これが、Hexoプラグインを開発する場所。

一方で、ただ使うだけのものは、別の場所にある。
Hexoで構成しているブログの作業場所は、こんな感じ。
例:~/www/MyBlog/

つまり、自分のブログに自分のプラグインを組み込むとすると、
例:~/www/MyBlog/node_modules/hexo-tag-google-photos-album/
ということになる。

しかしながら、npm link的には、上記の2箇所を直接リンクすることはできないわけだ。

なので、さらに回りくどいが、以下のようにして、解決してみる。

naoto@MyComputer:~/www/MyBlog$ cd ..
naoto@MyComputer:~/www$ ln -s ../repository/hexo-tag-google-photos-album
naoto@MyComputer:~/www$ ls -l hexo-tag-google-photos-album
lrwxrwxrwx 1 naoto naoto 42 5月 6 01:46 hexo-tag-google-photos-album -> ../repository/hexo-tag-google-photos-album

こうすることで、開発中のプラグイン実体は従来通りのままとしつつ、link可能な場所にも配置できた。

呼び出される側のlinkは、以下の通り。

naoto@MyComputer:~/www$ cd hexo-tag-google-photos-album
naoto@MyComputer:~/www/hexo-tag-google-photos-album$ sudo npm link
(snip)
/usr/lib/node_modules/hexo-tag-google-photos-album -> /home/naoto/repository/hexo-tag-google-photos-album

そして、呼び出す方で使う側の、つまりブログ側の(しつこい)linkはこの通り。

naoto@MyComputer:~/www/hexo-tag-google-photos-album$ cd ../MyBlog
naoto@MyComputer:~/www/MyBlog$ npm link hexo-tag-google-photos-album
/home/naoto/www/MyBlog/node_modules/hexo-tag-google-photos-album -> /usr/lib/node_modules/hexo-tag-google-photos-album -> /home/naoto/repository/hexo-tag-google-photos-album
naoto@MyComputer:~/www/MyBlog$ grep photos package.json
"hexo-tag-google-photos-album": "git+https://github.com/isnot/hexo-tag-google-photos-album.git",
naoto@MyComputer:~/www/MyBlog$ ls -l node_modules/hexo-tag-google-photos-album
lrwxrwxrwx 1 naoto naoto 64 5月 6 01:50 node_modules/hexo-tag-google-photos-album -> ../../../../../usr/lib/node_modules/hexo-tag-google-photos-album

これで、毎度git pushとnpm upを繰り返すこと無く、作業ができるようになる(はず)。
確かめてみよう。

開発中のプラグインの中に、以下を書き加える。

~/repository/hexo-tag-google-photos-album/index.js
const { inspect } = require('util');
var g = Function('return this')();
console.log(inspect(g, { depth: 0 }));
console.log(inspect(hexo, { depth: 0 }));

これを、コミットもせず、コピーもせず、動かしたい。

naoto@MyComputer:~/www/MyBlog$ hexo list page
Object [global] {
global: [Circular],
process: [process],
Buffer: [Function],
clearImmediate: [Function: clearImmediate],
clearInterval: [Function: clearInterval],
clearTimeout: [Function: clearTimeout],
setImmediate: [Function],
setInterval: [Function: setInterval],
setTimeout: [Function] }
Hexo {
_events: [Object: null prototype] {},
_eventsCount: 0,
_maxListeners: undefined,
base_dir: '/home/naoto/www/MyBlog/',
public_dir: '/home/naoto/www/MyBlog/public/',
source_dir: '/home/naoto/www/MyBlog/source/',
plugin_dir: '/home/naoto/www/MyBlog/node_modules/',
script_dir: '/home/naoto/www/MyBlog/scripts/',
scaffold_dir: '/home/naoto/www/MyBlog/scaffolds/',
theme_dir: '/home/naoto/www/MyBlog/themes/stage/',
theme_script_dir: '/home/naoto/www/MyBlog/themes/stage/scripts/',
env: [Object],
extend: [Object],
config: [Object],
log: [Logger],
render: [Render],
route: [Router],
post: [Post],
scaffold: [Scaffold],
_dbLoaded: false,
_isGenerating: false,
database: [Database],
config_path: '/home/naoto/www/MyBlog/_config.yml',
source: [Source],
theme: [Theme],
locals: [Locals] }
INFO Start processing
INFO ---- START COPYING TAG CLOUD FILES ----
INFO ---- END COPYING TAG CLOUD FILES ----
Date Title Path
2019-04-09 Tags tags/index.md
2019-04-13 About いしだなおと / isnot N3 about/index.md

できた!

いいね。これで行こう。

運用中の注意事項

上記のような手順でプラグインをlinkしてある状況下で、もしnpm updateしたら、どういうことになるのだろうか?
試したところ、答えはlink状態が解除されて、package.jsonの記述内容の通りにモジュールが上書きされるということのようです。

ところが、開発中のプラグインとは無関係に、他も含めたnpmモジュールをアップデートしたいということはあるだろうと考えられる。
こういった状態を回避するには、どうするべきか考えると、いくつか選択肢が思い浮かぶ。

  • updateする頻度が低い場合は、毎回linkし直すという方法。あまり解決してない
  • linkを維持したいモジュールは、package.jsonに書かなければいいのかな?試してない
  • それ以外。何かあるかな?