npmパッケージを公開していざ使おうと思ってもimportできなかったので調べたこと
こちらの記事でも書きましたが、アメーバのような形状をp5.jsで作り、generatorも公開しました。この記事はこれを機にこのアメーバーの生成をnpmパッケージにして公開してみようと思い、公開方法を調べた記録です。HowToではないです。つまづいた点などの記録ですので、作り方などは私も参考にしていた以下の方の記事が良いと思います。
参考
初めてのnpm パッケージ公開
3分でできるnpmモジュール
公開用のフォルダ
パッケージの作り方を参考にして、npmにアカウント登録とpackage.jsonにライブラリ情報を記入し、npm publish
で公開するところまでいけました。公開するフォルダの中身はwebpackでアプトプットしたデータです。package.jsonに以下を記入すると、プロジェクトディレクトリの中のデータが、例えば他のプロジェクトでnpm install p5-ameba
とインストールした時にnode_modulesに入ってきます。
...
"files": [
"README.md",
"lib"
]
...
上の例だと、README.mdとlibフォルダにあるデータですね。なので、使い手がimport ameba from 'p5-ameba'
とした時に必要なデータを書き込めば良いと思います。このp5-ameba
はパッケージのname
fieldで決められるので、lib
フォルダの中にp5-ameba.js
のようなファイルを用意する必要はないです。それで、npm install p5-ameba
とした時に読み込むjsファイル
は、package.jsonのmain
fieldで指定します。
...
"name": "", <- npm install するときの名前
"main": "", <- importした時に読み込むファイル
"files": [] <- node_modulesに入るファイルを指定
...
公開してもimportで読み込めない
なんとかパッケージを公開してみて、いざ使ってみようと思い、別プロジェクトで実際にnpm install p5-ameba
とし、jsファイル
からimport ameba from p5-ameba
とやってみました。すると、以下のエラーが出て読み込みができません。
Uncaught SyntaxError: Unexpected identifier
開いた口が塞がりません。。。まだまだフロントエンドの勉強中なので、おそらく何かの知識が抜け落ちてるか、何となくの知識で使っている何かが原因だと思います。ただ、用語が多すぎたりでまだ自分の技術にできていません。仕方がないので、少しづつ原因を追っていきました。
確認作業
- 開発環境で配布したライブラリが本当に使えているのかを確かめる -> 使えた
- 配布したライブラリを、新しいプロジェクトで直接読み込んでみる -> 使えた(要は開発環境と同じ)
- 配布したライブラリを、
node_modules
から読み込む -> エラー
つまり、node_modulesにある状態だとなぜか読み込まれないことが分かりました。ほかのnpmパッケージのライブラリはimport
しても使えているので、node_modules
にデータを置く過程か、データそのものに原因がありそうです。作成したライブラリはES2015
で書いているため、もしかしたらbabel
とかwebpack
も含めてこの辺りの知識の曖昧さが原因なのでは?と思い調べてみました。怪しいのはwebpackでアウトプットしたデータです。
他のパッケージの作りを研究
作成したアメーバーのアニメーションライブラリは、animejs
というライブラリの構成をかなり参考にしています。初期化時にパラメータを指定するなど。なので、このanimejsのパッケージはどのような作りになっているのか調べました。
Usage
- ES6 modules
- CommonJS
- File include
パッケージの使い方で、ライブラリの使用方法が上記の3方法あります。このうち、CommonJS...???と恥ずかしながら私はこの用語を知りませんでした。。。少し調べてみると、
CommonJS
- モジュール管理の規格のひとつ。
-
require(<モジュール名>)
でライブラリを読み込む仕様。 - この記事が参考になりました。
- node.jsでも使用する場合は必須のよう
これを踏まえてanimejsのpackage.jsonを見てみると作りは以下になっています。
"umd:main": "lib/anime.min.js",
"module": "lib/anime.es.js",
"main": "lib/anime.js",
"files": [
"lib"
],
main
にumd:
とついてますが、UMDとはUniversal Module Definitionの略で、以下のように定義されています。(GitHubより抜粋)
The UMD pattern typically attempts to offer compatibility with the most popular script loaders of the day (e.g RequireJS amongst others). In many cases it uses AMD as a base, with special-casing added to handle CommonJS compatibility.
また不明な用語、、、AMDとはAsynchronous Module Definitionの略で、モジュールを非同期で読み込むため規格のようです。CommonJSの規格を非同期で読み込むための仕様。。。かな。それともう一つ、module fieldがあり、これの読み込み先のファイルがES2015基準のファイルを指していました。npmの仕様には
The main field is a module ID that is the primary entry point to your program. That is, if your package is named foo, and a user installs it, and then does require("foo"), then your main module’s exports object will be returned.
This should be a module ID relative to the root of your package folder.
For most modules, it makes the most sense to have a main script and often not much else.
このように書かれてあり、どうやらmain fieldにはCommonJS規格のファイルを指定する必要があるようです。ではこのmodule
fieldは何だろうとしらべてみると、こちらに詳しく書いてありますが、
"module"フィールドに書くファイルパスは名前のとおりECMAScript モジュール形式のコードで、このコードはimport/exportのままのコードを配置します。webpackなどのbundlerは"module"フィールドが存在する場合はそちらを優先して読み込みます。
ES2015形式で書かれたコードのファイルを指定するfieldのようです。
CommonJS用にライブラリを書き出す
ライブラリを作成したのはES2015形式なので、これをCommonJSのファイルとして扱えるように書き出す必要があります。webpackでoutputしただけのファイルは、ライブラリのモジュールとしては使えないようです。やはりこれが読み込みができない原因と言えそうです。
ライブラリ用にビルドする
私が使っていたwebpackの設定はjsなどのアセットをまとめて、ブラウザで読み込める形に書き出すことはやりますが、ライブラリ用のモジュールとして書き出すことはしません。webpackでもライブラリ用にビルドする設定はあると思いますが、他にも調べてみるとRollupというモジュールバンドラがライブラリ開発に適しており、CommonJS形式に変換できるようです。基本的にこちらの記事を参考にすると変換までできます。記事元ではアウトプットのフォーマットがcjs
とCommonJSのみの変換になっていたので、これでも良いと思いますが、今回私が参考にしたanimejs
のパッケージはumd
規格のファイルになっていたので、私もこれに習ってumd
規格のファイルを作りました。
export default {
input: './lib/ameba.es.js',
output: [{
file: './lib/ameba.js',
format: 'umd',
name: "p5-ameba"
}],
external: [
'p5'
]
};
formatのfieldのプロパティをumd
に変えただけです。これでビルドして、CommonJSファイルを作り、ようやくnpmパッケージが使えるようになりました。
Conclusion
まだまだフロントエンドは分からないことが多く知らない用語がたくさんあります。それでも調べながらコツコツやっていくとレベルアップできるのではないかと感じました。このamebaライブラリはあまり役に立つものではないですが、パッケージ配布までの全体像が掴めたことは自分にとっては収穫です。その中で知らない単語を少しずつ吸収していけました。
ちなみに、ライブラリを開発していく中で、作ったライブラリを試すのにイチイチnpm publish
とやって公開してから別プロジェクト作ってnpm install p5-ameba
とやって確認作業していましたが、開発中のライブラリを擬似的にnode_modules
に入れて確認できるようです。
npm link p5-ameba <- node_modulesにいれる
npm unlink p5-ameba <- node_modulesから外す
Author And Source
この問題について(npmパッケージを公開していざ使おうと思ってもimportできなかったので調べたこと), 我々は、より多くの情報をここで見つけました https://qiita.com/mitsuya_bauhaus/items/a3a725f203f88cd3daf0著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .