LoginSignup
33
9

More than 3 years have passed since last update.

中華製npmを知ってますか?! cnpmを紹介(ネタ)

Last updated at Posted at 2020-12-22

Node.jsアドベントカレンダー21日目になります。
npmといえば、Node.jsやフロントエンド開発で欠かせないツールですよね。そんな npmの中国版があることをご存知でしょうか。

仕事柄、中国に行ったり、中国にいる人とやりとりしたりすることがありますが、その辺に関連した話です。実用性はほぼ無いので話のネタだと思ってもらえると幸いです。(アドカレ遅刻すみません)

スクリーンショット 2020-12-22 11.54.59.png
IoTLT vol70で話をしたネタです。 スライドはこちら

npmが何かについては触れませんのでご了承下さい。

cnpm - 中国ミラー版のnpm

For developers in China, please visit the China mirror.

中国の開発者向けに作られているnpmのミラーサイト及びツールです。

そもそもなぜcnpmが必要なのか - グレートファイヤーウォール問題

中国ではグレートファイアウォール(金盾)というネット検閲の仕組みがあってGoogleやTwitterなどのサービスが使えないことが有名です。

試して無いですがおそらく、 中国国内からnpmを利用しようとすると、全く利用できないか、一部のパッケージのDL・インストールが出来ないという状況なのだと思います。

※中国以外の国のVPNを経由したり、香港SIMを使うなど回避方法はありますが、そういった回避方法を使わずに直で中国国内のネットワークを利用する際の話です。

見たところ、CNPMはtaobao(中国の楽天とかAmazonみたいなサイト)のドメイン下にミラーがある模様なので、中国国内のネットワークでも問題なく利用できるのでしょう。

怖いけどcnpmをインストールしてみた

正直情報抜かれてそうで怖かったりもしますので、試す場合は自己責任でお願いします。

実はnpm経由でインストールできる

メタな感じがしますが、npmにcnpmがいます。

https://www.npmjs.com/package/cnpm

なのでnpm i -g cnpmでインストールできるのですが、どうやら--registryオプションでtaobaorのサーバーを指定してインストールすることでcnpmのインストールができる模様です。

$ npm i -g cnpm --registry=https://registry.npm.taobao.org

でcnpmをインストール可能です。

ちなみに、指定している、https://registry.npm.taobao.orgが不安定で、アクセス出来たりできなかったりの差が激しかったです。(何の検証をしてるんだ......苦笑) コマンドとしてのcnpmを試すだけなら--registryオプション無しでインストールでも良いと思います。

$ npm i -g cnpm

インストールから時間かかる

僕が試した際には、 6分強かかりました。

スクリーンショット 2020-12-22 15.05.11.png

参考までにnpm i -g yarnでyarnをインストールした場合は0.5秒でした。

参考: https://speakerdeck.com/n0bisuke2/zhong-hua-zhi-npmfalsecnpmgaarumo-yang-number-iotlt?slide=14

cnpmを触ってみた

次は実際にcnpmのコマンドを見ていきます。

npm initやnpm installなどは同様に使える

基本的なコマンド操作は同じです。

  • パッケージインストール

npm icnpm iになるだけです。

$ cnpm i パッケージ名
  • プロジェクト初期化

これもnpm initcnpm initになるだけです。

$ cnpm init -y

ちなみにこの際に出来上がるpackage.jsonはほぼ一緒でした。

スクリーンショット 2020-12-22 15.12.13.png

バージョンの違い、npxは使えないなど

手元の環境が

  • Node.js v15.3.0
  • npm v7.0.14
  • cnpm v6.1.1

という状況で、若干の違いがありました。cnpmのバージョンがnpmの各バージョンの機能に追随出来てるかも不明です。

--saveオプション

例えば、最近のnpmはinstall時に--saveを付けなくても、package.jsonに記載してくれますが、現状のcnpmは--saveを付けないとダメでした。

cnpxは無かった

また、npxは使えるかなと思い、cnpx ngrok http 3000みたいな試し方をしてみましたが、npxのcnpm版はパッと見存在しなさそうでした。

サンプルアプリケーションを作ってみる準備

実際にcnpm経由でインストールしたモジュールが問題なく使えるのかを試してみたく、mqttライブラリを使ったサンプルを作って試してみました。

$ cnpm init -y
Wrote to /Users/n0bisuke/Documents/ds/playground/test-cnpm/test2/package.json:

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

初期化できました。
次にモジュールのインストールです。

サーバーに到達できなかったり、タイムアウトなどのトラブル

$ cnpm i mqtt --save

ここでトラブルが発生しました。

Get /bug-versions/latest from https://r.npm.taobao.org error: ConnectionTimeoutError: Connect timeout for 5000ms,

