たかぴろのブログ

雑多なアウトプット

メリクリ2019

npm xmas

 メリクリですね。今日も街中はたくさんの人がいました。

今日はnpm xmas について書きたいと思います。これです↓


ぼくは昨日Twitterで見て初めて知りました。node(npm) が入ってる人は
$ npm xmasしてみてください。

f:id:sum6:20191225213008p:plain
npm xmas

癒されますね。
 npmについての説明は省略します。ググってください。
npm install きっとやったことある人が多いと思います。ちなみに僕の尊敬してる友達は yarn のほうが好きって言っていました。


こいつ、ソースを見てやろうと思ったのですがなかなか面白いやつで、色々勉強になりました。

なるほどxmasっていうパッケージね(違った)

ああ npm scripts ね(全然違った) 


参考: https://docs.npmjs.com/misc/scripts
   https://olein-design.com/blog/build-webpage-by-npm-script


本題


え… npm 自体にもともと組み込まれたコマンド…?
すごくない?ユーモアが違うな。


探す。

 $ which npm    //   usr/bin/npm
 $ ll /usr/bin/npm  //     (略)   /usr/bin/npm -> ../share/npm/bin/npm-cli.js*

とのことだったので、 /usr/share/npm/ の中を探ると

 $ ls    // bin  doc  lib  man  node_modules  npmrc  package.json
 $ ls lib 
 access.js      deprecate.js               init.js          ping.js        shrinkwrap.js  unpublish.js
adduser.js     dist-tag.js                install          prefix.js      star.js        update.js
bin.js         docs.js                    install.js       prune.js       stars.js       utils
bugs.js        edit.js                    install-test.js  publish.js     start.js       version.js
build.js       explore.js                 link.js          rebuild.js     stop.js        view.js
cache          faq.js                     logout.js        repo.js        substack.js    visnup.js
cache.js       fetch-package-metadata.js  ls.js            restart.js     tag.js         whoami.js
completion.js  fetch-package-metadata.md  npm.js           root.js        team.js        /*xmas.js*/
config         get.js                     outdated.js      run-script.js  test.js
config.js      help.js                    owner.js         search.js      unbuild.js
dedupe.js      help-search.js             pack.js          set.js         uninstall.js

おー、あった、では肝心のコードも。

//  npm/lib/xmas.js

var log = require('npmlog')

module.exports = function (args, cb) {
  var s = process.platform === 'win32' ? ' *' : ' \u2605'    //  ★ ほし!
  var f = '\uFF0F'          // /  ひだり
  var b = '\uFF3C'        //  \  みぎ
  var x = process.platform === 'win32' ? ' ' : ''
  var o = [
    '\u0069', '\u0020', '\u0020', '\u0020', '\u0020', '\u0020',
    '\u0020', '\u0020', '\u0020', '\u0020', '\u0020', '\u0020',
    '\u0020', '\u2E1B', '\u2042', '\u2E2E', '&', '@', '\uFF61'         // i, space, ⸛, ⁂, ⸮, 。
  ]
  var oc = [21, 33, 34, 35, 36, 37]
  var l = '\u005e'     //  ^ (下の部分)

  function w (s) { process.stderr.write(s) }

  w('\n')
  ;(function T (H) {
    for (var i = 0; i < H; i++) w(' ')
    w(x + '\u001b[33m' + s + '\n')
    var M = H * 2 - 1
    for (var L = 1; L <= H; L++) {
      var O = L * 2 - 2
      var S = (M - O) / 2
      for (i = 0; i < S; i++) w(' ')
      w(x + '\u001b[32m' + f)
      for (i = 0; i < O; i++) {
        w(
          '\u001b[' + oc[Math.floor(Math.random() * oc.length)] + 'm' +
          o[Math.floor(Math.random() * o.length)]
        )
      }
      w(x + '\u001b[32m' + b + '\n')
    }
    w(' ')
    for (i = 1; i < H; i++) w('\u001b[32m' + l)
    w('| ' + x + ' |')
    for (i = 1; i < H; i++) w('\u001b[32m' + l)
    if (H > 10) {
      w('\n ')
      for (i = 1; i < H; i++) w(' ')
      w('| ' + x + ' |')
      for (i = 1; i < H; i++) w(' ')
    }
  })(20)      //←後述
  w('\n\n')
  log.heading = ''
  log.addLevel('npm', 100000, log.headingStyle)
  log.npm('loves you', 'Happy Xmas, JavaScripters')
  cb()
}
var dg = false
Object.defineProperty(module.exports, 'usage', {get: function () {
  if (dg) module.exports([], function () {})
  dg = true
  return ' '
}})

よくわからないですね。でもできるだけコメントしてみました。

まず \u2605 などの形をしているのは Unicode です。例えば \u2605 →★

T(H)は高さHの木を作る関数のようです。中ではw(s)でどんどん書き足してっていることが伝わってきました。あとは[32mなどのところが色ですね。

参考: BashでPromptの色を変更する方法 - Qiita


さらに

w()関数の中は process.stderr.write() となっていますが、これは Node.js で標準エラー出力に文字列を出力できるヤツらしいです。一応エラーなんだね、これ。別のプロジェクトの中に入れて試してみたけど、console.log と変わらんやんってなった。先行者がいた。

参考: https://www.cloverfield.co.jp/2018/05/31/%E6%94%B9%E8%A1%8C%E3%81%AE%E6%9C%89%E7%84%A1%E3%81%A0%E3%81%91%E3%81%AE%E8%A9%B1%E3%81%AA%E3%81%AE%E3%81%8B%EF%BC%9F/


そしてもう一つ、ツリーの大きさが20と与えられていることについて。
JSでは関数の引数は arguments[] に保存されるため、20のところを arguments[0] にしたら、なんと大きさを指定できるようになりました。

f:id:sum6:20191225235615p:plain
小さいツリー
f:id:sum6:20191225233123p:plain
小さいツリー

f:id:sum6:20191225233314p:plain
大きいツリー


ということで、今日は npm について色々知れる日になりました。
なんでも調べたらでてきちゃうからネットすごいわ。


超参考: npm xmas! - すぎゃーんメモ 超ありがとうございます

感想

周りにリア充が多くて悲しくなりました。

おわりです。