Try T.M Engineer Blog

多摩市で生息するエンジニアが「アウトプットする事は大事だ」と思って始めたブログ

新年早々Vue.jsのSPA/SSR/SSGを整理してみた話

はじめに

明けまして、おめでとうございます。
まだまだコロナで苦しい日々が続きますが、皆様頑張ってのりきりましょう(T T;;

さて、新年早々(ホントは年末から)、Vue.jsを使ってSSR、SSGで作るのってどうするんだ?と思って、色々調べてたので、調べたことを纏めて書いておこうと思います。
SPA、SSRの定義から曖昧な人なので、定義から確認していくこと・・・

SPA vs SSR

  • SPA(Single Page Application) ・・・ 1つのHTML内でコンテンツのみを切り替えるアプリケーションのこと。
  • SSR(erevr Side Rendering) ・・・ コンテンツ毎にサーバー側でHTMLを生成してブラウザに返す仕組みのこと。

SPAの場合、コンテンツの切り替えをブラウザ側のJavaScriptを使って行うため、必ずしもサーバーが必要というわけではありません。
SSRの場合、HTMLをサーバーサイドで生成する必要があるため、必ずサーバーが必要になってきます。

f:id:special-moucom:20210103001142p:plain

どうしてSSRが必要なのか?

SSRを使う理由の1つとして「SEO」が上げられます。

クローラーは、完全に描画されたページ(HTML)を直接解析しています。
そのため、SPAのようなJavaScriptを使ってコンテンツを切り替えているようなページ(HTML)は、クローラー側で正しくページを評価できない(正確には、JavaScriptを正しく実行して、切り替えたコンテンツを解析してくれているかわからない)という問題があります。

とはいえ、昨今ではクローラーの機能も向上しており、今後はSPAで作られたページ(HTML)でも正しく評価されるようになると思われます。
それまでは、「SEO」を重視するのであればSSRが必要となります。

もう1つの理由は、JavaScriptのダウンロード時間です。

SPAは、JavaScriptを使ってコンテンツを切り替えるため、JavaScriptの容量が大きくなりがちです。
そうなると、JavaScriptのダウンロードに時間が掛かり、クローラーの評価を落とす要因になります。

こういった観点からもSSRが必要になってくるケースは多いと思われます。

SSR vs SSG(プリレンダリング(事前描画))

Vue.jsでは、「SEO」目的でSSRするなら、SSG(プリレンダリング(事前描画))がオススメですよ。と書いてある。

SSR vs プリレンダリング (事前描画)

もしあなたが、幾つかのマーケティングのページの SEO を向上させるためだけに SSR を調べているとしたら (たとえば /, /about, /contact など)、代わりに プリレンダリング (事前描画) を使用することをオススメします。 
HTML を急いでコンパイルするために Web サーバーを使用するのではなく、プリレンダリングは、ビルド時に特定のルートに対して静的な HTML ファイルを生成します。
利点はプリレンダリングを設定する方が遥かに簡単で、フロントエンドを完全に静的なサイトとして保つことができることです。

プリレンダリングとは事前描画のことで、コンテンツ毎に必要なHTMLを事前に作成しておく仕組みのこと。つまり、Static Site Generator(SSG)。
JavaScriptを使ってコンテンツを切り替えるが、切り替えたコンテンツは事前に作成しておいたHTMLを表示しようというもの。
そのため、必ずしもサーバーが必要というわけではありません。

f:id:special-moucom:20210103001152p:plain

HTMLは事前に作成しているため、クローラーからも正しく評価されるし、JavaScriptの容量も大きくなり辛いので、ちょうどSPAとSSRの良いとこ取りみたいな感じですね。

SSRを再評価してみる

じゃあ、これからはSSRではなく、全部プリレンダリングで作れば良いじゃん・・・
とは、大きな声では言えませんがクローラーの機能も向上しているのでSSRのメリットが少なくなっているのは事実です。

SSRは、SPAやプリレンダリングでは得られない以下のようなメリットもあるので、要件によってどれを選択するかを決めたほうがよさそうです。

  • クライアントサイドでAPIを実行してHTMLを生成するよりも、サーバーサイドでAPIを実行してHTMLを生成して表示した方が、クローラー側で正しくページを評価してくれる。
  • コンテンツ表示までの時間を短縮できる。
  • コンテンツのアップロードの度にビルドをする必要がないので、大量ページを必要とする場合にむいている。

また、どうせ裏の仕組み(API等)を作る必要があるのなら、いっそのことSSRにするという選択肢もありますね。
その裏の仕組みもJavaScriptを使って作るアイソモーフィック(Isomorphic)ユニバーサル(Universal)といった単語も最近では良く聞きます。

アイソモーフィックJavaScript

アイソモーフィック(Isomorphic)とは、「同型の」という意味で、クライアントサイドとサーバサイドを同じ言語(JavaScript)を使って実装して、コードの共有を行うこと。 つまり、「JavaScriptを使ってSSRやりましょう」イコール「アイソモーフィックJavaScriptでやりましょう」ということ。

ユニバーサルJavaScript

ユニバーサル(Universal)とは、「全般の」という意味で、クライアントサイドとサーバサイドだけでなく、モバイル端末や組み込みデバイス上まで同じ言語(JavaScript)を使って実装して、コードの共有を行うこと。 アイソモーフィックJavaScriptの考え方をさらに広げようといった意味が込められている。

上記のように、SSRは「SSRで作るメリット」があるので、ケースバイケースでSPA、SSR、SSGを選択しましょう。

最後に

去年末のAdvカレンダーで、Vue.jsのSSGフレームワークGridsomeについて調べたことを書きました。

qiita.com

データソースをGraphQLを使ってアクセスできる面白いフレームワークなので、興味のある方は是非読んでみてください。

さて、個人的な観点で、SPA、SSR、SSGについて、整理してみました。
タイトルに「Vue.jsの」と書きましたが、「Vue.js」の内容はあまり含んでいなかったですね。(Vue.jsのWebサイトから抜粋してきたものが多いですが・・・)

2020年を振り返るのと2021年の抱負について

2020年を振り返りたいと思います。 コロナの影響で生活スタイルに大きな変化があり、そのあたりも踏まえて書いていきたいと思うので、「仕事・プライベート」と(いつもの)「技術」の2つの角度から、2020年を振り返ります。

2020年はどんな年だった?

仕事・プライベート

まずは、2020年の「仕事・プライベート」面から見ていきます。

在宅ワークがメインになった

コロナの影響により、会社のオフィスが縮小して、在宅ワークがメインになりました。会社への出勤時間が無くなったので、その時間は家事・育児に労力を回せるようになりました。 これには、個人的に良い点と悪い点がありました。箇条書きにすると以下の通り。

  • 良い点

    • 家族と一緒にいられる時間が増えた
    • 家事(掃除、洗濯)が捗る
  • 悪い点

    • 子供が保育園から帰ってくると仕事にならない
    • 仕事のオン・オフの切り替えが曖昧
    • (定時以降に行われる)カンファレンスやイベントに参加できない

このあたり、小さな子供持つエンジニアの方々のブログを拝見すると、皆さん同じような意見を持たれる方が多いようですね。
特に辛いのが「子供が保育園から帰ってくると仕事にならない」ところです。
私の場合、仕事で残業が発生するときは、仕事を一旦定時で切り上げ、続きを子供が寝静まった後にします。
これが続くと、時間があれば会社のPC開く習慣ができ、「仕事のオン・オフの切り替えが曖昧」になってしまうという問題があります。

私自身、在宅ワークに憧れを持っていましたが、いざ実践するとなるとなかなか上手くいかないもので、現在進行中で苦労しています。

健康に気を使うようになった

在宅ワークになってから、健康に気を使うようになりました。在宅ワークになってから4、5ヵ月たったある日、体重計にのってみると体重が4、5キロ増えていることに気づき、驚きました。

スマートウォッチを購入して、毎日の歩数を計測してみると、通勤していたときは10000歩以上歩いていましたが、在宅ワークのときは、4000歩以下であることがわかりました。

改めて運動不足であることがわかり、毎日4000歩は必ず歩く様、目標設定することにしました。

※購入したスマートウォッチは、以下。

また、家の椅子がそんなに良いものでは無かったために、腰と首を痛めました。 あまりにも痛かったので、整体(カラダファクトリー)で見てもらうと、いかに自分の姿勢が悪かったのかを指摘されました。

以降、デスク周りのレイアウト(モニターの位置)を調整したり、改めて椅子も購入することにしました。

※購入した椅子は、以下

ブログの更新が止まった

在宅ワークになってから、ブログの更新が停止しました。
理由は2つあり、1つは会社内でブログのようなものを書くようになったこと。もう1つは、私は普段、通勤時間を使ってブログの記事を考えたりしていたのですが、その時間が無くなったことです。

アウトプットが減ったというわけではないのですが、外へのアウトプットは減っているので、このあたりは今後改善を目指したいと考えています。

技術

続いて、2020年の「技術」面を見ていきます。

Laravelに挑戦できた

仕事でLaravelを扱うプロジェクトに参加して、Laravelに触れる機会を頂きました。 その結果、Laravelへの理解がすごく深まった気がしています。

私は以前から上司にLaravelに触れるお仕事がしたいと手を上げていました。 その結果、上司から「こんな仕事もあるけど・・・どう?」みたいな形で、お話があり、すんなりとプロジェクトへ参画することができました。

こういったこともあるので、普段から自分のやりたいことに対して声を上げておくことは、重要だと改めて思いました。

AWSの資格を再取得できた

年初の話ですが、AWSソリューションアーキテクト(アソシエイト)、AWSデベロッパー(アソシエイト)の2つを無事、獲得することができました。 このあたりは、以下記事に纏めています。

kodak.hatenablog.com

WordPressのカスタムブロックを作った

仕事でWordPressを扱う案件で、カスタムブロックを作るお仕事を頂きました。 当時、Gutenbergの情報は少なかったので、作るのに大変苦労しましたが、Reactの理解も深まり、なによりPHPの世界からいきなりJavaScriptの世界に飛び込んだこともあって、作っていてとても楽しかったです。

qiita.com

オブジェクト指向デザインパターンを理解できた

改めて、オブジェクト指向デザインパターンリファクタリングを理解しました。 今までは「概念」だけはわかる状態で置いていたもの達を、ちゃんとした本を読むことで、「概念」から「理解」へ進めることができました。

github.com

kodak.hatenablog.com

2021年はどんな年にしたいか?

仕事・プライベート

さて、続いて2021年をどんな年にしていきたいか?「仕事・プライベート」面から見ていきます。

断捨離とスタイリッシュな仕事空間作り

家にいる時間が増えたので、自分の居場所を快適にしていきたいと思います。 在宅になって、いつでも配達を受け取れるようになったので、捨てようと思っていたPCや粗大ゴミが一気に片付きます。メルカリもやり易くなりました。 これによってストレスも解消されるので、断捨離とスタイリッシュな仕事空間作りを目指したいと思います!

老後について考える

35を過ぎたので、そろそろ老後について考えなくてはならない歳・・・ 「老後2000万円問題」なんてものもありましたね。老後に向けた貯蓄について、少しづつですが考えていきたいと思います。

ブログの継続

継続って難しいですよね。はい。私が一番苦手な分野です。 子供にも言っています。「いきなりはできないよ。何事も、ちょっとづつやることで、できるようになるんだよ。だから、毎日ちょっとづつやろうね。」と・・・ そのちょっとづつが難しいんですよね。 子供に言っているだけに、自分がお手本にならなくてはいけませんね

技術

最後に、2021年をどんな年にしていきたいか?「技術」面を見ていきます。

JavaScriptを得意な言語にする

うちの会社では最近、JavaScriptやTypeScriptができる人を増やしていこう。という目標を立てています。 バックエンドとフロントエンド共に、JavaScriptやTypeScriptでできていれば、コードの流用やフロントエンドの人でもバックエンドのコードが読める等、いろいろとメリットが多いからだそうです。 いわゆる、ユニバーサルやアイソモーフィック的な考え方ですね。

これには、私なりに色々と思うところはありますが、JavaScriptとTypeScriptは理解していないと積むことが多いので、まずは、ちょっとデキルからちゃんとデキルくらいにはなっていきたいと思います。

テストコードが書けるようになる

プログラムを作り終えた後に、テストコードを書くのにはだいぶ慣れてきた気がします。ですが、プログラムを作る時にテストコードを書く(つまり、テスト駆動開発)は、まだできていません。
なので、来年はテストコードをたくさん書いて、テスト駆動開発ができるようになる!そんな年にしたいと思います。

まとめ

2020年はコロナの影響で、大きく色々なことが変化を受けた年でした。 2021年はその変化の対応していく・・・そんな年になりそうです。(= = ;;

Cloud Runについて調べてみた話

AWSだけでなく、GCPについても知識を深めていこうと思い、最近流行りのCloud Runについて調べたことを書いていきます。

Cloud Runとは?

GCPが提供しているサーバレスプラットフォームは以下3つあるが、その内の1つ。

  • Cloud Functions
  • App Engine
  • Cloud Run <- コレ!

中でもCloud Run自分で作成したDockerコンテナをサーバーレス環境で実行できるという特徴を持つ。

GCPが提供しているサーバレスプラットフォームの選び方(使い分け)

GCPのドキュメントに書いてあったので、こちらを転機。
https://cloud.google.com/serverless-options/?hl=ja

Dockerコンテナを動かすという特徴から、好きな言語とライブラリを使って開発したい場合に選ばれることが多い。
それだけでなく、規模や開発容易性からも選ばれることが多そう。。。

料金

https://cloud.google.com/run/pricing?hl=ja

上記に書いていますが、イマイチピンときません。私はお金にうるs(ry
簡単に式にすると、以下になる模様。

  • (呼び出し回数 * Requestの時間) * スペック(CPU/メモリ)

以下の料金シミュレーションをしてみると、(デフォルトスペックなら)1 Request(10秒)を100万回実行しても0円なので、結構リーズナブルなんではないかと・・・ (多分、無料枠分で結構遊べるので、個人開発や個人サイトで運用する分なら、ほぼ無料だと思われる)

https://cloud.google.com/products/calculator?hl=ja

使い方

以下ご参照。
https://cloud.google.com/run/docs/quickstarts/build-and-deploy?hl=ja

試しに実施してみましたが、使用するのはCloud Runだけかと思いきや、他にも以下サービスも使いました。

  • Cloud Build ・・・ コンテナのビルドはココで行う。
  • Container Registry ・・・ コンテナのビルド後のイメージをココで管理する。(イメージファイルはCloud Storageに格納)
  • Cloud Storage ・・・ コンテナのビルド前、ビルド後のイメージファイルはココに格納される。
  • Cloud IAM ・・・ Cloud Runの実行権限等の管理はココ。

Cloud Runへのデプロイまでに、以下ステップを踏む模様。

  • Step.1: Cloud Storageにビルド前ファイルを配置
  • Step.2: Cloud Storageに配置したビルド前ファイルを使用して、Cloud Buildでビルド
  • Step.3: Cloud BuildでビルドしたイメージはContainer Registry管理。ビルド後のイメージファイルはCloud Storageに配置
  • Step.4: Container Registry(ビルドしたイメージ)からCloud Runで起動。権限周りはCloud IAMを使用

Cloud Runへデプロイは直接ではなく、Container Registryから行う流れですね。
このあたりはAWSも同じですね。

上記で記載した料金についても、上記4つサービスすべてに料金(従量課金)が掛かってくるので注意!
とはいえ、無料枠もあるので微々たるものだと思います。
1回しかデプロイしないのであればCloud StorageContainer Registryにあるビルド前ファイルとイメージファイルは削除して良いかもしれません。
(デプロイすればするほどCloud Storageに履歴ファイルが溜まっていくので、このあたりも定期的な削除が必要です)

認証・公開制限

Cloud Runでは、今のところCloud IAMを利用した認証・公開制限しかできません。
つまり、IP制限Basicを利用した制限コンテナ内で行うかCloud Endpoints等の他サービスを利用する必要があり、工夫が必要です。

CDN配信

Firebase Hostingと連携すれば、GCPサービス内で完結できます。

https://firebase.google.com/docs/hosting/cloud-run?hl=ja

まとめ

Cloud Runを使用するにあたり、Cloud Runだけでなく他サービスの理解も必要だと感じました。
とくにCloud IAMの理解は必須。Cloud Endpointsも使えるようになっておくと、さらに便利そうです。
というわけで、引き続き他サービスについても勉強していきたいと思います。(= =)>

『リファクタリング 既存のコードを安全に改善する(第2版)』の感想

著者:MartinFowlerさんの本『リファクタリング 既存のコードを安全に改善する(第2版)』を読んだので、その感想エントリーを書いていきたいと思います。

本書の第1版は「Java」で書かれていたのですが、第2版は「JavaScript」で書かれているので、フロントエンドの方でも読みやすくなっていると思います。
*とはいえ、「JavaScript」で説明できない部分(アクセス修飾子の表現等)は、「Java」で書かれているので注意してください。

本書のChapterと感想

本書のChapterは以下の通り、Chapterごとに感想を書いていきます。

Chap.1 リファクタリング-最初の例

サンプルコード(劇団員を派遣して演劇のパフォーマンスを行う会社を想定して、演じた劇に対する請求書を作成するコード)を例に、リファクタリングしていく一連の流れが書かれています。
このChapterを読むだけで、コードをリファクタリングしていく流れを体験できると思います。

私も本書を読むまで知らなかったのですが「いきなり目的に向かってリファクタリングをしても良いコード」と「いきなり目的に向かってリファクタリングをしてはいけないコード」があります。
たとえば、以下のようなサンプルコードがあり、関数名をinOldEngland(c)inNewEngland(c)に変更したいとします。

const newEnglanders = someCustomer.filter(c => inOldEngland(c));

function inOldEngland(aCustomer) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}

関数名をただ変更するだけなので、直接関数名を変更したくなりますが・・・
ちょっと立ち止まって考えてみましょう!

関数名を変更すると、呼び出し側の関数名も変更する必要があります。
呼び出し側が1つしかないのであれば問題ありませんが、呼び出し側が複数ある場合、いきなり関数名を変更すると変更漏れが発生するかもしれません。
また、関数名が変わることで「引数の見直し」もしたくなるかもしれません。

このような場合、関数名変更後の関数を仮実装(inNewEngland(c)を仮実装)して移行することを考えます。

// Step.1
// 関数名を`inNewEngland(c)`に変更
const newEnglanders = someCustomer.filter(c => inNewEngland(c));

// 関数`inNewEngland`を仮実装する
function inNewEngland(aCustomer) {
  return inOldEngland(aCustomer);
}

function inOldEngland(aCustomer) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(aCustomer.address.state);
}

引数も見直します。
こちらも段階的に変更します。

// Step.2
const newEnglanders = someCustomer.filter(c => inNewEngland(c));

function inNewEngland(aCustomer) {
  return inOldEngland(aCustomer.address.state);
}

// 引数を`stateCode`に変更。呼び出し側(仮実装側)の引数を変更します。
function inOldEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}
// Step.3
const newEnglanders = someCustomer.filter(c => inNewEngland(c.address.state));

