npm にパッケージ置いてみた
- カテゴリ:
- JavaScript
- Webサービス
- コメント数:
- Comments: 0
◆ 公開はすごく簡単にできる
普段 JavaScript ばかりいじってますが 基本的にブラウザのもので node.js はたまに使うくらいです
node.js で使われる npm もたまに npm install で試してみるものがあるくらいであんまり使ってません
普段コードはブログか gist においていますが ブログは記事数が多くなってくると探すのがちょっと大変です
再利用しそうなコードを書いた記事以外が多すぎますからね
gist もあんまり検索に向いてないです
何か無いかなと考えていると npm を思いつきました
npm だと npm install でインストールできるし ちょっと試す分には そのまま node.js でやってしまってもいいですし インストールされた node_modules から js ファイル持ってきて HTML からロードすることもできます
とりあえず使ってみようということで たまに使いそうなライブラリ公開してみた
のですが このことをブログに書く想定で公開してなかったので 公開に使ったアカウント名を伏せるために公開したのとは別のを使って説明します
たまに思うのですが
こういうインデントがちょっと深いところでテンプレートストリング (`) を使うとインデントが気持ち悪くなります
コードの見た目を重視すると
インデントがそのままでるのでこうなります
これをどうにかしたくてこう書けるようにしてみます
コードはこうなりました
では とりあえずこのコードを align-first.js というファイル名で保存します
このファイルを公開する用のフォルダを作って入れておきます
いまだに ES2015 の ES module が使えるようになったという話は聞かないので これまでどおりの node.js の module の作り方にします
export したいデータを exports のプロパティに設定します
exports オブジェクトが require したときの返り値になります
最後の行が増えただけです
require で動くか確認します
同じ align-first フォルダの中に require-test.js というファイルを作って
node で実行します
ちゃんとロードできています
最初に
とやっていますが これは exports のプロパティに alignFirst を入れていて require した返り値は exports 自身になるからです
exports 自身を alignFirst にしてしまえばもうちょっと短くできますが 将来的に関数増やしたいときに使い方が変わるのでこうしてます
一応公開する以上 使い方が変わるのはできるだけ避けたほうがいいと思うので 1 つしかプロパティなくてもこうしてるパッケージは結構あると思います
どうしても require の返り値を関数にしたいなら
とすれば
こう使えます
module だと module のトップレベルで定義しても global ではないのですが ブラウザではそうはいかないので export するもの以外見えないようにします
パッケージを作ると言っても公開用のフォルダに package.json を置くだけです
最低限これだけあれば大丈夫
これで公開用のフォルダがパッケージになります
みんなに使ってもらうことを前提にしてるなら description に説明書いたり script に実行用のコマンド書いたり もっと色々書いた方がいいと思います
https://docs.npmjs.com/files/package.json
あと README 置いたり ですね
手動で書かなくても
聞かれる項目がちょっと多いのでどこかのパッケージをコピペしてきて それをテンプレートに編集したほうが楽な場合もあります
このパッケージをインストールするために別のフォルダを作ります
test フォルダで
test フォルダの中に node_modules フォルダができて その中に align-first フォルダがあるはずです
試しに test フォルダに test.js ファイルを↓の中身で作ります
実行してみると
ちゃんと動きますね
まずは npm にサインアップします
ユーザ名とパスワードとメールアドレスくらいのシンプルなものです
メールアドレスは公開されるので注意です
メールアドレスに送られてきたリンクをクリックする必要もないので 見た人が間違ってメールしてしまうことがない明らかなダミーアドレスを入れておいても問題はなさそう
そのまま 公開まで web で出来るのかと思っていたらどこにもボタンがなくて調べてみると npm コマンドが必要でした
最初は npm adduser でアカウント設定が必要です
対話型でユーザ名とパスワードとメールアドレスを聞かれます
メールアドレスはサインアップしたものと違っても大丈夫でした
終わったら npm publish コマンドで公開できます
最後に npm install でインストールされることを確認しておしまい
※ 実際にはこのパッケージを公開してないので探しても見つかりません
adduser ができていない状態で publish してしまってもエラーになるだけです
メッセージにあるように npm adduser しましょう
↓
nodejs で require 出来る形にする(ブラウザでも同じコード使うなら window へのエクスポートも)
↓
公開用フォルダに package.json をおいて最低限の設定を書き込む
↓
(初めてなら) npm にサインアップ (web) して npm adduser で登録したユーザ情報を npm に設定 (コマンド)
↓
package.json のあるところで npm publish コマンドを実行して公開
まとめるとすごく簡単にできるようになってます
とか
module のトップレベルで定義したのが global にないの?
って思う人はこちらをどうぞ
Node.js 7 が出てたのでなんとなく module の読み込みを調べてみた
簡単にいってしまうと
として実行されてるから というだけですけど
node.js で使われる npm もたまに npm install で試してみるものがあるくらいであんまり使ってません
普段コードはブログか gist においていますが ブログは記事数が多くなってくると探すのがちょっと大変です
再利用しそうなコードを書いた記事以外が多すぎますからね
gist もあんまり検索に向いてないです
何か無いかなと考えていると npm を思いつきました
npm だと npm install でインストールできるし ちょっと試す分には そのまま node.js でやってしまってもいいですし インストールされた node_modules から js ファイル持ってきて HTML からロードすることもできます
とりあえず使ってみようということで たまに使いそうなライブラリ公開してみた
のですが このことをブログに書く想定で公開してなかったので 公開に使ったアカウント名を伏せるために公開したのとは別のを使って説明します
何か作る
実際に公開してみたのを例にするとぐぐったらアカウントがわかるので 何か別に作りますたまに思うのですが
!function(){
if(1){
var text = `
a
b
c
d
e
f
`
console.log(text)
}
}()
if(1){
var text = `
a
b
c
d
e
f
`
console.log(text)
}
}()
a
b
c
d
e
f
b
c
d
e
f
こういうインデントがちょっと深いところでテンプレートストリング (`) を使うとインデントが気持ち悪くなります
コードの見た目を重視すると
!function(){
if(1){
var text = `
a
b
c
d
e
f
`
console.log(text)
}
}()
if(1){
var text = `
a
b
c
d
e
f
`
console.log(text)
}
}()
a
b
c
d
e
f
b
c
d
e
f
インデントがそのままでるのでこうなります
これをどうにかしたくてこう書けるようにしてみます
!function(){
if(1){
var text = alignFirst `
a
b
c
d
e
f
`
console.log(text)
}
}()
if(1){
var text = alignFirst `
a
b
c
d
e
f
`
console.log(text)
}
}()
a
b
c
d
e
f
b
c
d
e
f
コードはこうなりました
function alignFirst(parts, ...pieces){
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
では とりあえずこのコードを align-first.js というファイル名で保存します
このファイルを公開する用のフォルダを作って入れておきます
-- align-first\
-- align-first.js
-- align-first.js
node.js で使える形にする
npm は node.js のパッケージなので node.js で使える形にしますいまだに ES2015 の ES module が使えるようになったという話は聞かないので これまでどおりの node.js の module の作り方にします
export したいデータを exports のプロパティに設定します
exports オブジェクトが require したときの返り値になります
function alignFirst(parts, ...pieces){
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
exports.alignFirst = alignFirst
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
exports.alignFirst = alignFirst
最後の行が増えただけです
require で動くか確認します
同じ align-first フォルダの中に require-test.js というファイルを作って
const align_first = require("./align-first")
const alignFirst = align_first.alignFirst
if(1){
const text = alignFirst `
a
b
c
d
`
console.log(text)
}
const alignFirst = align_first.alignFirst
if(1){
const text = alignFirst `
a
b
c
d
`
console.log(text)
}
node で実行します
C:\Users\user\Desktop\align-first>node require-test.js
a
b
c
d
a
b
c
d
ちゃんとロードできています
最初に
align_first.alignFirst
とやっていますが これは exports のプロパティに alignFirst を入れていて require した返り値は exports 自身になるからです
exports 自身を alignFirst にしてしまえばもうちょっと短くできますが 将来的に関数増やしたいときに使い方が変わるのでこうしてます
一応公開する以上 使い方が変わるのはできるだけ避けたほうがいいと思うので 1 つしかプロパティなくてもこうしてるパッケージは結構あると思います
どうしても require の返り値を関数にしたいなら
module.exports = alignFirst
とすれば
const text = require("./align-first")`
a
b
`
a
b
`
こう使えます
ブラウザでも使えるようにする
個人的にはブラウザで使うほうが多いのでブラウザでも動くようにしておきますmodule だと module のトップレベルで定義しても global ではないのですが ブラウザではそうはいかないので export するもの以外見えないようにします
!function(){
function alignFirst(parts, ...pieces){
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
typeof exports !== "undefined" && (exports.alignFirst = alignFirst)
typeof window !== "undefined" && (window.alignFirst = alignFirst)
}()
function alignFirst(parts, ...pieces){
const lines = join(parts, pieces).split("\n").slice(1, -1)
if(lines.length === 0) return ""
const indent = lines[0].length - lines[0].trimLeft().length
const re = new RegExp(String.raw `^\s{0,${indent}}`)
return lines.map(e => e.replace(re, "")).join("\n")
}
function join(arr, betweens){
var g = loop(betweens)
return arr.reduce((a, b) => a + g.next().value + b)
}
function* loop(arr){ while(true) yield* arr }
typeof exports !== "undefined" && (exports.alignFirst = alignFirst)
typeof window !== "undefined" && (window.alignFirst = alignFirst)
}()
パッケージ作る
JavaScript 的には準備ができたので公開用のパッケージを作って試しにローカルのパッケージをインストールしてみますパッケージを作ると言っても公開用のフォルダに package.json を置くだけです
{
"name": "align-first",
"version": "1.0.0",
"main": "align-first.js"
}
"name": "align-first",
"version": "1.0.0",
"main": "align-first.js"
}
最低限これだけあれば大丈夫
これで公開用のフォルダがパッケージになります
みんなに使ってもらうことを前提にしてるなら description に説明書いたり script に実行用のコマンド書いたり もっと色々書いた方がいいと思います
https://docs.npmjs.com/files/package.json
あと README 置いたり ですね
手動で書かなくても
npm init
コマンドを実行すると 対話型で色々聞いてくれてそれにそって入力すると コマンドを実行したフォルダに package.json ができます聞かれる項目がちょっと多いのでどこかのパッケージをコピペしてきて それをテンプレートに編集したほうが楽な場合もあります
ローカルインストールする
公開用のフォルダがデスクトップにあるならこんな構造になってるはずです-- デスクトップ\
-- align-first\
-- align-first.js
-- package.json
-- align-first\
-- align-first.js
-- package.json
このパッケージをインストールするために別のフォルダを作ります
-- デスクトップ\
-- align-first\
-- align-first.js
-- package.json
-- test\
-- align-first\
-- align-first.js
-- package.json
-- test\
test フォルダで
C:\Users\user\Desktop\test>npm install ..\align-first
test フォルダの中に node_modules フォルダができて その中に align-first フォルダがあるはずです
試しに test フォルダに test.js ファイルを↓の中身で作ります
const align_first = require("align-first")
const alignFirst = align_first.alignFirst
if(1){
const text = alignFirst `
a
b
c
d
`
console.log(text)
}
const alignFirst = align_first.alignFirst
if(1){
const text = alignFirst `
a
b
c
d
`
console.log(text)
}
実行してみると
C:\Users\user\Desktop\test>node test.js
a
b
c
d
a
b
c
d
ちゃんと動きますね
公開する
ローカルで問題無いことを確認したらアップロードして完了ですまずは npm にサインアップします
ユーザ名とパスワードとメールアドレスくらいのシンプルなものです
メールアドレスは公開されるので注意です
メールアドレスに送られてきたリンクをクリックする必要もないので 見た人が間違ってメールしてしまうことがない明らかなダミーアドレスを入れておいても問題はなさそう
そのまま 公開まで web で出来るのかと思っていたらどこにもボタンがなくて調べてみると npm コマンドが必要でした
最初は npm adduser でアカウント設定が必要です
C:\Users\user\Desktop\align-first>npm adduser
Username: username
Password:
Email: (this IS public) mail.address@mail.address
Logged in as username on https://registry.npmjs.org/.
Username: username
Password:
Email: (this IS public) mail.address@mail.address
Logged in as username on https://registry.npmjs.org/.
対話型でユーザ名とパスワードとメールアドレスを聞かれます
メールアドレスはサインアップしたものと違っても大丈夫でした
終わったら npm publish コマンドで公開できます
C:\Users\user\Desktop\align-first>npm publish
+ align-first@1.0.0
+ align-first@1.0.0
最後に npm install でインストールされることを確認しておしまい
C:\Users\user\Desktop\test>rmdir node_modules /S /Q
C:\Users\user\Desktop\test>npm install align-first
C:\Users\user\Desktop\test>npm install align-first
※ 実際にはこのパッケージを公開してないので探しても見つかりません
adduser ができていない状態で publish してしまってもエラーになるだけです
メッセージにあるように npm adduser しましょう
C:\Users\user\Desktop\align-first>npm publish
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "publish"
npm ERR! node v6.10.1
npm ERR! npm v3.10.10
npm ERR! code ENEEDAUTH
npm ERR! need auth auth required for publishing
npm ERR! need auth You need to authorize this machine using `npm adduser`
npm ERR! Please include the following file with any support request:
npm ERR! C:\Users\user\Desktop\align-first\npm-debug.log
npm ERR! Windows_NT 6.1.7601
npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\bin\\npm-cli.js" "publish"
npm ERR! node v6.10.1
npm ERR! npm v3.10.10
npm ERR! code ENEEDAUTH
npm ERR! need auth auth required for publishing
npm ERR! need auth You need to authorize this machine using `npm adduser`
npm ERR! Please include the following file with any support request:
npm ERR! C:\Users\user\Desktop\align-first\npm-debug.log
まとめ
公開したいもの作る↓
nodejs で require 出来る形にする(ブラウザでも同じコード使うなら window へのエクスポートも)
↓
公開用フォルダに package.json をおいて最低限の設定を書き込む
↓
(初めてなら) npm にサインアップ (web) して npm adduser で登録したユーザ情報を npm に設定 (コマンド)
↓
package.json のあるところで npm publish コマンドを実行して公開
まとめるとすごく簡単にできるようになってます
おまけ
どうして module.exports を書き換えれるのに exports をそのまま書き換えれないの?とか
module のトップレベルで定義したのが global にないの?
って思う人はこちらをどうぞ
Node.js 7 が出てたのでなんとなく module の読み込みを調べてみた
簡単にいってしまうと
(function (exports, require, module, __filename, __dirname) { 【ここにファイルの中身】\n});
として実行されてるから というだけですけど