昨日以下のようなブログを書いた。
この投稿ではlicense-checker
というツールを使って利用しているOSSライブラリの一覧とライセンス情報を出力し、それを読み取って画面に出力するという内容だった。
だがしかし、前回の投稿の最後に書いたようにとても重いのである。
なんかダサいし重いのでもうちょっと考えよう。。。
出力されるファイルが1万行近いものだったため、都度読み込んで表示するにはとても重い状態だったのである。ファイルの中身を見るとbabel関連などが--production
で指定しているにも関わらず出力されていた。また、--direct
というオプションを指定していたにも関わらずそれがあまり機能していないというIssueもあって未解決のようだった。
というわけで、前回の選定時には落としたnpm-license-crawler
というのを試してみた。
これはlicense-checker
同様にnpmをスキャンしてJSONで結果を出力してくれるというものだが、license-checker
ほどは利用されていないようだ。確かに出力するJSONの内容のカスタマイズなどはlicense-checker
のほうに分がある。
だがしかし、license-checker
の--direct
オプション相当の--onlyDirectDependencies
というオプションがあり、先ほどのIssueではこれが機能しているということだった。
というわけで早速試してみる。今回はyarn global add
でインストールせずにnpxで実行する。
npx npm-license-crawler --dependencies --production --onlyDirectDependencies --omitVersion --json ./src/licenses.json
--omitVersion
てのは出力にバージョン番号を含まないという指定。
そしてこの出力結果は以下のような感じである。
{ "@react-native-community/async-storage": { "licenses": "MIT", "repository": "https://github.com/react-native-community/react-native-async-storage", "licenseUrl": "https://github.com/react-native-community/react-native-async-storage/raw/master/LICENSE", "parents": "patrolcommunity" }, "@react-native-community/masked-view": { "licenses": "MIT", "repository": "https://github.com/react-native-community/react-native-masked-view", "licenseUrl": "https://github.com/react-native-community/react-native-masked-view", "parents": "patrolcommunity" }, "@react-native-community/slider": { "licenses": "MIT", "repository": "https://github.com/react-native-community/react-native-slider", "licenseUrl": "https://github.com/react-native-community/react-native-slider", "parents": "patrolcommunity" }, "@react-navigation/bottom-tabs": { "licenses": "MIT", "repository": "https://github.com/react-navigation/react-navigation", "licenseUrl": "https://github.com/react-navigation/react-navigation/raw/master/LICENSE", "parents": "patrolcommunity" }, 以下略
以下略としたがlicense-checker
の出力と異なりbabel関連が出力されていないだけでなく全体的に直接的な依存関係にあるもの以外は出力されていないようだ。サイズ的にも300行ちょっととだいぶスリムになった。
残念ながら、license-checker
ではライセンスファイルの中身そのものも出力できていたのだがそれはnpm-license-crawler
ではできない模様。
というわけで、これを表示する処理は以下のように変更した。
import React from 'react' import { Container } from 'native-base' import { StyledScrollView, StyledView, NameText, LicenseText } from './styled' import HyperLink from 'react-native-hyperlink' import { Linking } from 'react-native' interface LicenseFile { [key: string]: any } export const LicenseScreen: React.FC = () => { const licenseFile: LicenseFile = require('../../licenses.json') const licenseKeys = Object.keys(licenseFile) return ( <Container> <HyperLink linkStyle={{ color: '#0071C8' }} onPress={(url: string): void => { Linking.openURL(url).catch((err) => console.error("Can't open the url.", err) ) }} > <StyledScrollView> {licenseKeys.map((packageName: string) => { const license = licenseFile[packageName].licenses const licenseUrl = licenseFile[packageName].licenseUrl return ( <StyledView key={packageName}> <NameText>{packageName}:</NameText> <LicenseText>{license}</LicenseText> <LicenseText>{licenseUrl}</LicenseText> </StyledView> ) })} </StyledScrollView> </HyperLink> </Container> ) } export default LicenseScreen
基本的には前回とほぼ同じ内容でJSONの出力内容が少し異なるのでそれにあわせてプロパティ名を変更したくらい。ただし、TypeScriptの場合はJSONファイルを直接importしてmapで扱おうとすると以下のようなエラーが出る。
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type No index signature with a parameter of type 'string' was found on type
というわけでちょいちょいと型を定義してあげて、それを指定してimportではなくrequireで読み込むことにした。あとは前述のとおりnpm-license-crawler
はライセンスファイルの中身そのものは出力してくれず、ライセンスファイルへのURLのみなので画面上もURLを表示してハイパーリンクを設定してブラウザで表示してもらうようにするためにreact-native-hyperlink
でまるっと囲みつつonPress()
でLinking.openURL
を使ってブラウザでタッチされたURLを表示するようにした。
というわけでだいぶ軽くなったのでこれなら都度JSONを読み込んでもまあ使用に耐えうるということでいったんこれで行くことにした。
本当はビルドのタイミングで処理したりするのがいいんだろうけど。