// 引数を`stateCode`に変更。呼び出し側(実装側)の引数を変更します。
function inNewEngland(stateCode) {
  return inOldEngland(stateCode);
}

function inOldEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}

上記コードで、ちゃんとテストをして問題ないことを確認してから、仮実装した関数は削除して、以下コードに変更します。

// Step.4
const newEnglanders = someCustomer.filter(c => inNewEngland(c.address.state));

function inNewEngland(stateCode) {
  return ["MA", "CA", "ME", "VT", "NH", "RI"].includes(stateCode);
}

上記は遠回りなリファクタリングの方法です。
「テストをしていれば大丈夫!」と考える人もいると思いますが、「テストに責務を持たせすぎないこと!」というのも、本書では書かれています。
リファクタリングは小さな変更の積み重ねであること!」これが本書でMartinFowlerさんの言いたかった事の1つです。

Chap.2 リファクタリングの原則

リファクタリングの定義、リファクタリングを行う理由、リファクタリングはいつすべき?、問題点など・・・
リファクタリングの原則について書かれています。
やっぱり「IDEを使うのがいいよね」的な話も書かれていました。

Chap.3 コードの不吉な臭い

いわゆるリファクタリングすべき場所を解説している。
このあたりは「不吉な臭い」等でググると書いている記事が多くでてくる。
とはいえ、第1版と第2版ではいくつか追加・削除されたものもあるので注意。

