社内で無限スクロールの実装したいって話があり、そのぐらいならライブラリ化しちゃっていいのでは。と軽い気持ちでやったら結構ハマったのでまとめておきます。
作ったもの
ComponentをAoT対応させつつjsファイルとして出力するまで
必要なパッケージをインストールする
$ yarn add -D @angular/{compiler-cli,compiler,common,core} rxjs typescript
画面確認するならもっと色々必要ですが、ライブラリとしてComponent作るだけの最低限ならこれでOKです
トランスパイルの設定
以下のようなtsconfig.jsonを用意する
{
"compilerOptions": {
"target": "es5",
"module": "es2015",
"sourceMap": true,
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"declaration": true,
"outDir": "dist",
"lib": [
"dom", "es2015"
]
},
"include": [
"src/index.ts"
],
"angularCompilerOptions": {
"genDir": "aot"
}
}
ポイントは以下
- module: es2015にして、トランスパイル結果でもimport/exportが利用されている状態にする
- declarationをtrueにしてd.tsファイルを出力させる
- includeで自分のライブラリのみをトランスパイル対象とする
- node_modules/内のものが混ざってくると困るので
-
@angular/compiler-cli
用のオプションで、AoTコンパイル結果の出力フォルダを指定
以上の設定で、型定義ファイルとともに、AoT用のmetadata.jsonを持った状態でdist
ディレクトリに結果が吐き出されます
Componentの書き方
こんな感じ。
import { NgModule, Component } from '@angular/core';
@Component({
selector: 'app-hoge',
template: `<div>hello npm package</div>`,
})
export class HogeComponent {}
@NgModule({
declarations: [HogeComponent],
exports: [HogeComponent]
})
export class HogeModule { }
@NgModule
のexports
でライブラリとして公開したいComponentを指定するのがポイント。
ライブラリとしてじゃなくても、自前でModule単位で分けたい場合もこういう書き方になりますね。
利用側はHogeModule
を@NgModule
のimport
に指定してあげればOKです。
AoTコンパイルを実施する
$ $(npm bin)/ngc
これで成果物がtsconfig.jsonのoutDir
で指定したディレクトリに吐き出されます(今回の設定の場合はdist/
)
動作確認用のexample作成
あんまり余計な事はせず、最低限だけで済ませたいですね。
こんな感じのパッケージ構成になると思います
{
...略
"devDependencies": {
"@angular/common": "~2.4.0",
"@angular/compiler": "~2.4.0",
"@angular/core": "~2.4.0",
"@angular/platform-browser": "~2.4.0",
"@angular/platform-browser-dynamic": "~2.4.0",
"@sisisin/ng-infinite-scroll": "file:../",
"core-js": "^2.4.1",
"lite-server": "^2.2.2",
"rxjs": "5.0.1",
"ts-loader": "^2.0.1",
"typescript": "^2.2",
"webpack": "^2.2.1",
"zone.js": "^0.7.4"
}
}
exampleはプロジェクトのルートにexample/ディレクトリを置いて作成を想定しています
以下ポイント。
- npmではfile system上のnpm packageを指定する事が可能です.
-
"@sisisin/ng-infinite-scroll": "file:../"
がそれ。 - ちなみに、npmのdocumentのとおりに
npm install -D ../
とすると、フルパスが入ってきてしまうので注意が必要です - さらに注意が必要な点として、yarnを利用すると
.npmignore
の指定を無視して対象のディレクトリをまるっと持ってきやがります- そのせいで余計なtsファイルが混ざってコンパイル通らなくなったりします
-
- このくらい軽い感じなら、といってsystemjsに手を出さない
- 情報も少ないし普段触らないのでまじハマって辛かった
- (用途的にはこういうので使うのが一番よさそうと思ったんですけどね。。。
publishする
package.jsonのprepublishにビルドスクリプトを定義しておいて、npm publish --access=public
!
さいごに
大枠こんな流れで公開まで漕ぎ着けられました。
Component書く時間より環境構築に時間がひたすらかかったのはザ・Angularって感じでしたね!