Angular Libraryでハマったこと
現在携わってるプロダクトで、Angular CLIのライブラリ作成機能をつかうことにしたので、その時ハマったことを紹介。
Angular Library
Angular CLIにはアプリケーションを作る機能だけでなく、アプリケーション内で使うライブラリを作成する機能があります。
作り方は簡単で my-lib
というライブラリを作りたいなら
$ ng generate library my-lib
このように ng generate
コマンドでライブラリ用のprojectを生成することができます。
作成したライブラリはビルドしてから各アプリケーションで参照する形で使用します。
また、npmにも簡単に公開できる仕組みも用意されています。
詳しくは Creating Libraries を見てみてください。
ハマったこと
何点かlibraryを作る上でハマったポイントがあったのでそれを紹介します。
moment
ビルドしたらmomentがないよ!って怒られました。
BUILD ERROR Cannot call a namespace ('moment') Error: Cannot call a namespace ('moment')
momentに限らず import * as xxx from 'xxx'
でimportしてるライブラリはビルド時に怒られます。
その場合は、このようにするとビルドがとおります。
import * as _moment from 'moment' const moment = _moment type Moment = _moment.Moment
ただ、これだけだとビルドは通るようになりますが、以下のようなWarningはでてしまうます。
No name was provided for external module 'moment' in output.globals – guessing '_moment'
このwarningは ng-package.json
に以下を追加すると解消します
{ ... "lib": { ... "umdModuleIds": { // これを追加 "moment": "moment" } } }
index.ts
index.ts
にディレクトリ内のすべてのファイルをexportして、rootにおいてある public-api.ts
はそれ参照するようにしていたのですが、これだと何故かlibraryを利用しているアプリのproductionビルドが通りませんでした。(library自体のビルドはできます)
ERROR in : Unexpected value 'XXXModule in xxx/xxx.d.ts' imported by the module 'YYYModule in yyy.module.ts'. Please add a @NgModule annotation.
index.ts
を作るのをやめて、各ディレクトリに public-api.ts
をおいて、それを参照するようにしたらビルド通るようになりました。
ただ、Angular MaterialとかNG-ZORRO など他のライブラリを見ると index.ts
があるので、もしかしたら方法があるのかもしれません。
tsconfigのpaths
Angular libraryをnpmに公開せず、内部だけで使用する場合、以下のフローになります。
ライブラリをビルド→/distなどに配置→各アプリケーションは/distにあるライブラリを参照。
この/distのものを参照するためにTypescriptのパスマッピングという機能を使うことになります。これはtsconfigのpathsの設定で行います。
{ "compilerOptions": { "paths": { "my-lib": ["/dist/my-lib"], "my-lib/*": ["/dist/my-lib/*"] } } }
このように定義しておくとアプリケーション側は
import { XXX } from `my-lib`
と、このようにimportできるようになります。
ただ、このパスマッピングの設定で気をつける点があります。
それはライブラリにあるpackage.jsonの name
に設定しているライブラリ名とパスマッピングで実際importすることになる名称を揃えないと、利用側のアプリのProductionビルドで失敗します。
例えば、package.json
で
{ "name": "xxx-my-lib" }
という名前をつけたのであれば、
{ "compilerOptions": { "paths": { "xxx-my-lib": ["/dist/my-lib"], "xxx-my-lib/*": ["/dist/my-lib/*"] } } }
と、このようにしないと、アプリケーションのビルド時にエラーになります。
Angularでpugを使用するのをオススメしない理由
最近とある理由から既存のAngularアプリのテンプレートをpugからhtmlに戻しました。その理由を書こうと思います。
続きを読むReact v16.2 ~ v16.7で入った新機能
ここ1年ぐらい古いverのReactで開発し続けていて、最近ようやく最新のReactに対応したのでここ1年ぐらいでどんな機能が追加されてのかまとめてみることにしました。
※ v16.5, v16.7は大きな機能追加がなかったみたいなので書いてないです
続きを読む