devtab.jp

Chap.4 テストの構築

リファクタリングにはテストが欠かせない・・・というお話。
最近は、開発者にとってテストは関心事の1つになってきているとも書いてありましたね。テストやりましょう・・・・m( )m

Chap.5 カタログの紹介

ここから以下のChapterすべてリファクタリングテクニックのお話。 「うーん、書いてみないとわからんなぁ・・・」という箇所は、雑に写経しながら理解しました。

Chap.6 リファクタリングはじめの一歩

関数と変数に着目したリファクタリングのテクニック集。
- 関数は一画面に収まらなければ、ロジックを詰め込みすぎだと考える - 2回以上使われるコードはそれ自体を関数にすべき! - パラメーターが多すぎるならオブジェクトごと渡す!

などなど、いわゆるリファクタリングの王道パターンに対するテクニック集が記載されていました。

Chap.7 カプセル化

クラスに着目したリファクタリングのテクニック集。
私はあまり意識していなかったのですが、関数からコレクションを返す時は、コピーか読み取り専用にするのが良いとされていますね。
昨今では、このあたりもパフォーマンス的に問題になることは少ないとも書かれていました。
前のChapterでも書かれていましたが「変数・関数に名前を付ける -> 名前以上のことをする処理の場合はクラス化する」これを守っていればよさそうです。
委譲の隠蔽仲介人の除去は使い方が難しいテクニック(= o = ;;)

