eyecatch
Thu, Sep 6, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その5: Material-UIとWebフォント

ReactとReduxを学ぶために、開発環境というかプロジェクトテンプレートをスクラッチから作っている。 (最終的な成果はGitHubに置いた。) 前回はCSS周りの処理系をセットアップした。 (adsbygoogle = window.adsbygoogle || []).push({}); 既成Reactコンポーネント 前回まででHTMLもCSSもReactコンポーネント単位で書けるようになったんだけど、実際、自分で1からコンポーネントを書くのは、特にデザインセンスがない人にとっては辛い。 かっこいいUIコンポーネントを作りたいならデザイナーの協力が必要だけど、個人の開発などそれができない状況も多い。 という問題を抱えた人たち向けなのかはわからないが、既成のReactコンポーネントセットが色々OSSで提供されている。 Material-UI: GoogleのマテリアルデザインのReact実装。 Semantic UI React: Semantic UIのReactバインディング。 antd: Ant DesignのReact実装。 Blueprint: 複雑でデータ量の多いUI向けに作られたReact UIツールキット。 React-Bootstrap: BootstrapのReactバインディング。現時点ではv4未対応。 Grommet: HPEによるエンタープライズレディなデザインシステム。 Office UI Fabric React: OfficeなどのMicrosoft製品に使われているReactコンポーネントセット。 今回はこの中でも圧倒的に人気なMaterial-UIを導入する。 Material-UI Material-UIは簡単に使える。 とりあえずコアパッケージをインストールする。 yarn add @material-ui/core v1.4.1が入った。 あとはパッケージに入っている色々なコンポーネントをMaterial-UIのドキュメント見ながら使えばいいだけ。 import React from 'react'; import styled from 'styled-components'; +import Button from '@material-ui/core/Button'; const Wrapper = styled.div` font-size: 5rem; `; const App = () => ( <Wrapper> - HOGE + <Button variant="contained"> + HOGE + </Button> </Wrapper> ); export default App; これでただのテキストがボタンになった。 CSS Web Fonts 前節でいちおうMaterial-UI使えたけど、フォントをケアしてやるともう少しかっこよくなる。 Material-UIはRobotoフォントを想定して作られているが、これはブラウザにデフォルトで入ってはいないので、そのままだとArialとかにフォールバックされちゃう。 のでRobotoフォントを導入する。 フォントはCSS Web Fontsの機能である@font-faceで、フォントファイルをブラウザにロードさせることで導入できる。 @font-faceで読み込むフォントファイル(i.e.
eyecatch
Wed, Aug 29, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その4: CSS ModulesとPostCSSとstylelintとstyled-components

ReactとReduxを学ぶために、開発環境というかプロジェクトテンプレートをスクラッチから作っている。 (最終的な成果はGitHubに置いた。) 前回はPrettierとESLintをセットアップした。 (adsbygoogle = window.adsbygoogle || []).push({}); CSS 前回までで作った環境で、Reactを使ってHTMLのDOMツリーを構築することができるようになったが、これは基本的にUIに表示する情報の構造しか定義しない。 UIの見た目(スタイル)を決めるのはCSSなので、それをアプリに組み込むことを考えないといけない。 組み込み方には現時点で大きく3通りある。 CSSを別途設計する 一つ目はCSSを別途設計する方法。 Reactコンポーネントからレンダリングされる要素にclassが付くようにしておいて、設計したCSSをbundle.jsとは別途読み込んでスタイルを適用することにはる。 この場合、CSSのスタイル定義はすべてグローバルなので、設計効率やメンテナンス効率を維持しつつ、各コンポーネントに意図したスタイルが適用されるようにするため、テクニックを凝らしてCSSクラスを設計する必要がある。 例えばBEM (2009年3月誕生)、OOCSS (2009年3月誕生)、SMACSS (2011年9月誕生)、FLOCSS (2014年4月誕生)など。 CSS自体は、素のCSSを書くことはあまりなく、普通はSassなどのAltCSSやPostCSSを使って書く。 さらに、stylelintでリンティングすることで、CSSの品質を上げられる。 リンティングルールは、stylelintプロジェクトから提供されているstylelint-config-recommendedかstylelint-config-standardを使えば十分。 後者がGoogleやAirbnbのCSSスタイルガイドを反映していていい感じ。 書いたCSSは、webpackのcss-loaderで読み込める。 webpackはJavaScriptのimport './App.css';みたいなコードを見つけると、css-loaderに処理を渡す。 css-loaderは、import文で指定されたCSSファイルだけでなく、@importやurl()で定義される依存関係をたどって関連するCSSを一通り読み込む。 読み込んだCSSは、webpackのstyle-loaderを使ってDOMに適用できる。 style-loaderは、読み込んだCSSを<style>タグで囲ってHTMLのヘッダに挿入してくれる。 CSSの処理にはPostCSSを使うとして、プロジェクトに以下のパッケージを追加する。 (PostCSSについてはQiitaの記事が参考になった。) css-loader: CSSを読み込むためのwebpackのローダ。 style-loader: CSSをDOMに追加するためのwebpackのローダ。 postcss-loader: PostCSSを実行するためのwebpackのローダ。 postcss-preset-env: CSSのエッジな機能を使うためのPostCSSプラグイン。 autoprefixer: CSSプロパティにベンダプレフィックスを追加してくれるPostCSSプラグイン。 postcss-flexbugs-fixes: Flexboxのバグを修正してくれるPostCSSプラグイン。 cssnano: CSSをミニファイしてくれるPostCSSプラグイン。 stylelint: CSSのリンタ。 stylelint-config-standard: stylelintのルール設定集。 stylelint-config-prettier: Prettierが施すコード整形とコンフリクトするルールを無効にするstylelintルール設定集。 yarn add -D css-loader style-loader postcss-loader postcss-preset-env autoprefixer postcss-flexbugs-fixes cssnano stylelint stylelint-config-standard stylelint-config-prettier PostCSSとstylelintの設定は、それぞれpostcss.config.jsとstylelint.config.jsを書いてプロジェクトルートに置けばいい。 postcss.config.js: module.exports =
eyecatch
Thu, Aug 23, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その3: PrettierとESLint

ReactとReduxを学ぶために、開発環境というかプロジェクトテンプレートをスクラッチから作っている。 (最終的な成果はGitHubに置いた。) 前回はReactをセットアップした。 (adsbygoogle = window.adsbygoogle || []).push({}); フォーマッタとリンタ プロジェクトにフォーマッタとリンタを導入する。 フォーマッタはソースの体裁を整えるツール。 フォーマッタを使うことで体裁が統一され、ソースが読みやすくなり、品質向上につながる。 リンタはソースを静的解析して、潜在的なバグ、構造的な問題、体裁の問題を検出して警告してくれるツール。 フォーマッタは体裁だけ整えるのに対し、リンタは論理構造にも制約を課せるので、コーディングスタイルがより統一できたり、ミスをしやすい論理構造が無くなったりして、品質向上につながる。 JavaScriptのような動的型付け言語では、実行時まで顕在化しないバグを作りこみやすく、また実行時エラーの原因解析が静的型付け言語に比べて難しいので、フォーマッタとリンタでプログラム実行前に問題をできるだけ取り除いておくのが重要。 またチーム開発では、コードレビューでコーディンスタイルを見る必要がなくなり、効率化につながる。 Prettier フォーマッタにはPrettierを使う。 Prettierは2017年1月にリリースされた新しいツール。 構文解析をしてASTを構築し、そこからフォーマット済みコードを出力するので、従来のツールよりも厳密な整形(e.g. 行の最大長を考慮した整形)ができる。 また、opinionated(独断的)であることも特徴で、Prettierプロジェクトが推奨するフォーマットをほぼ強制し、設定がほとんどない。 このため導入が簡単だけど、かゆいところに手が届かないこともある。 JavaScriptの他、JSX、CSS、Markdown、GraphQLのフォーマットにも対応している。 まずプロジェクトにインストールする。 yarn add -D prettier v1.14.0が入った。 設定はprettier.config.jsというファイルを書いてプロジェクトルートに置けばいい。 prettier.config.js: module.exports = { printWidth: 100, // 行の最大長 tabWidth: 2, // インデント長 singleQuote: true, // 文字列をシングルクオートで囲う trailingComma: 'all', // オブジェクトのプロパティとか関数の引数を複数行で書いたときに、全行の末尾にカンマをつける }; また、フォーマット対象外のファイルを指定するファイルである.prettierignoreをプロジェクトルートに置く。 .prettierignore: node_modules/ dist/ node_modulesはnpmパッケージが入るディレクトリ。 実際はnode_modulesはデフォルトで無視されるから書かなくていいんだけど。 prettier-ignoreコメントを書くことで、ソースを部分的にフォーマット対象外とすることもできる。 最後に、npmスクリプトを書く。 package.json: (前略) "scripts": { + "format": "prettier --write **/*.jsx **/*.js **/*.css", "build": "webpack --config webpack.prod.js", "start": "webpack-dev-server --hot --config webpack.dev.js" }, (後略) これで、yarn formatを実行するとプロジェクト内ソースを一通りフォーマットできる。 ESLint リンタにはデファクトスタンダードのESLintを使う。 ESLintは2013年6月にリリースされたそこそこ歴史のあるツール。 リンティングルールがプラガブルで、豊富なルールを細かく制御できるのが特徴。 フォーマッタとしての機能もあるけど、そこはPrettierにまかせることにする。 JavaScriptもJSXもリンティングできる。 リンティングルールはAirbnbによるeslint-config-airbnbが有名なのでこれを使う。 ESLintを導入するために、以下のパッケージをプロジェクトにインストールする。 eslint: ESLint本体。 eslint-loader: webpackからESLintを実行するやつ。 eslint-config-airbnb: ESLintルール設定集。 eslint-plugin-import: eslint-config-airbnbのピア依存。import文を処理するためのESLintプラグイン。 eslint-plugin-jsx-a11y: eslint-config-airbnbのピア依存。JSXを処理するためのESLintプラグイン。 eslint-plugin-react: eslint-config-airbnbのピア依存。React特有のリンティングルールを追加するESLintプラグイン。 eslint-config-prettier: Prettierが施すコード整形とコンフリクトするルールを無効にするESLintルール設定集。 ピア依存をインストールするのにはちょっとコツがいるので、eslint-config-airbnbのドキュメントを参照すべし。 今回は以下のコマンドでインストールした。 yarn add -D "[email protected]>=1.6.0 <5.0.0" eslint-loader eslint-config-airbnb "[email protected]^2.12.0" "[email protected]^6.0.3" "[email protected]^7.9.1" eslint-config-prettier ESlintはv4.19.1が入った。 ESlintの設定は、設定ファイルである.eslintrc.jsをプロジェクトルートに置けばいい。 .eslintrc.js: module.exports = { env: { browser: true, }, extends: ['airbnb', 'prettier'], }; アプリの実行環境はブラウザなのでenv.browserをtrueにしている。 これにより、ブラウザ環境でデフォルトで使えるグローバル変数(e.g.
eyecatch
Wed, Aug 22, 2018

React + Reduxアプリケーションプロジェクトのテンプレートを作る ― その2: React

ReactとReduxを学ぶために、開発環境というかプロジェクトテンプレートをスクラッチから作っている。 (最終的な成果はGitHubに置いた。) 前回はNode.jsとYarnとBabelとwebpackをセットアップした。 (adsbygoogle = window.adsbygoogle || []).push({}); Reactとは 以前にも同じような事を書いたけど、改めてReactについて書く。 ちょっとコーディングの詳細にも触れながら。 ReactはViewを記述するためのライブラリで、特徴はVirtual DOMとJSX。 Virtual DOM Virtual DOMはDOMを仮想化するもので、JavaScriptからVirtual DOMでUIを記述してやると、それが実DOMに効率的に反映されるようになっている。 JSX Virtual DOMはJSXというHTMLみたいな言語で記述できる。 import React from 'react'; import ReactDOM from 'react-dom'; ReactDOM.render( <h1>Hello, world!</h1>, document.getElementById('root') ); こんな風に書くと、idがrootであるHTML要素の中に、<h1>Hello, world!</h1>がレンダリングされる。 上記コードの<h1>Hello, world!</h1>の部分がJSX。 コンポーネント JSXではコンポーネントを定義して新たなタグとして使うことができるので、再利用できるコンポーネントを作って、それらを組み合わせてUIを構築することで、効率的な開発ができる。 import React from 'react'; import ReactDOM from 'react-dom'; // Welcomeコンポーネントの定義 function Welcome() { return <h1>Hello, World</h1>; } // Welcomeコンポーネントのレンダリング ReactDOM.render( <Welcome />, document.getElementById('root') ); 上記コードではコンポーネントをfunctionで定義しているが、アロー関数で書いても全く一緒。 const Welcome = () => ( <h1>Hello, World</h1>; ); 関数の代わりにclassで定義することもできる。 class Welcome extends React.Component { render() { return <h1>Hello, World</h1>; } } 関数による定義とclassによる定義はおおむね変わらないが、stateとライフサイクルメソッドを使いたいときはclassにする必要がある。 props コンポーネントはレンダリングの際にpropsというパラメータを受け取って使うことができるので、上手く設計すれば汎用的なコンポーネントが書ける。 import React from 'react'; import ReactDOM from 'react-dom'; // Welcomeコンポーネントの定義 (props付き) function Welcome(props) { return <h1>Hello, {props.name}</h1>; } // Welcomeコンポーネントのレンダリング (props付き) ReactDOM.render( <Welcome name="Kaitoy" />, document.getElementById('root') ); propsはイミュータブルにしてコンポーネント内で変更しない(i.e.