こんな感じのエラーでしたが単なるタイムアウトではなく、--registry=https://registry.npm.taobao.orgを指定してcnpmのインストールしてるとnpmではなくhttps://registry.npm.taobao.orgからモジュールをインストールしてこようとします。先程も書いたようにこのhttps://registry.npm.taobao.orgが落ちてたり不安定だったりするとここでエラーになります。

これは大元のサーバーの挙動が怪しいという話なので、このタイムアウトの場合はもうしばらく待つしかなさそうです。

また、サーバーの調子がよく、ある程度インストールが進んだかなぁと行った段階でも

Connect timeout for 60000ms......

といった タイムアウトエラーが発生しました。中国のサーバーに向かったり、内部でリダイレクトしたりをしてると思うので遅いのだと思うのですが、普通にタイムアウトするとは......

調べるとcnpm set timeoutでタイムアウトするまでの制限時間を伸ばすことが出来る模様です。もはやタイムアウトしてしまうのが前提なのかも

$ cnpm set timeout 120000

スクリーンショット 2020-12-22 19.14.51.png

こんな感じで改めてcnpm iでmqttモジュールをインストールできました。

$ cnpm i mqtt --save[0/1] Installing concat-map@0.0.1[npminstall:get] retry GET https://r.npm.taobao.org/concat-stream after 100ms, retry left 4, error: Error [ConnectionTimeoutError]: Connect timeout for 60000ms, GET https://r.npm.taobao.org/concat-stream -2 (connected: false, keepalive socket: false, agent status: {"createSocketCount":27,"createSocketErrorCount":0,"closeSocketCount":27,"errorSocketCount":0,"timeoutSocketCount":26,"requestCount":187,"freeSockets":{},"sockets":{},"requests":{}}, socketHandledRequests: 1, socketHandledResponses: 0)
headers: {}
    at Timeout._onTimeout (/Users/n0bisuke/.nodebrew/node/v15.3.0/lib/node_modules/cnpm/node_modules/urllib/lib/urllib.js:946:15)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7) {
  requestId: 7,
  data: undefined,
  path: '/concat-stream',
  status: -2,
  headers: {},
  res: [Object]
}, status: -2, headers: {}, 
stack: ConnectionTimeoutError: Connect timeout for 60000ms, GET https://r.npm.taobao.org/concat-stream -2 (connected: false, keepalive socket: false, agent status: {"createSocketCount":27,"createSocketErrorCount":0,"closeSocketCount":27,"errorSocketCount":0,"timeoutSocketCount":26,"requestCount":187,"freeSockets":{},"sockets":{},"requests":{}}, socketHandledRequests: 1, socketHandledResponses: 0)
headers: {}
    at Timeout._onTimeout (/Users/n0bisuke/.nodebrew/node/v15.3.0/lib/node_modules/cnpm/node_modules/urllib/lib/urllib.js:946:15)
    at listOnTimeout (node:internal/timers:556:17)
    at processTimers (node:internal/timers:499:7)
✔ Installed 1 packages
✔ Linked 61 latest versions
✔ Run 0 scripts
peerDependencies WARNING mqtt@4.2.6 › ws@^7.3.1 requires a peer of bufferutil@^4.0.1 but none was installed
peerDependencies WARNING mqtt@4.2.6 › ws@^7.3.1 requires a peer of utf-8-validate@^5.0.2 but none was installed
✔ All packages installed (66 packages installed from npm registry, used 1m(network 1m), speed 10.75kB/s, json 62(114.02kB), tarball 581.6kB)

ふう。。。

MQTTでPub/Subしてみる

  • Pub -> cnpm経由でインストールしたmqttモジュール
  • Sub -> npm経由でインストールしたmqttモジュール

という感じでcnpmとnpmでPub/Subしてみました。

先程mqttのインストールが完了したので、app.jsを書いてみます。

ここは通常と何ら変わりません。

  • mqttでpublishするコード
app.js
const mqtt = require('mqtt');
const client  = mqtt.connect('mqtt://test.mosquitto.org');

client.on('connect', () => {
  client.publish('n0bisuke', 'Hello cnpm');
});
$ node app.js
  • mqttでsubscribeするコマンド
$ npx mqtt sub -h test.mosquitto.org -t n0bisuke 
Hello cnpm

こんな感じでPub/SubのMQTT通信ができています。

インストール後は割と普通ですね

cnpm限定コマンド

cnpm限定のコマンドもある模様です。

  • cnpm sync -> npm側との差分を無くす
  • cnpm i --by=npm -> npmからDL/インストール

調べたらもっとあるかも

まとめ

cnpmという中華製のnpmミラーがある!

日本で使う意味はほぼ皆無 だと思うので、ネタ的な感じですね。

中国に行って開発することがあれば覚えておくと良いかもしれません。

33
9
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
33
9