Chap.8 特性の移動

クラスや関数のロジックの移動に着目したテクニック集。
オブジェクト指向の大原則「データ構造処理を分離しよう」にしたがってリファクタリング(移動)しましょう!という感じですね。
ループの分離なんかで書かれている「1回のループで処理したいという理由だけで、2つの異なる処理を同時に行っているループをよくみる。」というコメントは、イタタタ・・・・

Chap.9 データの再編成

変数、フィールド名やそれ自体の置き換えや変更に着目したテクニック集。
フレッド・ブルックスの名言「フローチャートを見せてくれても、テーブルを隠されたら煙に巻かれたままだろう。テーブルを見せてくれれば通常フローチャートは要らない。それだけですぐわかる」 それだけ、名前って大切なんですね。ところで、フレッド・ブルックスって誰?(= = ;;)注)すごい人です
「変更可能なデータは、ソフトウェアにおける問題の発生源となる。」とのことですね。
話は変わりますが、TypeScriptreadonly修飾子がありますが、これが使えるだけで結構変わりそうです。

Chap.10 条件記述の単純化

条件分岐に着目したテクニック集。
ポリモーフィズムによる条件記述の置き換えは何を言っているのかさっぱりだったので、写経多め・・・
条件分岐にアサーションを入れてコメント代わりに使う方法があった。
Fowlerさんはセルフテストと呼んでいるそうですが、こんな使い方をするのもおもしろいですよね。

Chap.11 APIリファクタリング

関数、関数の引数などの呼び出し側に着目したテクニック集。
個人的にでるかな〜?と思っていた、setterの削除はここで登場。
「関数に渡す引数が、その関数に相応しいかを考えよう」をFowlerさんは責務という言葉を使って「債務が関数側に相応しいかを考えよう」と言っていました。
ファクトリ関数によるコンストラクターの置き換えで、コンストラクターの制限について書いていましたが、正直そんな事まで考えたこともありませんでした。m( )m

Chap.12 継承の取り扱い

最後は継承に着目したテクニック集。
委譲継承を同列で考えたことなんてありませんでした。m( )m
委譲によるサブクラスの置き換え委譲によるスーパークラスの置き換えはぜったい難しい。。。

さいごに

というわけで、雑な写経をしつつ、本を読み進めてみました。
大切なのはChap.3 コードの不吉な臭いを覚えること。そして、それに着目して怪しいコードはリファクタリングしていくこと。
リファクタリングはいつすべきなのか?」という問に対しても、Fowlerさんは「常に」と回答しています。
テクニックだけではなく、リファクタリングは身近なものでなくてはならないことを、この本で教わりました。
最初にも書きましたが、第2版は「JavaScript」で書かれているのですごく読みやすかったです。興味のある方は是非読んでみることをオススメします!!

OSSのライセンスについて調べてみた話

GitHubに落ちているライブラリ。
さくっと使えて便利なのですが、ふと「ライセンス」のことも気になったので、調べたことを以下に纏めておこうと思います。

「ライセンス」はなぜ大事なのか?

OSSは無償で公開されていて、誰でも自由に使用でき、「複製・配布・改良」することができるソフトウェアです。 しかし、この「複製・配布・改良」はライセンスによって制限されています。 このライセンスを守った上で、OSSを「複製・配布・改良」しないと、コンプライアンスの問題になるため、OSSを使用する時はライセンスも確認しておくのが良いです。

「ライセンス」の種類

OSSのライセンスは、「コピーレフト型ライセンス」と呼ばれる概念から始まり、大きく3つのカテゴリに分けられるそうです。

これら3つの違いは以下の通り。

類型 複製・配布・改良可能 改変部分のソース公開要 他のコードと組み合わせた場合、組み合わせたコードのソース公開要
コピーレフト型ライセンス
コピーレフト型ライセンス
コピーレフト型ライセンス

大きく違うのは「改変部分のソースを公開しなくてはならいのか?」と「他のコードと組み合わせた場合、組み合わせたコードも公開しなくてはならいのか?」です。
順番に見ていきましょう。

コピーレフト型ライセンス

代表的なライセンス ・・・ GNU General Public License(GPL)
代表的なソフトウェア ・・・ WordPressなど。。。

・コピーレフト型ライセンスを持つOSSを改変した場合、改変部分も同じライセンスの適用を要求する。
・コピーレフト型ライセンスを持つOSSを他の他のソフトウェアと組み合わせた場合、組み合わせ先のソフトウェアにまで同じライセンスの適用を要求する。

たとえばGPLの場合、GPLライセンスのコードを改変しても、他のソフトウェアと組み合わせたとしても、(他のソフトウェアも含めて)GPLライセンスになってしまう。ということです。
また、GPLには、同じコピーレフト型ライセンスですが、GPL2GPL3があり、その違いは以下の通りです。

  • GPL2 ・・・ OSS作成者の特許は守られる。たとえば、特許が含まれるコードを書いたとして、GPLに基づいてソースコードは公開しないといけません。しかし、特許は特許権を持っている人の裁量に任されているため、厳密な意味では自由に使えないコードになっている。
  • GPL3 ・・・ OSS作成者の特許は守られない。たとえば、特許が含まれるコードを書いたとして、GPLに基づいてソースコードを公開しないといけない&そのコードを利用した第三者を訴える権利を放棄しないといけない。

コピーレフト型ライセンス

代表的なライセンス ・・・ Mozilla Public License(MPL)
代表的なソフトウェア ・・・ Mozilla Firefoxなど。。。

・準コピーレフト型ライセンスを持つOSSを改変した場合、改変部分も同じライセンスの適用を要求する。
・準コピーレフト型ライセンスを持つOSSを他の他のソフトウェアと組み合わせた場合、組み合わせ先のソフトウェアにまで同じライセンスの適用を要求しない。

たとえばMPLの場合、MPLライセンスのコードを改変したものはMPLライセンスのままですが、他のソフトウェアと組み合わせた場合は他のライセンス(たとえば下のMIT License)を適用して良い。ということです。

コピーレフト型ライセンス

代表的なライセンス ・・・ BSD License、MIT License
代表的なソフトウェア ・・・ Vue.js jQueryなど。。。

・非コピーレフト型ライセンスを持つOSSを改変した場合、改変部分も同じライセンスの適用を要求しない。
・非コピーレフト型ライセンスを持つOSSを他の他のソフトウェアと組み合わせた場合、組み合わせ先のソフトウェアにまで同じライセンスの適用を要求しない。

たとえばMIT Licenseの場合、MIT Licenseライセンスのコードを改変しても、他のソフトウェアと組み合わせたとしても、他のライセンス(たとえば上のMPL)を適用して良い。ということです。
ただし、MIT Licenseは、特許や著作権などを明記する必要があるなど、製作者のコードが守られているため、非コピーレフト型からコピーレフト型へのライセンス切替はほとんど発生しません。

コピーレフトと特許や著作権は考え方が別

上記に出てきたGPL2GPL3のように、コピーレフトは、いわばライセンスの適用範囲を示したものなので、特許や著作権とは考え方は別です。特許や著作権の考え方はライセンスによって異なるので注意してください。

どのライセンスを選ぶべき?

使用したいOSSにライセンスは紐付いているので、選べないことが多いと思います。 似たようなOSSが複数あり、ライセンスが異なるのであれば、「非コピーレフト型ライセンス」であるBSD LicenseMIT Licenseを選ぶがの良いかと思います。 なお、2015年の時の情報ですが、GitHubにあるOSSでもっとも使用されているライセンスはMIT Licenseとの情報もあるので、MIT Licenseは選択肢に入りやすいと思います。

macOS(Catalina)で、デフォルトシェルがbashからzshに変更になったのもライセンスが原因!?

macを使用している方はご存知かと思いますが、macOS(Catalina)デフォルトシェルがbashからzshへ変更になりました。
この理由は、実はライセンスだと言われています。
というのも、Appleは、macOSGPL3ライセンスのソフトウェアを一切入れない!というポリシーを掲げています。(GPL2はOK)
そのため、macOSにインストールされているbashGPL2であるバージョン3.2からアップデートされていません。
現在(2020/07/06時点)の最新のbashのバージョンは5です。
bashはバージョン4から、GPL2からGPL3へライセンスの変更を行いました。 そのため、Appleはポリシーを守るため、macOSに標準で入っているbashのバージョンは3.2のままにしています。

## macOS(Catalina)でも入ってるbashのバージョンは3.2のまま・・・
$bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin19)
Copyright (C) 2007 Free Software Foundation, Inc.

このままbashのアップデートを停止したままだと、セキュリティ上よろしくないため、ApplemacOS(Catalina)からデフォルトシェルをbashからzshに変更する決断をしたとのことです。
ちなみに、zshは、MIT Licenseです。

さいごに

個人的に興味を持って調べ始めた「ライセンス」のはなし・・・ 調べてみると、なかなかおもしろいもので、大変勉強になりました。

以下、勉強のため参考にさせていただいたサイトです。
ありがとうございました。