OSS/ライブラリってどう調べて導入するの？ (moment.jsリプレースを通して)


# はじめに
世の中にはたくさんのOSSで溢れています。
そしてOSSには流行り廃りがあります。
昨日までデファクトスタンダードだったOSSが今日では斜陽となる可能性すらあります。
エンジニアはその中でどうやってOSSを調査し自プロダクトに取り入れているのでしょうか？
今回はそんなOSSに関わる業務の際に自分がどう進めているのかまとめたいと思います。

# 本記事
- 実際に業務で開発したこと無い初心者エンジニア向けに実務の開発の流れを具体例を用いて解説
- 今回は日付時刻操作ライブラリである moment を date-fns でリプレースする作業をやっていきます

# 対象読者
web 開発をしたい初心者エンジニア
OSS調査の流れを知りたいエンジニア

# リプレイスするコード
```javascript:moment.js
import moment from 'moment';

function getStartTime() {
    return '2022/07/01 15:22';
}

const start_time = moment(getStartTime(), 'YYYY/MM/DD HH:mm');
const now = moment();

if (start_time < now) {
    console.log(`${start_time} はすでに始まっています`);
} else {
    console.log(`${start_time} はまだ始まっていません`);
}
```

今回はこちらをリプレイスしていきます。
受け取った文字列の時間が現在より過去か未来か否か判定するコードです。
ちょっとなんのためにあるのか分からないですがこれでやって行きます。(さらっといい感じのサンプルコード作れる能力ほしい...)
ちなみにこちらを実行すると
```
$ node moment.js 
Fri Jul 01 2022 15:22:22 GMT+0000 はまだ始まっていません
```
こんな感じで moment が日付オブジェクトに変えて送っていますね

# momentjs とは

https://qiita.com/yun_bow/items/622ec62d04fc69855e1e

こちらの記事に詳しいですが、javascript の日付操作をいい感じにやってくれるライブラリのようです。
だたこちら現在は開発が終わってしまい別のライブラリを使用することが推奨されています

>We now generally consider Moment to be a legacy project in maintenance mode. It is not dead, but it is indeed done.
https://momentjs.com/docs/ より引用

# リプレース
ここから実際にリプレース作業をしていきます。
先に手順を説明すると
1.  リプレース対象の公式ドキュメントを読む
2.  代替ライブラリを調べる
3.  とりあえず導入してみる
4.  doc 見ながらリプレイスする
5.  momentjs を omit する 

## リプレース対象の公式ドキュメントを読む
まずはじめにすることは **「公式ドキュメントを読む」**
誰もが口を酸っぱくして言うことですがまずリプレース対象を知らなければ始まりません。
moment の[公式 doc](https://momentjs.com/docs/) を読みましょう
ちなみに先程の 「momentjs とは」のような調査をすれば気がつけば、どういうものか、なぜリプレイスが必要なのか掴めてきます。
ここではあくまで概要をつかむことが目的です
あまり深掘りしすぎて時間を使いすぎないように注意しましょう

## 代替ライブラリを調べる
リプレイスする原因や概要を掴めたところで新たな代替手段に何があるか調べましょう

npm trends: https://www.npmtrends.com/

を使うのがおすすめです
https://www.npmtrends.com/date-fns-vs-luxon-vs-moment-vs-dayjs
今回だと有名なライブラリはこのあたりですかね。

ではこの中の date-fns を実際に使ってみましょう

※今回は OSS の調査から実装の流れに着目しているため時刻表示ライブラリのうちどれが優れているかという点には触れないので悪しからず

## とりあえず導入してみる
結構大事だと思っている考え方です
慣れていないと開発プロダクトにライブラリを入れてしまうことに抵抗があるかもしれません。
しかし自分の環境であれば何をやってみても問題はないはずです(それこそ開発環境のあるべき姿)
積極的に使ってみましょう

### date-fns 導入
```bash
$ yarn add date-fns // npm 使っていればそっち使う
```

## doc 見ながらリプレイスする
それでは実際に[公式ドキュメント](https://date-fns.org/)を使ってみながらリプレイスしてみます

### method 調査
```javascript
moment(getStartTime(), 'YYYY/MM/DD HH:mm:ss');
```
まずはこちらのコード。何をしているかというと受け取った日付の文字列を日付型 obj に変えています
これと同じことができる date-fns の method を探してみましょう
https://date-fns.org/v2.28.0/docs/parse
それっぽい`parse` という method がありました

```javascript
// Parse 11 February 2014 from middle-endian format:
var result = parse('02/11/2014', 'MM/dd/yyyy', new Date())
//=> Tue Feb 11 2014 00:00:00
```

例を見る限り同じようなことができそうですね！

### parse method 使ってみる
早速コードを書き換えてみましょう
```javascript
import moment from 'moment';
import { parse } from 'date-fns'; // 追加

function getStartTime() {
    return '2022/07/01 15:22';
}

// const start_time = moment(getStartTime(), 'YYYY/MM/DD HH:mm:ss');
const start_time = parse(getStartTime(), 'YYYY/MM/DD HH:mm', new Date());　
console.log(start_time); // 出力を見るために追加
const now = moment();

if (start_time < now) {
    console.log(`${start_time} はすでに始まっています`);
} else {
    console.log(`${start_time} はまだ始まっていません`);
}
```

実行してみる
```bash
$ node moment_replace/moment.js 
RangeError: Use `yyyy` instead of `YYYY` (in `YYYY/MM/DD HH:mm`) for formatting years to the input `2022/07/01 15:22`;
```
おっとなにやらエラーが出ましたね。どうやら `yyyy` という日付コードが間違っていて `YYYY` という大文字使えと言われました。

#### 日付コードはライブラリによって変わる
どうやら日付コードは導入するライブラリによって変わるようです
ではもう一度 moment, date-fns のドキュメントを見て日付コードがどのようになっているのか調べてみましょう

- moment https://momentjs.com/docs/#/parsing/string-format/
YYYY / 2016 / 4 or 2 digit year. Note: Only 4 digit can be parsed on strict mode
D DD / 1..31 / 	Day of month

- date-fns https://date-fns.org/v2.28.0/docs/parse
YYYY　/ 0044, 0001, 1900, 2017 / Local week-numbering year
DDD / 001, 002, ..., 365, 366 / Day of year

一部だけ抜粋しましたが結構変わるようですね、、、
ではこれを踏まえてもう一度実装してみましょう

```javascript
const start_time = parse(getStartTime(), 'yyyy/MM/dd HH:mm', new Date());
```

こちらで動くコードになったと思います。また現在時刻は以下のようにして取得します
```javascript
const now = new Date();
```

最終的なコードは以下になります

```javascript
import { parse } from 'date-fns';

function getStartTime() {
    return '2022/07/01 15:22';
}

const start_time = parse(getStartTime(), 'yyyy/MM/dd HH:mm', new Date());
const now = new Date();

if (start_time < now) {
    console.log(`${start_time} はすでに始まっています`);
} else {
    console.log(`${start_time} はまだ始まっていません`);
}
```
実行すると問題なく動くと思います

### momentjs を omit する 

で入らなくなった moment を omit しましょう
```bash
$ yarn remove moment
```
ここまでできて PR として出せる状態になったのではないでしょうか。
これでOSS調査からリプレイスまですべての作業が終わりました。

## まとめ
- まず公式ドキュメントを読むこと
- とりあえず導入してみる
- この2つの考え方を進めていけば自身のゴールへの道が開けるのではないかと思います