静的型付け言語・動的型付け言語
(会社のLT会で発表したものの転記。)
TypeScriptのメリットを紹介するつもりでしたが、型がある言語全般に言えることなので、もう少し広い意味で静的型付け言語・動的型付け言語の紹介をします。
データ型
データ型・プログラムを実行するときのデータの入れも(コンピュータのメモリの確保する量)
データ型を定義する→プロダクトの実行前に入れ物の大きさが分かる→データに対して最適なメモリ使用量で済む
データ型を定義しない→プログラム実行前に入れ物の大きさが分からない→実行するまでにどんなデータが来るか分からないため、余分にメモリを確保する必要がある
※メモリ=一時的にデータを記憶する場所、作業机のイメージ
机のスペースが広い=メモリの使用量が少ない→実行速度が速い
机のスペースが狭い=メモリの使用量が多い→実行速度が遅い
特徴
静的型付け言語
変数・関数にデータ型の宣言が必要な言語
- メリット
- データ型に関するエラーが事前に分かる
- 実行速度が速い
- メリット
- コードの記述量が多い
- 開発スピードが遅い
言語
動的型付け言語
変数・関数にデータ型の宣言が不要な言語
- メリット
- コードの記述量が多い
- 開発スピードが遅い
- メリット
- データ型に関するエラーはプログラムを実行しないと分からない
- 実行速度が遅い
言語
利用ケース(個人的な意見)
静的型付け言語が向いているケース
- 大規模・大人数
- スケールする可能性が高いサービス(自社サービス)
- 安全性・パフォーマンス重視(金融・ゲーム)
動的型付け言語が向いているケース
- 小規模・小人数
- スケールする可能性が低いサービス(受託など)
- 開発スピード重視(スタートアップ)
所感
最初に開発した言語がJavaだったり、今はC#を使っていることもあり静的型付け言語の方が贔屓目な書き方になってしまった。
ただ世間的にも最近JavaScript→TypeScript、Ruby→Goに移行している事例を割と見るので、型があるほうが安心して開発できると感じる。
参考
フロントエンドエンジニアのロードマップ(2021)読解
はじめに
結論から書くと、今後はフロントエンドに注力していこうと思います。
現状フロントエンド・バックエンド両方担当していますが、下記理由からフロントエンドに注力しロードマップを参考に学んでいこうと思います。
なぜフロントエンド?
会社で受講したWebのセキュリティ研修がきっかけです。
IPAのAppGoatとFlatt SecurityのKENROを受講しましたが、似たような内容でもKENROの方が使いやすかったです。(IPAさんごめんなさい)
どうして使いやすかったのかはうまく説明できませんが、色を使いすぎていない、スペースが適度に空いているなどデザインの面が良かったからだとは考えています。
もともとユーザーも自分も使いやすいと思えるサービスを開発したいと考えていましたが、「使いやすい」の定義が曖昧でした。
ただ2つのサービスを使ってみた経験から、使いやすさは目に見える画面に影響されることが多いと考えたため、目に見える部分を担当するフロントエンドを専門にしたいと思うようになりました。(レスポンスが遅い、すぐエラーになるなど正常に動作することはクリアしている前提の話ですが)
デザイナーでもよくない?
画面を担当するのであればデザイナーでもよくないかと思いましたが、過去にデザイン系の案件を担当してデザインを考えているときよりもコードを考えてたり、書くことの方が好きなためエンジニアとして働きたいと思っています。
過去に担当した案件から、デザインは客観的に説明することが難しい(主観的になってしまう)ことが多いイメージです。色のコントラスト比や黄金比など数値にできるものならまだしも、レイアウトやUIの使いやすさは個人の感覚に左右されることが多く、自分が納得してデザインを決めることができませんでした。(私が知らないだけで、そういったものの理論ややり方もあるかもしれませんが)
デザインに対し、プログラムは客観的に説明できることが多く、自分も納得感を持って仕事ができていました。(同じ処理は繰り返し処理にしてコード量を減らす、複数箇所から参照される値は変数・定数にして改修時に直す箇所を少なくするなど)
なぜロードマップ?
フロントエンドを専門にしていくにあたり、何を学べがいいか分からないため、全体像を知ることができるものを探していました。
今回参考にするのはroadmap.shのFrontendDeveloperのロードマップです。Zennなど技術系サイトに掲載されたり、テック系のYouTuberが紹介していました。
何を学ぶ必要があるかを知るためにロードマップを読解し、その中から今後学んでいく領域について書いていこうと思います。
ロードマップ
画像の中心の1本の線でつながっているブロックごとにどういった内容か書いていきます。
マークの意味
画像左上のマークの意味です、上にあるものほどおすすめな選択肢になっています。
Personal Recommendation / Opinion
おすすめな選択肢Alternative Option - Pick this or purple
代わりの選択肢、選ぶならこれか上記のものOrder in roadmap not strict(Learn anytime)
いつでも学んでいい、順番は守らなくていいものI wouldn't recommend
非推奨、やらなくてもいい
項目
項目内のトピックについて箇条書きしていきます。太字は優先度が高い選択肢です。(マークの意味
の上から2項目の選択肢)
Internet
インターネット、HTTP、ブラウザなどそもそもの基礎となる技術。
フロントエンドはパフォーマンス向上のために特にブラウザの知識は持っておく必要がありそう。
- How does the internet work?
- What is HTTP?
- Browers and they work?
- DNS and how it works?
- What is Domain Name?
- What is hosting?
HTML
HTMLの基礎、フォーム・バリデーション、ベストプラクティス 。
基本的には書けるけど、何が良い書き方なのかは知っておいた方がよさそう。
- Learn the basics
- Writing Semantic HTML
- Forms and Validations
- Conventions and Best Practices
Semanctic HTMLは要素に目的・役割を持たせること。検索エンジンがページの検索のランキングを上げる、目の不自由なユーザー向けの読み上げソフトのページ移動を補助するなどの利点がある。
CSS
CSSの基礎、FloatsやFlexなどのレイアウト、端末ごとによって表示が異なるレスポンシブデザイン。
- Accesibility
- SEO Basics
- Learn th basics
- Making Layouts
- Responsive design and Media Queries
Accesibilityはフォントサイズを上げる、行間を空けるなど、ユーザーがより快適になるようにデザインすること。
SEOは検索エンジンで自社のページが検索時に上位表示されるように最適化する戦略。toC向けのサービスはこの知識も求められそう。(toB向けサービスでも広告記事は同様に必要かも?)
JavaScript
JavaScript基礎、DOM操作、非同期通信、ES6・JavaScriptモジュール、バブリングやスコープなど概念。
- Syntax and Basic Constructs
- Learn DOM Manipulation
- Learn Fetch API / Ajax(XHR)
- ES6 + and modular JavaScript
- Understand the concepts Hosting, Event Bubbling, Scope, Prototype, Shadow DOM, strict
普段ES5で書いているので、ES6は改めて学ぶ必要がありそう。バブリングやスコープなどJavaScript固有の概念も理解しておく。
Version Control Systems
バージョン管理システム、Gitの基本操作。
- Basic Usage of Git
Repo hosting services
GitのWebサービスにあたるもの。GitHubを覚えればOK。(BitBucketを使ったことあるけど、UIが違うだけでほぼ同じだったので、GitHubだけでよさそう)
- GitHub
- GitLab
- Bitbucket
Web Security Knowlwdge
最低限覚えておくセキュリティの知識。
- HTTPS
- Contents Security Policy
- CORS
- OWASP Security Risks
Package Manager
主にJavaScriptで開発されたモジュールを管理するためのシステム。
手動でそれらモジュールの設定ファイルや更新を行うのは手間が掛かるため、簡単なコマンド入力でそれらの作業ができるようになる。
- npm
- yarn
CSS Architecture
- BEM
- OOCSS
- SMACSS
モダンなフレームワークとCSS-in-JSがある場合は、CSS設計は優先度は低い。
ただBEMには精通していることは推奨。
CSS Preprocessors
- Sass
- PostCSS
- Less
CSS設計と同じくフレームワークとCSS-in-JSが主流になっているので、こちらも優先度は低い。
ただ余力があれば知識を付けておくとよい。
Build Tools
Task Runner
ファイルの更新を監視しコンパイルするなどのタスクを自動化してくれるツール。
- npm scripts
- Gulp
Linters and Formatters
- Prettier
- ESLint
- StandardJS
静的解析ツール、コードを整形してくれたり、策定したルールに沿っていない箇所を教えてくれたりするもの。
Module Bundlers
- Webpack
- Rollup
- Parcel
複数のファイル(モジュール)を1つの最適化されたファイルにバンドル(まとめる)するツール。
Pick a Framework
フロントエンド開発のフレームワークと状態管理ライブラリ
- React.js
- Reduc
- MobX
- Angular
- RxJS
- NgRx
- Vue.js
- Vux
Modern CSS
CSS in JSと呼ばれるJavaScript内にスタイルを記述することで、スタイルをコンポーネント単位に指定する技術
- Styled Components
- CSS Modules
- Styled JSX
- Emotion
- Radium
- Glamorous
Web Components
再利用なカスタム要素で、他のコードから独立してカプセル化する機能を持つ
- HTML Templates
- Custom Elements
- Shadow DOM
CSS Frameworks
JS based
JavaScriptフレームワークと共に利用することが推奨とされているもの
CSS first
デフォルトでJavaScriptコンポーネントが付属していないCSSファーストなもの
- Bootstrap
- Materialize CSS
- Bulma
Testing your Apps
単体、結合、機能テストの違いとツールを使ってそれらを作成する方法を学ぶ
- Jest
- react-testing-library
- Cypress
- Enzyme
Type Checkers
静的型チェッカー、実行前に型が正しく定義されているか検証する
- TypeScript
- Flow
Progressive Web Apps
先進的なWebアプリで使われる様々なWebAPIを学ぶ。
- Storage
- Web Sockets
- Service Workers
- Location
- Notifications
- Device Orientation
- Payments
- Credentials
パフォーマンスの計算、測定、改善をする
- PRPL Pattern
- RAIL Model
- Performance Metrics
- Using Lighthouse
- Using Dev Tools
Server Side Rendering(SSR)
サーバーサイドでレンダリング(HTMLを生成)し、ブラウザはレンダリングされたファイルを表示する。Node.jsの実行サーバーが必要、サーバー側の負荷が増加するが、SPAよりも表示速度が速い。
- React.js
- Next.js
- After.js
- Angular
- Universal
- Vue.js
- Nust.js
GraphQL
API向けに作られたクエリ言語及びランタイム。クライアントが必要なデータ構造を定義することで、サーバーから必要以上のデータを返されることを防止でき効率がよいとされる。
- Apollo
- Relay Modern
Static Site Generators
静的サイトジェネレータ、WebサイトのHTMLファイルを生成するツール。
CMSと異なり、すべてのHTMLファイルを作成するため、レスポンスが速い・サーバー代が掛からないなどのメリットがある。
- Next.js
- GatsbyJS
- Nuxt.js
- Vuepress
- Jekyll
- Hugo
Mobile Application
モバイルアプリ、iOS・Android両方を開発できるクロスプラットフォームのフレームワークが推奨。
- React Native
- NativeScript
- Flutter
- Ionic
Desktop Applications
VSCodeやslackなどPCにインストールして利用するアプリ
- Electron
- Carlo
- Proton Native
Web Assembly
ブラウザ上で動作するバイナリコード。JavaScriptより高速で主要ブラウザでは対応している。2019年にW3C(Webの標準化団体)は公式水準として受け入れている。
これから学ぶ領域
まずはTypeScriptとSPAを勉強しようと思います。上記2点が、現在フロントエンドエンジニアでの必須要件になっている求人が多いためです。
このこと自体は初めから求人だけ見れば良かったかもしれません。 ただロードマップを読解したことで何を学ぶべきかの全体像を把握することができました。ロードマップを参考に今自分が勉強している場所を確認しながら、今後も学習を進めていきたいと思います。
参考
【C#/NUnit/Moq】単体テストについて
背景
業務で利用しているNUnit・Moqを学習するにあたり、そもそも単体テストについての知識がないので単体テストの目的、手法、ライブラリの使い方などついて自分用にまとめます。
なお、単体テストは自動化されたテストを前提に記載しています。分類としての単体テストでは自動テストを必ずしも意味していないため。(手動の単体テストはマイナーだと思いますが)
単体テスト
比較的小さなプログラムのテスト。テスト対象は主にクラスやメソッドなどテスト可能な最小単位な部品(ユニット)。
メリット
バグの早期発見
単体テストはコードの開発直後にテストするため、バグがあった場合にすぐに発見できる。
またテスト対象の粒度が小さいため、問題があった箇所を特定しやすい。品質の維持
リファクタリングや影響箇所の修正などで既存コードを改修した際に、テストコードがあれば改修による問題を発見・修正しやすくなるため品質を維持しやすい。
デメリット
開発者の工数増加
単体テストはテストコードだけではなく、テストコードを呼び出すドライバやテストコードから呼び出されるスタブなどの準備が必要となる。
開発者は稼働するコード以外にも開発する必要があるため、開発工数が増加してしまう。後回しにされやすい
開発者の負担増加によるスケジュールの関係で、網羅的ではなく簡易的なテストだけで済まされてしまう場合がある。またテストコードのメンテナンス漏れやテスト実行されなくなってしまう可能性もある。
他のテスト
単体テスト以外にも以下のテストがある。
結合テスト
単体テストの次に行うテストで複数のプログラムを組み合わせて正常に動作するか確認するテスト。
部品ごとの動作を確認する単体テストは完了しているため、主にデータの受け渡しや流れを確認する。システムテスト
結合テストの次に行うテストで、ユーザーが使用する環境を想定して確認するテスト。
1つの機能を確認する結合テストは完了しているため、外部のシステムや他の機能に影響がないかシステム全体を確認する。
単体テストの手法
ホワイトボックステスト
プログラムの内部構造(関数や条件分岐など)に関するテストで、テスト対象のソースコードが正常に動作するか確認するテスト。
網羅手法
命令網羅
全ての処理を最低1回でも通す。分岐網羅
全ての分岐の処理を通す。(分岐先に注目したテスト)条件網羅
全ての分岐条件の真/偽条件の場合の処理を通す。(分岐条件に注目したテスト)
ブラックボックステスト
プログラムの内部構造は意識せず、入力に対して期待される結果が仕様通りか確認するテスト。
分割法
同値分割法
有効な値、無効な値を入力して想定となる結果になるか。境界値分割法
有効な値と無効な値の境界となる値を入力して想定となる結果になるか。
NUnit/Moq
NUnit
C#やVisual Basicなど.NET言語の単体テストフレームワーク。Javaの単体テストフレームワークであるJUnitから派生して開発された。
Moq
.NETのための唯一のモックライブラリ、予め作成しておいたインターフェースに対して、テストする際の振る舞いを設定することができる。
以下Microsoftのチュートリアルや業務でよく見かけるキーワードについて記載。
属性
テスト用のクラスやメソッドなどに付与する属性
Test
TestFixtureクラス内のメソッドをテストとしてマーキングする。パラメーターを利用しない単純なテストに使われることが多い。TestFixture
テストとオプションでsetup, teardownメソッドを含むクラスをマーキングする。Setup
TestFixture
の内側で使われ、各Testメソッドの前に実行される共通処理を書くことが出来る。TearDown
TestFixture
の内側で使われ、各Testメソッドの後に実行される共通処理を書くことが出来る。Ignore
何らかの理由でテストを実行すべきではないときに、TestFixture
やTest
の属性に加えることで、付与したテストを無視できる。TestCase
テストメソッドにパラメータを渡し、渡したデータでテストが実行される。
アサーション
テスト結果を判定するための機能、テスト結果によって成功・失敗と判定される。
Assert.AreEqual
2つの引数が同一か判定するAssert.NotEqual
2つの値が異なるか判定するAssert.Throws
特定の例外がthrowされることを確認するAssert.DoesNotThrow
特定の例外がthrowされないことを確認するAssert.Fail
失敗を生成する、またプロジェクトに合わせて失敗時のメッセージやパラメーターを設定できる。
モック
データベースアクセスやネットワーク通信など外部通信が行われるテストにおいて、テスト用の結果を返す代わりのオブジェクト。
注意点
事前にテストするクラス・メソッドのインターフェースを定義する必要がある。また本物のクラスもそのインターフェースを実装する。
Setup
特定のメソッドが呼ばれた際の戻り値や例外などの指定ができる。 このメソッドでテスト時のオブジェクトの振る舞いを決定する。
検証用アプリ
参考
【JavaScript】call・apply
- 関数のthisを置き換える
call・apply共に関数を呼び出し、呼び出した関数のthisを第1引数に指定したオブジェクトに置き換える。
var func = function(){ console.log(this); } func(); func.call({hoge: 1}); func.apply({hoge: 2});
//出力 //func()はwindowオブジェクトが出力される(長すぎるため省略) { hoge: 1 } { hoge: 2 }
違い
- 第2引数の値
callは第2引数以降に値を複数受け取る。applyは第2引数に1つの配列を受け取る。
var func = function(a1, a2){ console.log(this); console.log(a1); console.log(a2); } func.call({hoge: 1}, "c1", "c2"); func.apply({hoge: 2}, ["a1", "a2"]);
//出力 { hoge: 1 } "c1" "c2" { hoge: 2 } "a1" "a2"
使用例
- なりすまし
callやapplyを利用すると本来は利用できない機能が、利用可能なオブジェクトになりすまして利用できるようになる。
<ul> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> <li>10</li> </ul>
var liText1 = ( document.querySelectorAll( "li" ) ).map( function (e) { return e.textContent; }); console.log(liText1) var liText2 = Array.prototype.map.call( document.querySelectorAll( "li" ), function (e) { return e.textContent; }); console.log(liText2)
//liText1 はmap()を持っていないため実行できずエラー Uncaught TypeError: document.querySelectorAll(...).map is not a function //liText2 はmap()を持っているArrayオブジェクトになりすますことで実行できる ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
参考
【C#】抽象クラス・インターフェース
前提
C#の抽象クラス・インターフェースの話
抽象クラス
定義
インスタンスを生成出来ないクラスで、継承して利用することを前提としたクラス
※継承...クラスの共通部分を別クラス(A)にまとめ、Aを継承することでAのプロパティ・メソッドを継承先で宣言することなく利用できる仕組みポイント
- クラスやメソッドの前にabstractキーワードを付ける
- 抽象クラスの中の抽象メソッドでは処理を書かず定義だけ行い、処理は継承先の具象クラスで書く必要がある
- 継承できる抽象クラスは1つのみ(抽象クラスに限らず、具象クラスを継承する際も継承可能なクラスのは1つ)
実装例
public class Test{ public static void Main(){ var normal = new NormalUser(); var str1 = normal.GetUserClassName(); var admin = new AdminUser(); var str2 = admin.GetUserClassName(); System.Console.WriteLine(str1); System.Console.WriteLine(str2); } } abstract class AbstractUser {//抽象クラス abstract public string GetUserClassName(); //抽象メソッド } class NormalUser : AbstractUser {//抽象クラスを継承 public override string GetUserClassName(){//抽象メソッドをオーバーライド return "NormalUser"; } } class AdminUser : AbstractUser {//抽象クラスを継承 public override string GetUserClassName(){//抽象メソッドをオーバーライド return "AdminUser"; } }
//出力結果 NormalUser AdminUser
インターフェース
定義
メソッドの実装を強制し、機能を追加するための仕組みポイント
- classではなく、interefaceキーワードを付ける※アクセス修飾子はpublic固定
- インターフェースを実装したクラスは、インターフェースの処理を実装しなければいけない(抽象メソッドと同じ)
- 複数のインターフェースの継承が可能
- 実装例
public class Test{ public static void Main(){ var user = new User(); var str1 = user.GetId(); var product = new Product(); var str2 = product.GetId(); System.Console.WriteLine(str1); System.Console.WriteLine(str2); } } interface IGetId{//インターフェース int GetId(); } class User : IGetId { public int GetId(){//インターフェースのメソッドを実装 var userId = 1;//本来はUserテーブルにidを取得しに行くが、ここでは仮に定義 return userId; } } class Product : IGetId {//インターフェースのメソッドを実装 public int GetId(){//インターフェースのメソッドを実装 var productId = 2;//本来はProductテーブルにidを取得しに行くが、ここでは仮に定義 return productId; } }
//出力結果 1 2
抽象クラスとインターフェースの使い分け
調べていくうちに想像より複雑だったため、また別の記事として作成予定。
参考
プロセス・スレッド・並列処理
プロセスとスレッド
プロセスやスレッドやマルチスレッドや並列処理など関係ありそうだけど、今まであやふやなまま放置していたので、まとめる。
プロセス
OSが実行しているプログラム。
WordやExcelなどタスクマネージャーで表示されるもの。
プロセスが並行処理されることを「マルチプロセス」と呼ぶ。
スレッド
プログラムの実行単位。
CPUのコアは1コアあたり、1スレッドしか実行できない。そのため、スレッド=CPUコアの処理単位。
ex)画面を描画するスレッド、キー入力を受け取るスレッドなど。
スレッドはプロセスの中に含まれ、1つのプロセスの中で複数のスレッドを動作させることができる。(マルチスレッド)
マルチスレッドにすることでCPUの複数のコアに処理を割り振れるため、シングルスレッドよりも処理を高速化できる。(CPUが複数コアに限る)
プロセスとスレッドの違い
同じメモリ領域を共有するかしないか
プロセスはOSからメモリ領域を割り当てられるため、各プロセスがメモリを共有することはない。
ex)メモ帳に書いた文字がWordに反映されない。スレッドは同じメモリ領域を共有するため、マルチスレッドの場合はメモリの管理をしないとバグが発生する可能性がある。
並列処理(マルチスレッドプログラミング)
複数のスレッドを同時に実行するプログラムを作成することをマルチスレッドプログラミングと呼ぶ。
ただし実際は並行に処理を行っているのではなく、人間には分からない程高速でスレッドの切り替えをして、同時に処理を行っているようにみえている。
using System; using System.Threading; using System.Threading.Tasks; public class TaskSample { public static void Main() { // 並行処理 var task1 = Task.Run(() => ThreadMethod("A")); var task2 = Task.Run(() => ThreadMethod("B")); task1.Wait(); task2.Wait(); } static void ThreadMethod(String str) { for(var i =0; i < 100; i++){ Console.Write(str); }; } }
//値が交互に出力される BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
スレッドセーフ
複数のスレッドで同じリソースにアクセスしようとすると、想定の値にならないバグが発生する可能性がある。このバグを防止することをスレッドセーフと呼ぶ。 リソースを読み取り専用にする、排他制御(スレッドによる書き込み中は他のスレッドからのアクセスを不可にする)をかけるなど
参考
【Sass】@extendと@mixinの使い分け
定義したスタイルを複数のクラスで使用できるSassの@extendと@mixinの違いが分からなかったので、両者を比較して使い分けるべきケースをまとめる。
@extendの特徴
定義したスタイルを他のクラスに継承して使用できる
/* Sass */ .btn-base{ border:1px solid; border-radius: 0.5rem; padding: 0.5rem; } .btn-success{ @extend .btn-base; background-color: green; } .btn-error{ @extend .btn-base; background-color: red; }
/* CSS */ .btn-base, .btn-error, .btn-success { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; } .btn-success { background-color: green; } .btn-error { background-color: red; }
プレースホルダーを使用する場合
継承元になったクラス(.btn-base)を利用しない場合は、プレースホルダー(%)を使用することでCSSにコンパイルされない
/* Sass */ %btn-base{ border:1px solid; border-radius: 0.5rem; padding: 0.5rem; } .btn-success{ @extend %btn-base; background-color: green; } .btn-error{ @extend %btn-base; background-color: red; }
/* CSS */ .btn-error, .btn-success { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; } .btn-success { background-color: green; } .btn-error { background-color: red; }
@mixinの特徴
定義したスタイルを他のクラスで呼び出して使用できる
/* Sass */ @mixin btn-base{ border:1px solid; border-radius: 0.5rem; padding: 0.5rem; } .btn-success{ @include btn-base; background-color: green; } .btn-error{ @include btn-base; background-color: red; }
/* CSS */ .btn-success { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; background-color: green; } .btn-error { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; background-color: red; }
引数を使用する場合
@includeに引数を渡すことで、呼び出し元のクラスごとにスタイルを調整することが出来る
/* Sass */ @mixin btn-base($bgc:transparent){ border:1px solid; border-radius: 0.5rem; padding: 0.5rem; background-color: $bgc; } .btn-success{ @include btn-base(green); } .btn-error{ @include btn-base(red); }
/* CSS */ .btn-success { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; background-color: green; } .btn-error { border: 1px solid; border-radius: 0.5rem; padding: 0.5rem; background-color: red; }
比較
@extend
メリット
- コード量が少ない
継承元と継承先のクラスが1セレクタにグルーピングされるため、共通スタイルのコードの重複を防止できる
- コード量が少ない
デメリット
引数が使用できない
@mixinと違い引数が使えない分、継承されるスタイルは固定になる可読性が下がる
継承元と継承先のコードが離れるため、コードの可読性が落ちる。
そのため、グルーピングできない関連性がないクラスへの@extendは控える。(関連性があるコードは距離が近く、関連性がないコードは距離が遠いため)
@mixin
メリット
引数が使える
@includeしたクラスごとにスタイルの調整が出来る可読性が高い
コードが@includeしたクラスに全て記載されるため、可読性が高い
デメリット
- コード量が増える
@includeしたクラスに同じスタイルが記載されるため、コードが重複する。
- コード量が増える
まとめ
グルーピング出来るような関係性のあるスタイルは@extendを使用する
関係性がない、または引数を利用したいなら@mixinを使用する
まとめのまとめ
継承関係があるなら@extend、それ以外は@mixin