20211201のReactに関する記事は11件です。

Hermesを導入してAndroidのパフォーマンスを向上した話

自己紹介 株式会社Another worksでエンジニアインターンをしている@hakeと申します。 主にTypescriptとReactNativeでクロスプラットフォーム開発をしております。 経緯 弊社ではAndroidアプリのパフォーマンスが悪いことが課題の一つとして上がっていました。 ReactNative開発ではあるあるだと思っています。 そこで今回、HermesというJavaScriptエンジンを導入することで改善を図りました。 Hermesとは Meta(旧Facebook)が開発しているReactNative用に最適化されたオープンソースのJavaScriptエンジン。 Hermesを有効にすると、起動時間が改善され、メモリ使用量が減少し、アプリのサイズが小さくなります。 いいことづくしですね! 参考 https://reactnative.dev/docs/hermes 仕組み バイトコードの事前コンパイル 通常のJavaScriptエンジンは、JavaScriptソースがロードされた後に解析し、バイトコードを生成しますが、HermesはJavaScriptを事前コンパイルによりバイトコードを生成しています。 また、実行時にJavaScriptをパースしてバイトコードを生成するというステップが省略できることによる起動時間の短縮を実現しています。 下記の図がとてもわかりやすかったです。 通常のJavascriptエンジン parseとconpileがRun timeに行われます。 Hermes ParseとCompileがビルド時に行われる その他にもJITコンパイラの廃止やガベージコレクタの最適化などを行っているらしいです。 詳しく知りたい方は下記を読んでみてください! 参考 https://engineering.fb.com/2019/07/12/android/hermes/ Hermesについて Android:ReactNative 0.60.4以上 iOS:React Native 0.64以上 expoを利用している場合 Android:SDK42以上 iOS:SDK43以上(SDK43では実験的サポートになっているので注意) また、expo buildではなくeas buildを使用する必要があります。 (eas buildを利用することでnative層の変更も可能になるため) 先日ちょうどexpo buildの利用は2023年までと発表があったので、どこかのタイミングで切り替えていく必要があります。 https://blog.expo.dev/turtle-goes-out-to-sea-d334db2a6b60 導入 基本的にドキュメントに沿って実装すれば大丈夫でした。 実際に導入で詰まる点はありませんでした。 また、リロードを高速に保つために、デバッグビルドは事前コンパイルを使用していません。 なので導入したからと言って開発体験が悪くなるといった問題も今の所はないです。 ReactNative https://reactnative.dev/docs/hermes expoを利用している場合 https://docs.expo.dev/guides/using-hermes/ 導入結果 初期起動時間の減少 約6秒程度から3秒程度に(端末によって異なる場合あり) →起動からhome画面に遷移するまでの時間を計測 アプリサイズ減少 デバイス上のアプリサイズが約8MB減少 48MB→40MB 全体的にパフォーマンスが向上 メモリの使用率が減ったことにより、全体的にパフォーマンスが向上 最後に 仕組みや開発背景についてはMeta公式のブログに詳しく書かれているので興味のある方はぜひ見てください。 https://engineering.fb.com/2019/07/12/android/hermes/ ▼複業でスキルを活かしてみませんか?複業クラウドの登録はこちら! https://talent.aw-anotherworks.com/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Hermesを導入してAndroidのパフォーマンスを向上した話(ReactNative)

自己紹介 株式会社Another worksでエンジニアインターンをしている@hakeと申します。 主にTypescriptとReactNativeでクロスプラットフォーム開発をしております。 経緯 弊社ではAndroidアプリのパフォーマンスが悪いことが課題の一つとして上がっていました。 ReactNative開発ではあるあるだと思っています。 そこで今回、HermesというJavaScriptエンジンを導入することで改善を図りました。 Hermesとは Meta(旧Facebook)が開発しているReactNative用に最適化されたオープンソースのJavaScriptエンジン。 Hermesを有効にすると、起動時間が改善され、メモリ使用量が減少し、アプリのサイズが小さくなります。 いいことづくしですね! 参考 https://reactnative.dev/docs/hermes 仕組み バイトコードの事前コンパイル 通常のJavaScriptエンジンは、JavaScriptソースがロードされた後に解析し、バイトコードを生成しますが、HermesはJavaScriptを事前コンパイルによりバイトコードを生成しています。 また、実行時にJavaScriptをパースしてバイトコードを生成するというステップが省略できることによる起動時間の短縮を実現しています。 下記の図がとてもわかりやすかったです。 通常のJavascriptエンジン parseとconpileがRun timeに行われます。 Hermes ParseとCompileがビルド時に行われる その他にもJITコンパイラの廃止やガベージコレクタの最適化などを行っているらしいです。 詳しく知りたい方は下記を読んでみてください! 参考 https://engineering.fb.com/2019/07/12/android/hermes/ Hermesについて Android:ReactNative 0.60.4以上 iOS:React Native 0.64以上 expoを利用している場合 Android:SDK42以上 iOS:SDK43以上(SDK43では実験的サポートになっているので注意) また、expo buildではなくeas buildを使用する必要があります。 (eas buildを利用することでnative層の変更も可能になるため) 先日ちょうどexpo buildの利用は2023年までと発表があったので、どこかのタイミングで切り替えていく必要があります。 https://blog.expo.dev/turtle-goes-out-to-sea-d334db2a6b60 導入 基本的にドキュメントに沿って実装すれば大丈夫でした。 実際に導入で詰まる点はありませんでした。 また、リロードを高速に保つために、デバッグビルドは事前コンパイルを使用していません。 なので導入したからと言って開発体験が悪くなるといった問題も今の所はないです。 ReactNative https://reactnative.dev/docs/hermes expoを利用している場合 https://docs.expo.dev/guides/using-hermes/ 導入結果 初期起動時間の減少 約6秒程度から3秒程度に(端末によって異なる場合あり) →起動からhome画面に遷移するまでの時間を計測 アプリサイズ減少 デバイス上のアプリサイズが約8MB減少 48MB→40MB 全体的にパフォーマンスが向上 メモリの使用率が減ったことにより、全体的にパフォーマンスが向上 最後に 仕組みや開発背景についてはMeta公式のブログに詳しく書かれているので興味のある方はぜひ見てください。 https://engineering.fb.com/2019/07/12/android/hermes/ ▼複業でスキルを活かしてみませんか?複業クラウドの登録はこちら! https://talent.aw-anotherworks.com/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【React】Qiita アドカレみたいな雪が降るアニメーションを作る

はじめに Qiita Advent Calendar 2021の2日目は、 Qiita 株式会社 プロダクト開発G デザインTMの出口(@degudegu2510)が担当します! 業務では、Qiita、Qiita Team 、Qiita JobsのUI/UX、フロントエンド、各イベント等のクリエイティブを担当しています。 今年から大きくリニューアルされたQiita Advent Calendar 2021のデザインを担当したのが僕です。 リニューアルした内容や、どうしてこのようなデザインにしたのかををまとめた記事も投稿しています。 ぜひご覧ください。 この記事では、リニューアルされたQiita Advent Calendar 2021 のTOPページの雪が降るアニメーションについての記事です。 Qiita Advent Calendar みたいな雪を降るアニメーションをつくってみたい。 particles.jsについて知りたい。 という人におすすめです。 particles.js particles.jsは、雪っぽいアニメーションや宇宙っぽいアニメーション、幾何学図形をアニメーションさせたりできるJSのライブラリーになります。 雪 宇宙 幾何学図形 パラメーターが豊富で、マウスのホバーに合わせてアニメーションさせたり、 クリックに合わせてアニメーションさせたり、色々なカスタマイズが可能です。 公式デモサイトで、パラメーターをいじりながらアニメーションを試すことができます。 (公式デモサイトをいじってるだけで楽しいです。) インストール react-particles-jsをインストールします。 ※ npmを使用する場合は、以下のコマンドでインストールできます。 npm i react-particles-js 実装 コーディングは簡単です。最小で実装するとこれだけ。 import css from '@emotion/css' import React from 'react' import Particles from 'react-particles-js' export const AdventCalendarHeroAnimation = () => { return ( <Particles params={{ {/* ここでアニメーションのパラメータを設定しています */} particles: { number: { value: 20, density: { enable: true, value_area: 2000, }, }, ... {/* パラメーターの設定が続く */} }, }} /> ) } 各パラメーターについて こちらのURLでパラメーターの値を変えることでどんなアニメーションになるか確認できます。 ここでは、各パラメーターが何が変わるかを説明します。 particles number value 画面内のシェイプの数 number density.enable valueの数を表示するareaを決めるか bool density.value_area valueの数を表示するをareaの大きさ number color value シェイプの色 string shape type shapeの形 circle、edge、triangle polygon、star、image stroke.width 枠線の太さ number stroke.color 枠線の色 srting polygon.nb_sides typeがpolygonの時の頂点の数 number image.src typeがimageの時の画像 string image.width typeがimageの時の画像の横幅 number image.height typeがimageの時の画像の縦幅 number size value シェイプの大きさ number random 大きさをランダムにするか bool anim.enable 大きさをアニメーションさせるか bool anim.speed アニメーションのスピード number anim.size_min アニメーション時のシェイプの最小の大きさ number anim.sync 全てのシェイプのアニメーションを合わせるか bool opacity value シェイプの不透明度 number random 不透明度をランダムにするか bool anim.enable 不透明度をアニメーションさせるか bool anim.speed アニメーションのスピード number anim.size_min アニメーション時のシェイプの最小の不透明度 number anim.sync 全てのシェイプのアニメーションを合わせるか bool line_linked enable_auto シェイプ間の線を引くか bool distance シェイプ間の線を引く時のシェイプ間の距離 number color シェイプ間の線の色 string opacity シェイプ間の線の不透明度(シェイプの不透明度に影響されます) number width シェイプ間の線の幅 number move enable シェイプをアニメーションさせるか bool direction シェイプのアニメーション方向 none、top、top-right、right、bottom-right、bottom、bottom-left、left、top-left random シェイプのアニメーションスピードをランダムにするか bool speed シェイプのアニメーションスピード string straight シェイプのアニメーションを真っ直ぐにするか bool out_mode 画面端に当たった時にどうするか out、bounce attract.enable 画面外に出たら消すか bool attract.rotateX 何が変わってるのかわからない number attract.rotateY 何が変わってるのかわからない number interactivity onhover enable マウスホバーでアニメーションするか bool mode マウスホバーアニメーションのモード repuse、grab、bubble onClick enable クリックでアニメーションするか bool mode クリックアニメーションのモード push、remove、repuse、bubble modes grab.distance grabモードでシェイプ間の線を引く時のシェイプ間の距離 number grab.line_linked.opacity grabモードのシェイプ間の線の不透明度 number bubble.distance bubbleモードで変化させる距離 number bubble.size bubbleモードで変化させる大きさ number bubble.opacity bubbleモードで変化させる不透明度 number bubble.duration (sec) bubbleモードで変化させる時間 number bubble.repulse repulseモードで変化させる距離 number page background page background background-color 背景色 string background-image 背景画像 string background-position 背景画像の場所 string background-repeat 背景画像のrepeat設定 string Qiita Advent Calendar Topページの実装 Qiita Advent CalendarのTopページでは、このように実装しています。 完成形 動いている様子はこちらからご確認ください コード マークアップ部分 import css from '@emotion/css' import React from 'react' import Particles from 'react-particles-js' export const AdventCalendarHeroAnimation = () => { {/*表示領域を取得するライブラリを使用しています。直接値を入れても使えます。*/} const { currentWidth, currentHeight } = useWindowSize() return ( <div css={heroStyle(heroBackgroundImage)}> {/* Qiita Advent Calendar の ロゴを入れます */} <img src={'./logo-advent_calendar.svg'} css={heroAnimationLogoStyle} /> {/* react-particles-jsで雪を表現しています */} <Particles width={`${currentWidth}px`} height={`${currentHeight}px`} style={{ display: 'block' }} params={{ particles: { number: { value: 20, density: { enable: true, value_area: 2000, }, }, size: { value: 8, random: true, }, opacity: { anim: { enable: false, }, value: 1, random: false, }, move: { direction: 'bottom', out_mode: 'out', speed: 6, random: false, }, line_linked: { enable: false, }, }, }} /> {/* 画面下にある丘の画像を入れます */} <img src={'./image-back_hill.svg'} css={heroHillStyle} /> <img src={'./image-front_hill.svg'} css={heroHillStyle} /> </div> ) } スタイリング部分 const heroStyle = (heroBackgroundImage: string) => css({ backgroundImage: `url(${heroBackgroundImage: string})`, // 背景画像を設定しています。 backgroundSize: 'contain', position: 'relative', width: '100%', }) const logoAnimation = keyframes({ '0%': { opacity: 0, transform: 'translate(-50%, -100%) scale(1.5)', ...viewportXS({ transform: 'translate(0, 0) scale(1.5)', }), }, '100%': { opacity: 1, transform: 'translate(-50%, -100%) scale(1)', ...viewportXS({ transform: 'translate(0, 0) scale(1)', }), }, }) const heroAnimationLogoStyle = css({ animationDelay: '0s', animationDuration: '3s', animationName: logoAnimation, left: '50%', maxWidth: 752, padding: `0 ${getSpace(2)}px`, position: 'absolute', top: '50%', transform: 'translate(-50%, -100%)', width: '100%', zIndex: 10, }) const heroHillStyle = css({ bottom: 0, left: '50%', minWidth: 1280, position: 'absolute', transform: 'translateX(-50%)', width: '100%', zIndex: 10, filter: 'drop-shadow(0px 4px 16px rgba(0, 0, 0, 0.5))', }) まとめ この記事では、リニューアルされたQiita Advent Calendar 2021 のTOPページの雪が降るアニメーションについてとparticles.jsについて説明しました。 particles.jsは、導入するのも実装するのも簡単でした。 特に、↓このサイトでパラメーターの設定を確認してから、実装できるので、 実装しながらパラメーターを調整することがほとんどなく、スムーズに実装できました。 雪のアニメーションだけではなく、 シェイプを桜の花びらにして、花びらが舞っているみたいなアニメーションも面白そうだなと思います。 Qiita Advent Calendar 2021の3日目も、 Qiita 株式会社 プロダクト開発G デザインTMの出口(@degudegu2510)が担当します! ぜひQiita Advent Calendar 2021を購読設定して、 明日の記事もご覧いただけると嬉しいです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

サーバーレスでWebシステム作った話

初めて記事を書きます! フリーランス2年目のシステムエンジニアです。 不慣れな部分ありますが、温かい目でお願いしますm(_ _)m また、次回に自己紹介を書こうと思いますw 今回は?? フリーランスエンジニアとして、個人で受けた初仕事としてユーザー管理システム的なものを作りました。 そのシステムをどのようなアーキティクチャー、技術で作ったかを紹介したいと思います。 ※サービス名はここでは伏せさせてもらいます、、、 仕事を受けた時の話、「こんなWebサービスつくりたんだよね〜」って言われて、色々ヒアリング開始! ベンチャー企業だったということもあり社内で使えるサーバーも保守、運用できる人員もいないので、 当時、私がAWSの勉強中だったこともあり、サーバーレスで作ってみようと提案し進めることになりましたw システム構成 さっくり描くとこんな感じの構成のものになる。 使用技術と使い方 Kotlin WebAPI実装 TypeScript+React 静的ページ実装 AWS S3 Webサイトのホスティング AWS APIGateway AWS Lambda APIGatewayと合わせてWebAPI AWS Cognito ユーザー認証 AWS CloudFront S3の前段でCDNとして使用 証明書の設定 AWS RDS MySQLを使用 ハマったこと これから描くこと以外にもハマったポイントはたくさんあったのですが、 パッと思い出した範囲で、、、 本番環境と検証環境の分離 ベストプラクティスとして環境ごとにアカウントを分離させる方法があげられますが、 アカウントは1つしか用意できず、どうしようと迷いました。 アカウントは1つで分離された環境を2つ用意、、、 結局、AWSアカウントを分割せず、VPCごとに環境を分割と環境変数で頑張りました。 今後のプロダクトの拡張次第でここら辺は改善したいですね。。。 Cognito ログイン画面をS3にデプロイし、Cognitoで認証、認可。会員用ページに遷移する。 というものにしたかったが、なかなかうまくいかず、、、 認証はうまくされているようなのにURLにパラメータが追加され、会員用ページに遷移されそうで遷移されなくて結構時間かかった。。 納期の関係もあって結局、Amplifyを使ってCognitoとログイン画面を作ったらうまく動いてくれたのでそれで進めました。 Cognito難しい、、勉強のやり直しですね、、、( ;∀;) まとめ 今年1月に企画がスタートして10月に一旦リリース完了しました。 ひとまず、致命的なバグなく動いていて安心しています! 今は、ユーザーから機能の改善案や追加機能の実装を行っています。 実際にユーザーに使ってもらって改善していくはプロダクトが育ってる感じがしていいと実感しています^^ 今回の対応を経て、壁にぶち当たったら文献漁って、解決、たまに諦めるの繰り返しでした。 知識不足をあらためて感じた次第でございます、、、( ;∀;) 今後も精進ですね、、、
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

学生のフロントエンド開発入門について

初めに 今回は、現在所属しているチーム開発に私がフロントエンド担当として参加するまでに行った勉強方法をQiitaの記事として残そうと思ったので書いて行こうかなと思います。 今回のフロントエンド開発として、typescriptの開発に入るまでの流れを記事に残していこうと思います。 プログラミング経験 私のプログラミングの経験としては、railsを半年くらい触ってからの状態からはじめました。レベルとしては、簡単なECサイトが実装できる程度になります。なので、特に才能があるわけでもできるわけでもありません。笑笑 今回主にtypescript開発に参加するまでの自分の勉強の道筋を示していくわけですが、私自身JavaScriptでrandom関数を使用したおみくじプログラム(超簡単)すらも全く分からず単位を落としそうになっていたくらいプログラミングが苦手だったので心配しなくて大丈夫です! 勉強していく順番(ざっくりと!) Html,css cssフレームワークを触ってみる! javascript学習(ES6) reactの学習 figmaの学習(UI, UXデザインの学習) reactで何か簡単なものを作成してみる!(軽いポートフォリオ?) フロントエンドとバックエンドを分けて何か作ってみる。 typescriptの学習 効率的な学習のコツ 効率的な学習のコツとしては、これは私の意見ですが、同じサイトを繰り返しで最低3回は復習をすることをお勧めします。 教科書、答え、詳しい人に聞きながらでもとりあえず実装をしてみる。 教科書だけをみて実装をしてみる(もしどうしても無理だったら答えを見る) エラーなどをもとに検索をしながら実装をする。 私が一番大事だなと感じているのは、3回目の工程になるかなと思います。 3回目まで復習をする理由としては、エラー文をしっかり読むようになるのと検索した記事を自分の場合だったらどのように書き換えれば良いのかという読み替える能力がかなりコードを書いていく上で重要だなと感じているからです!ぜひこの工程で勉強してみてください〜 具体的な進め方 HTML, CSS Progate まず一番最初はフロントの基礎である、HTML,CSSですね〜。 HTML,CSSは最初は仕組みを知ることが大事なのかなと思います。 一番最初の入門としては、やはりProgateに限ると思います。 Progateは、値段も安く教科書も初心者向けなので最初の理解としてはかなり助けになるかなと思います! 模写コーディング Progateの学習が終わったら、次にHTML,CSSの実践練習になります。具体的には、簡単な構成で描かれているHTMLのサイトのコピーを作成する練習がいいのかなと思います。私が実際に使用したサイトはもうなくなってしまったのですが、レベルとしてはこちらのサイトくらいのサイトを模写するのが練習になるかと思います! 模写コーディングを学習していて、答えはどうするの?という疑問が生まれるかなと思いますが、そんな時は開発者ツールを使用しましょう! この開発者ツールを開くには、サイトに移動してからサイトの上で右クリックをして検証というタブを開く、もしくはF12、command+option+Jのショートカットキーでも開くことができます。この開発者ツールのElementsという場所に実際のコードが乗っているのでこちらが答えになります。 模写するサイトで使用されている画像の撮り方としては、Sourceというタブのページのaseetsのフォルダの中にサイトで使用されている画像が格納されているので、assetsで画像を開いて開いた画像の上で右クリックでsave image as...をクリックして保存を行いましょう! css フレームワーク bootstrap bootstrapはかなり初心者向けのCssフレームワークになるかなと思います。素のCssだけで書いていた人からするともう目から鱗の状態なのではないかなと思います。最初からcssのフレームワーク使えばよかったのではないか?と思われる方もいらっしゃるかもしれませんが、私が最初からフレームワークを使用しなかった理由としては、cssのプロパティが何があるかわからない状態で使用しても効率が悪いと思ったからです。最初はCDNで1行読み込むだけで使えるようになっているところから始めるのがいいかなと思います! bootstrapCheatsheetや公式リファレンスをみながらぜひ勉強してみてください。 サンプルコード↓ <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="description" content="" /> <meta name="author" content="" /> <title>タイトル</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" /> </head> <body> <div class="container">Hello!</div> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script> </body> </html> 余力があれば!! tailwind css bootstrapの上位互換のフレームワークになります。bootstrapと基本的には書き方は同じになりますが、指定できる値が細かくなるのでその分カスタマイズ性も高くなり難しくもなります。フロントエンド開発の現場でも最近取り入れられているので、学習しておいて損はないと思います。bootstrapはjavascriptの記述も入っているのに対して、tailwindCssは純粋なCssで書かれているので他のコードとの競合が起きにくいという利点があり、この利点が実際の現場でも取り入れられている理由の一つです。 material ui マテリアルUIはreact開発の王道Cssフレームワークになります。かなり多くの現場で昔から使われているものになりますので学習しておけば間違いのないcssフレームワークになるかなと思います。bootstrapとは若干使い方が変わってくるのでそこは注意かなと思います。 実行環境について ここからは余談ですが、学習を行う際の実行環境についてお話をしたいと思います。 jsなどを走らせるためには、その言語を実行できる環境を用意する必要があります。 環境構築は、qiitaなどに環境構築の方法を検索するとたくさん出てきますが使っているパソコンごとにパスの通し方が違ったりコマンドがありませんよ〜ってエラーが出たりするので初心者にはかなりきついものがあるかなと思います。 私は自分のローカルに環境を構築して開発を進めておりましたが、環境構築だけで何日も取られてしまいかなり勿体無いことをしたな〜と反省をしました。笑 なのでここでは、環境構築をしなくても開発を進めることができるテキストエディターサイトを紹介したいと思います。 playcode こちらはjavascriptの勉強に使えるかなと思います!(私は使ったことありません笑) codesandbox こちらはreactやtypescriptの勉強に使えるかなと思います! 後々に紹介するじゃけえさんの講義でもcodesandboxを使用しているのでおすすめです! nodeのパッケージもコマンドを打たずともインストールができるので感覚的に使えるので最初の入りとしてはかなり良いのかなと思います! cloud9 最後に紹介するのは、cloud9というamazonのawsが運営しているサービスになります。 cloud9が上記の二つと違うのは、ほとんど全ての言語に対応をしている点です。 cloud9では、プロジェクトの新規作成の際にコマンドを打つ必要があります。 しかし、コマンドを実行する環境はどのかたが使っても同じになっているのでqiitaや公式リファレンス記事をそのまま実行すれば間違いなく動くはずです。 react環境構築 (https://qiita.com/naitya0412/items/6ca962e16d77e0d04273) typescript環境構築(若干難しい) (https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/sample-typescript.html) javascript学習(ES6) Progate こちらの学習もまずはprogateのjavascriptのコースを受講してみてください。コースとしては、ES6のjavascriptを受講することをお勧めします。 udemy progateの受講が終了した後は、udemyのじゃけえさんの講義を受講することをお勧めします。しかし、この段階ではjavascriptまでしか学習をしていないのでjavascriptでTodoアプリを作成するところまで進めましょう。 react学習 Progate こちらもreactの講座があるので、reactの講座を受講しましょう。 udemy その後はjavascriptと同様、じゃけえさんの講義を最後まで受講することをお勧めします。この講座では、素のjavascriptで作ったtodoアプリと全く同じものをreactで作るという講座の内容になっているため、reactがなぜ便利なのかreactで書くとどのようなメリットがあるのかを感じられるためかなり勉強になります。 figmaの学習(UI, UXデザインの学習) サンプルサイトのトレース figmaの学習方法としては、すでにあるサイトをfigma上でコピーしてみるのがかなり勉強になると思います。 yutube この辺の初学者向けfigmaの動画も参考になるかと思います! udemy udemyでの学習ではudemy講座この講座の評価が良かったので参考にするのもアリかと思います! reactで何か簡単なものを作成してみる!(軽いポートフォリオ?) ここまでできたら簡単なアプリをreactで作ってみましょう。 簡単なアプリの目安としては、Todoアプリに毛が生えたくらいのレベルのもので問題ないと思います。 私はこの段階では、自分が読んだ本の感想を投稿するアプリを作成しました。 フロントエンドとバックエンドを分けて何か作ってみる。 このセクションでは、今までは一つの言語だけで何かアプリを制作してきましたが、これまでのものはデータベースを接続していないので投稿を行っても一度リロードを行ってしまうと消えてしまう仕様になっておりました。そこでこの章では、実際にバックエンドのコードを追加してreactで作ったtodoのタスクが保存されるようにアップデートをしてみましょう! フロントエンドとバックエンドを分けて作成する際に、バックエンドとして使用する言語は何を使用しても問題はないと思います!私が作成した時には、フロントエンドはreactでバックエンドの言語としては、pythonのフレームワークであるflaskを使用して作成いたしました。 今回フロントエンドとバックエンドを分ける理由としては、それぞれフロントエンドに強い言語とバックエンドに強い言語があり言語を分けて作成することがかなり多いので、その際にフロントエンドとバックエンドを接続するという作業が生まれます。その際に、使用するjson(データフォーマット)やproxy(代理サーバー)などの技術を知っている必要があるのでフロントとの接続を勉強することはかなり大事な勉強になるかなと思います! yutube(react × flask) reactとflaskを使用して作成する場合の参考にしたサイトとしては、この動画を参考に勉強しました。全部見ると長いと思うので、この動画の50分過ぎから視聴するのがいいかなと思います! yutube(react × rails) もう一つ全部を見たわけじゃないのですが、reactとrailsを使用して作成する場合はこちらの動画を参考にしてみるのもいいかと思います! 近年バックエンドの言語としてrailsを導入している企業も多いので、railsを使用してみるのもアリかもしれないです〜〜! typescriptの学習 いよいよtypescriptにここで突入になります〜〜 typescriptはなんと言っても型の理解が重要になってくるのかなと思います。最初は型の理解から始めていくのがいいかなと思います!! udemy 超Typescript入門 完全パック この講座は14時間とかなり長いのですが、typescriptの基礎的なものを全て解説してくれており最後には健康管理アプリをtypescriptで作成するハンズオンもあるのでかなり充実したコースになっているかと思います! 書籍 プログラミングTypeScript 書籍の学習であれば、この本の評価が高かったので書籍で勉強する方が良いという方はこちらの本を購入して勉強してみるのもいいかもしれません。私は、本は昔から苦手なので動画で勉強しました。笑 最後に ここまで長くなりましたが、この記事を読んでくださりありがとうございました! 私はこの記事の内容のことをおよそ3ヶ月かけて学習を進めていきました。 javascriptを触るのがほとんど初めてということもあり、かなり苦戦をしましたが昔に比べればかなり書けるようになった気がします!私の学習方法が、参考になりましたら幸いです!!!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UI コンポーネントにマージンを付けずに実装する - Chakra UI の場合 -

この記事は、React Advent Calendar 2021 1 日目の記事です。 定期的に話題になる、UI コンポーネントでの余白 (margin, padding) をどうするか問題。 昨日も Zenn に解説記事が流れてきました。 (参照記事の参照記事) Zenn の記事の中で、UI ライブラリーにはレイアウト (Box モデル) が当たり前に存在する と記載がされています。 (※一部引用) 例えば、Chakra UIではレイアウト(Boxモデル)に特化したコンポーネントが存在します。 Chakraのレイアウトの責務を持ったコンポーネントの豊富さは大変魅力的ですね。 そう、Chakra UI のレイアウト関連コンポーネントは、大変魅力的なのです・・・! ということで、マージンを持たない UI コンポーネントを Chakra UI で作ってみようと思います。 保険 React を仕事で使い始めてから 3 ヶ月、Chakra UI は 1 ヶ月程度です。 Case 1. 保存ボタンコンポーネント (SaveButton) データを保存するアクションを表す、保存ボタン (SaveButton) コンポーネントを作っていきます。 Atomic Design でいう、Molecules に該当するかなと思います。 コンポーネントの要件は次のとおりとします。 ボタンは緑色 左側にチェックアイコンがついている シンプルな実装 とりあえず要件を満たせるコンポーネントを作ってみます。 ※注意: コメントは見やすさを優先して、すべて // で統一していますが、このままでは動かない箇所がある可能性があります。 import { CheckIcon } from "@chakra-ui/icons"; import { Button, ButtonProps } from "@chakra-ui/react"; export interface SaveButtonProps extends ButtonProps {} // (1) const SaveButton: React.FC<SaveButtonProps> = (props) => { const { children, ...buttonProps } = props; // (2) return ( <Button colorScheme="green" // (3) leftIcon={<CheckIcon />} // (4) {...buttonProps} // (5) > {children} // (6) </Button> ); }; export default SaveButton; No 説明 (1) コンポーネント用の Props インターフェースを、ベースとなるコンポーネントの Props 「ButtonProps」 を継承して定義する。 (2) ボタンのテキスト children とそれ以外の Props (ButtonProps の中身) で分ける。 (3) ボタンの色を緑色にする。 (4) ボタンの左側にチェックアイコンをつける。(アイコンは Chakra UI が提供する @chakra-ui/icons を利用。) (5) ベースコンポーネントの Props をすべて渡す。 (6) ボタンのテキストを指定する。 使い方は次のとおりです。 import SaveButton from "./components/SaveButton"; // 中略 <SaveButton>Save</SaveButton> このように、ボタンの文字を指定するだけでいい保存ボタンコンポーネントができました。 DevTools などで見てみると、この時点でマージンは指定されていません。 このコンポーネントの Props は、ButtonProps を継承して定義しているため、Button を拡張するようにデザインを変更することができます。 // 横幅を親要素いっぱいに広げる <SaveButton w="full">ほぞーーーん</SaveButton> // 角張ったボタンにする <SaveButton borderRadius={0}>SAVE</SaveButton> マージンの指定について Button には、マージンに関する Props を持っているため、コンポーネントを定義したあとでも自由にマージンを指定することができます。 // 例) 縦並びは margin-top を設定 <SaveButton>あっちに保存</SaveButton> <SaveButton mt={2}>こっちに保存</SaveButton> // 例) 横並びは margin-left を設定 <SaveButton>そっちに保存</SaveButton> <SaveButton ml={2}>どっちに保存?</SaveButton> 制限をつけた実装 マージン関連の話題からそれますが・・・。 Button のもつ Props を使えるため、柔軟である一方、ボタンの色やアイコンも上書きすることができます。 // 赤い色で、ワーニングのアイコン <SaveButton colorScheme="red" leftIcon={<WarningIcon />}>Save?</SaveButton> これだとコンポーネントを用意した意味がありません。 ということで、必要な機能に絞ったコンポーネントを作ってみます。 import { CheckIcon } from "@chakra-ui/icons"; import { Button, ButtonProps } from "@chakra-ui/react"; export interface SaveButtonProps { children: string; // (1) onClick?: React.MouseEventHandler<HTMLButtonElement>; // (2) buttonPropsEx?: ButtonProps; // (3) } const SaveButton: React.FC<SaveButtonProps> = ({ children, onClick = () => {}, buttonPropsEx = {} }) => { return ( <Button colorScheme="green" leftIcon={<CheckIcon />} onClick={onClick} {...buttonPropsEx} // (4) > {children} </Button> ); }; export default SaveButton; No 説明 (1) ボタンのテキストを指定できるようにする。 (2) ボタンクリック時のイベントを指定できるようにする。 (3) どうしてもボタンを拡張したくなった場合の拡張ポイント。 (4) 緊急ハッチをすべて展開する。 制限をかけるとしても、どうしても拡張が必要な場面が出てくるかもしれません。 その場合に備えて、ButtonProps を直接指定する buttonPropsEx という Props を用意しました。 こうすることで、柔軟性をもたせつつ、ある程度制限をかけたコンポーネントを作ることができます。 もちろん、TypeScript の型も効いています。 また、この例のように xxPropsEx という名前にすることで、拡張している箇所を PropsEx で検索することができるため、必要以上に拡張されていないかを調査することもできます。 // こらこら・・・! <SaveButton buttonPropsEx={{ colorScheme: "red", leftIcon: <WarningIcon /> }} > Delete </SaveButton> Case 2. ヘッダー 次に、ページのヘッダーを作ってみようと思います。 Atomic Design では Organisms 相当でしょうか・・・。 コンポーネントの要件は次のとおりとします。 左側にプロダクトアイコンを表示する。(今回は簡略化するため、アイコンを表示する。) アイコンの右にメニューを表示する。 ヘッダーの右に、ログインユーザーの情報を表示する。 よくあるヘッダーですね。 実装 Organisms レベルのコンポーネントを作るときは、基本的に <Box> で囲ってしまってもいいでしょう。 import { StarIcon } from "@chakra-ui/icons"; import { Box, BoxProps, Heading, HStack, Spacer, Text } from "@chakra-ui/react"; export interface PageHeaderProps extends BoxProps {} // (1) const PageHeader: React.VFC<PageHeaderProps> = ({ ...boxProps }) => { return ( <Box px={6} py={4} borderWidth="1px" {...boxProps}> // (2) <HStack spacing={4}> <Heading size="md"> <StarIcon /> </Heading> <Text>メニュー 1</Text> <Text>メニュー 2</Text> <Text>メニュー 3</Text> <Spacer /> // (3) <Text>あなた 様</Text> </HStack> </Box> ); }; export default PageHeader; No 説明 (1) BoxProps を拡張した Props インターフェースを定義する。 (2) Props をすべて渡す。 (3) Chakra UI にて、中間を開けることができるコンポーネント。 Case 1. のシンプルな実装で説明したとおり、BoxProps を継承した Props を採用することで、Box に指定できるものは何でも指定することができます。 マージンの指定 コンポーネントを配置したあとで、必要に応じてマージンなどを指定することができる ようになります。 import PageHeader from "./components/PageHeader"; // ページヘッダーを、画面上部からちょっと離す。 <PageHeader w="100vw" mt={4} /> まとめ Chakra UI を使用して、コンポーネントをいくつか定義してみました。 Chakra UI の Style に関する Props を使用することで、コンポーネント自体にマージンなどを定義しなくても、あとから どうにでも 柔軟にレイアウトができることが分かりました。 Chakra UI には、今回紹介した Box の他にも、中央揃えする Center や、縦並び、横並びにする Stack, VStack, HStack、複雑なレイアウトを実装できる Flex, Grid, SimpleGrid など、レイアウトに関するコンポーネントが多く用意されており、大変魅力的 です! ・・・うっかり Chakra UI はいいぞ みたいな記事になりかけてしまいましたが、Chakra UI はユーティリティベースで 型安全な Tailwind CSS として使えると思うので、まだ触ったことのない方はぜひ試してみてはいかがでしょうか。 明日 12/2 は、 @denkiuo604 さんの MUIで作った簡単なクイズアプリ(あとで更新) です。 付録: CodeSandbox に React + TypeScript + Chakra UI の環境を作ったときのメモ (できあがったテンプレートが こちら (CodeSandbox) です。Fork してお使いください。) CodeSandbox の「Create Sandbox」をクリックし、テンプレート React TypeScript をクリックする。 Dependencies に、次の 4 つと、アイコン関連のライブラリーを追加する。(2021 年 12 月 1 日時点の Chakra UI 公式サイト より) @chakra-ui/react -> 1.7.2 @emotion/react@^11 -> 11.7.0 @emotion/styled@^11 -> 11.6.0 framer-motion@^4 -> 5.3.3 @chakra-ui/icons -> 1.1.1 App.tsx を次のとおり変更する。 import { Box, Center, ChakraProvider, Heading, Text, VStack } from "@chakra-ui/react"; import "./styles.css"; export default function App() { return ( <ChakraProvider> <Box> {/* 外枠 */} <Center> {/* 子要素を中央に配置する */} <VStack> {/* 子要素を縦に並べる */} <Heading>Hello CodeSandbox</Heading> <Text>Start editing to see some magic happen!</Text> </VStack> </Center> </Box> </ChakraProvider> ); }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL + UbuntsでWindows上にReact開発環境を作る

目次 1.はじめに 2.インストール 3.anyenvが起動できない 4.そしてsshでのクローンでハマる 5.おわりに 1. はじめに Windowsで基幹システムしか作ってこなかったエンジニアがReact/Typescriptに挑戦する。 前回の記事にて、「Web開発ならLinuxを使え」という結論に至りました。しかし2児の父がそんなMacを買ってもらえるわけもありません。 なので、WSLを使ってWindows上に作る形にしました。 2. インストール 前回の記事で紹介しましたが、今読んでいる書籍にあった手順に従いインストールをします。 3. anyenvが起動できない 上記リンク先の手順に従ってインストールをしていると、以下の箇所で詰まります。 anyenv install nodenv 実行してもanyenvにパスが通っておらず(gitからダウンロードしただけだから当然だな)、コマンドが失敗します。そこでanyenvの公式サイトの「Manual git checkout」の以降の箇所を参照しました。 パスを通すために実行したコマンドは以下です。 echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.zshrc 書籍の手順ではパスを通すコマンドが足りなかったのでした。 4. そしてsshでのクローンでハマる さて、順調にセットアップを進めていったところ、VSCodeの拡張機能インストール確認の手順でハマりました。 適当なプロジェクトをローカルに用意する git clone git@github.com:oukayuka/Riakuto-StartingReact-ja3.1.git SSH経由でのGit Clone手順。そう、やったことがなかったのです。 ここの手順が一番わかりやすかったかしら。 ローカル側LinuxでSSH公開鍵を作る 作った公開鍵の中身(テキスト)をコピペ GithubのsettingからSSH keysを登録する 5. おわりに Linuxも触ったことがあったのでパスとは思いましたが、やはり作法は公式に従ったほうが良いと思い、anyenvのサイトを参照しました。 なお、書籍ではzsh(MacOSでは標準なの?)を使っているらしいので、それに合わせていきます。はい。従いますお姉さま。(元bash使い) 改めてインストールしたものをまとめます。 Windows上 dism.exeからWSL WSL2へアップグレード マイクロソフトストアからUbuntu マイクロソフトストアからWindows Terminal Visual Studio Code (もともとあった) VSCodeにRemote - WSL拡張機能 Ubuntu上 anyenvからnodenv nodenvからNode.js (現在の最新17.1.0と14.4.0) 使うパッケージたち(yan, typescript, ts-node, typesync) これはnotenv rootのdefault-packagesというファイルに記述する Github接続用のSSHキー生成
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

React.memoを使いつつ型引数を利用する

はじめに 型引数を受け取るコンポーネントにReact.memoを利用するとそのままでは型を渡すことができません。 そのような際の簡単なハックを記載します。 例 以下のコンポーネントがあったとします。 type Props<T> = { value: T; } const SomeComponent = <T>({ value }: Propd<T>) => { return ... }; React.memoの返り値は型引数に対応していないのでそのままReact.memoを利用すると以下のような定義になりコンポーネントに対して型を渡すことができなくなります。 const Memoized = React.memo(SomeComponent); // const Memoized: React.MemoExoticComponent<(<T>({}: SomeProps<T>) => JSX.Element)> <Memoized<number> value={1} />; // -> TS2558: Expected 0 type arguments, but got 1. ※ この用途であれば<number>を渡さなくても問題ないのですがシンプルな例として記載しています 解決方法 以下のようにすることで対応可能です。 const Memoized = React.memo(SomeComponent) as typeof SomeComponent; // そのままexportも出来ます export default React.memo(SomeComponent) as typeof SomeComponent; シンプルですが利用する頻度も多いと思うので誰かの役に立てるよう残しておきます
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Twitterに誰でもドット絵を投下できるサービスを作ったよ

どうも今年もやってきました クソアプリアドベントカレンダー 1の2日目を担当させていただきます @nabettu です。 今年で参加5年目らしい。まじかよ。 過去のクソアプリ達 作ったもの 今年作ったのはこちら! 100 Pixel Artというドット絵が書けるWebサービスです。 どんなサービスか 絵文字の ⬜ ? ? ? ? ? ? ? ⬛ の9色の四角のみを使ってドット絵が描けるサービスになります。 10かける10で100ドットのみ9色限定で、9^100パターンのみ作れるエディターになっております。 キャンバスサイズが100ドットのみで、使える色も9色しかないというポイントがクソアプリ的制限です! サービスの特徴 このサービスの特徴として「Finish」ボタンを押すと、編集が完了すると絵文字なのでそのままテキストとしてコピーできます。 つまり完成したらそのままTwitterでテキストとしてつぶやくことができるんです! 画像としてどこかに保存しなくていいし、そのままシェアできて便利ですね〜。。。 (あれ、、、思ったより全然クソアプリじゃないかも、、、) 技術的な話 React(ルーティングとかないけどNext.jsを使うだけ使っています) Cloudflare Pages Cloudflare Pagesめちゃめちゃ便利なのでみんな使うと良いと思います!Netlifyがアジアリージョンなくなって悲しんでいた方におすすめです。 苦労したポイント 表示はCanvasを使わずにDomでやっています。 ドットをクリックして絵文字が切り替わるのはonClickで設定するだけなのですが、ドラッグしてもちゃんと絵文字が反映されるようにするのがちょっと工夫が必要でした。 PCの場合:マウスでの動作について キャンバス上でクリックダウンされたらフラグをON マウスがクリックアップされたらフラグをOFF キャンバスからマウスカーソルが外に出たらOFF キャンバス上でフラグがONの状態でドラッグされていたら文字を変える という形で実装できました。 スマホの場合:タッチでの動作について 基本のタップはPCと同じ形にしておりますが、タッチしながらの移動(タッチムーブ)は同じ実装では動きません。 タッチムーブではイベントがタッチし始めのdomから発火してしまうので、 タッチムーブで別な要素への移動を検知 移動後の座標を確認 キャンバス全体からの相対座標で10*10の中のどこにいるかをチェック その座標の位置の文字を変える というちょっとした計算を追加して実装しました。 (・・・素のJSで作ってしまったのでライブラリ探してもよかったな!笑) Androidでは四角のカラー絵文字が無い これは困ったのでNoto Color Emojiを入れました。 ※ Apache 2.0ライセンス です。 以上です! クソアプリアドベントカレンダー2021 二日目、100 Pixel Artでした! 明日は@alclimbさん「2021年×おバカアプリ✨」なクソアプリをよろしくお願いします!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Reactのコンポーネントを生成するCLIアプリをNode.jsの標準機能のみで作ってみた話

この記事はTDU CPSLab Advent Calendar 2021 - Adventarの1日目の記事です 前の記事はありません、次の記事はこちらから。 追記 研究室で共有したところ、 Typescriptでのリファクタリングをnaruminchoが早速してくれました!!! シンプルに自分が知らなかったNode.jsの機能使っていたり、 Typescriptの型定義の工夫も学べるかと思いますので、 是非こちらから御一読ください!! はじめに amplify codegen (生成されるファイル達) かっこいい〜!!! codegenってお前。。genってめっちゃかっこいいじゃん。。 generateだよね?それをgenってなんか良くない? 俺もgenしたいな!! なんかこうバシッとgenしたいな!! ...という良くわかんない動機があって、 普段私が手動で作っていたReactコンポーネントをgenするCLI(脳筋)を作るに至り、 そのご紹介をしたいと思います。 以下、回避運動ですが。 筆者は(ガチで)雰囲気でプログラミングしているので書き方がダサい・デフォルトでそういう機能がある・実現できる便利なパッケージがあるなどが起きていましたら申し訳ありません。追記しますので、コメント欄でボソッと教えてくださると嬉しいです。...記事は作ってみた記事的に供養として残させていただけたら嬉しいです。 目次 開発環境 どんなことができるの? 実装内容 入力受け取り処理の作成 コード生成処理の作成 package.jsonに登録 開発環境 実現目標的に筆者の土台は create-react-appで生成されたプロジェクト 及びそれを駆動させているNode.js環境 yarnを使っている という感じですが。 もちろん、Node.jsが入っていればそれだけで大丈夫です。 どんなことができるの? 用意されているコマンドと、その挙動の対応は以下の通りです。 yarn page:codegen      → pageフォルダ配下にコンポーネントを生成する yarn layout:codegen  → layoutフォルダ配下にコンポーネントを生成する yarn comp:codegen      → componentフォルダ配下にコンポーネントを生成する そもそもの前提としまして、私は再利用可能なコンポーネントが集まるcomponentフォルダ・ページ毎のUIを整形するlayoutフォルダ・APIとの通信を行うpageフォルダといった具合に階層構造で分けております。なので上記のような3つのコマンドが定義されております。 続いて、以下の質問を答えることでコードを生成します。 yarn comp:codegen yarn run v1.22.11 $ node ./scripts/comp-codegen.mjs Code-gen : Create Presentational Component ? What file path ex) common/Button > common/Button ? What class name ex) Button > Button ? Create story(Y/n) > Y { filepath: 'common/Button', classname: 'Button', story: true } Start Code Generate... Succeded!! ✨ Done in 11.76s. 生成されるコードはStorybookの定義ファイルとReactコンポーネントのファイルです。 上記の例ではcomponents/common/Buttonフォルダ内に生成されます。 実装内容 大きな流れは以下の通りです。 ユーザの入力を対話的に受け取る処理の作成 ファイル生成を行う処理の作成 package.jsonに登録 特筆したいところは、何か便利なフレームワークやパッケージの導入はせずに、Node.jsの標準的な機能のみで作成したいという欲求がありました。そこで参考記事を探していたところ、napoporitataso様の個人ブログの記事に出会うことができ、参考にさせていただきました。本当にありがとうございます! (自分初めて記事投稿するのでよくわかってないのですが、こういうのってご本人様に連絡差し上げたほうが良いのですかね?) 入力受け取り処理の作成 コードは以下のような感じ。 cli.mjs /* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import * as readline from 'readline'; import * as process from 'process'; const reader = readline.createInterface({ input: process.stdin, output: process.stdout, }); // ④で使用 const getAnswer = (msg) => new Promise((res) => reader.question('? ' + msg + ' > ', res)); // ① 複数の質問を引数に取る export const cli = async (questions = []) => { const answers = {}; let answer, question; let name, type, message; // ② 各質問の構成要素 let result; // ③ それぞれ質問をしていく for (question of questions) { result = ''; ({ name, type, message } = question); // ④ ユーザの入力を待ち受ける result = await getAnswer(message); // ⑤ typeに合わせて簡単に値のチェックを行う switch (type) { case 'text': if (result !== '') { answer = result; } else { console.log('Invalid value'); } break; case 'number': if (result !== '' && parseInt(result)) { answer = parseInt(result); } else { console.log('Invalid value'); } break; case 'boolean': if (result.toLowerCase() === 'y' || result.toLowerCase() === 'n') { switch (result.toLowerCase()) { case 'y': answer = true; break; case 'n': answer = false; break; } } else { console.log('Invalid value'); } break; } // ⑥ answersに追加していく answers[name] = answer; } // ⑦ 返す return answers; }; ざっくり解説 ① 複数の質問を受け取り、その答えを返却する関数、cliをエクスポートしてます。 ② それぞれの質問は name,type,message の三要素の存在を保証します。例えばコンポーネント作成の際は以下のようなquestionsが入ってきます。 const questions = [ { type: 'text', name: 'filepath', message: 'What file path ex) common/Button', }, { type: 'text', name: 'classname', message: 'What class name ex) Button', }, { type: 'boolean', name: 'story', message: 'Create story(Y/n)', }, ]; ③ 上記のquestions配列をforで回して聞いていきます。 ④ getAnswer関数でユーザからの入力を待ち受けます。こちらの関数のほうはめちゃくちゃ参考記事様の方を参考させていただきました。 ⑤ questionsのtypeを参照して、簡単にですが値のチェックをしています。numberは使ってないから要らないんですけどもね。。。 ⑥ 値チェックが通過したらanswersに格納されていきます。 ⑦ 全ての質問が終わったらanswersを返して終了です。 ファイル生成処理の作成 コードは以下のような感じ。コンポーネントを作る時のスクリプトを代表して書きます。 comp-codegen.mjs import * as fs from 'fs'; import * as process from 'process'; import path, { dirname } from 'path'; import { fileURLToPath } from 'url'; import { cli } from './cli.mjs'; const questions = /*上で書いたやつと同じなので省略*/; const __dirname = dirname(fileURLToPath(import.meta.url)); const main = async () => { console.log('Code-gen : Create Presentational Component'); // ① 対話処理を使用 const answers = await cli(questions); console.log(answers); console.log('Start Code Generate...'); const from_dir = path.join(__dirname, '../scripts/template/component/'); const to_dir = path.join( __dirname, '../src/components/' + answers['filepath'] + '/' ); // ② フォルダ生成 fs.mkdirSync(to_dir, { recursive: true }); // ③ テンプレート生成(脳筋ポイント) let readcomp = fs.readFileSync(from_dir + 'index.tsx', 'utf-8'); readcomp = readcomp.replace(/COMPONENTTEMPLATE/g, answers['classname']); fs.writeFileSync(to_dir + 'index.tsx', readcomp); // ④ ストーリーテンプレート生成(脳筋ポイント2) if (answers['story']) { let readstory = fs.readFileSync( from_dir + 'componenttemplate.stories.tsx', 'utf-8' ); readstory = readstory.replace(/COMPONENTFILEPATH/g, answers['filepath']); readstory = readstory.replace(/COMPONENTTEMPLATE/g, answers['classname']); fs.writeFileSync( to_dir + answers['classname'].toLowerCase() + '.stories.tsx', readstory ); } console.log('Succeded!!'); process.exit(); }; (async () => { await main(); })(); ざっくり解説 ① 先ほど紹介した対話的にユーザの入力を取得する関数を使っています。 ② 質問で取得した「ファイルパス」の情報に従ってフォルダを作成しています。このmkdirSyncですが、Syncじゃない方も存在します。 ③ 作成したフォルダの中にReactコンポーネントを記述するindex.tsxを生成しています。そしてここからが脳筋(だと思っている)ポイントです。やっていることは以下の通りです。 予め../scripts/template/componentに用意されたindex.tsxの記述内容を読み込む。 正規表現を使ってCOMPONENTTEMPLATEという文字列を質問で取得した「クラス名」で置き換える。 書き出す つまり、テンプレート用のファイルが用意されており、それを複製しているような感じなんです。手動コピペを機械的にコピペできるようにしただけ..。もっといい感じの方法あるかなぁという気持ちがあります。テンプレートがどんな感じなのかは折り畳みで書いておきます。 index.tsxのテンプレート index.tsx import React from 'react'; export const COMPONENTTEMPLATE = (): JSX.Element => { return <div></div>; }; ④ 作成したフォルダの中にStorybookの定義ファイルを生成しています。やってることは③と全く同じです。 Storybookのテンプレート componenttemplate.stories.tsx import React from 'react'; // also exported from '@storybook/react' if you can deal with breaking changes in 6.1 import { Story, Meta } from '@storybook/react/types-6-0'; import { COMPONENTTEMPLATE } from '.'; export default { title: 'component/COMPONENTFILEPATH', component: COMPONENTTEMPLATE, argTypes: { backgroundColor: { control: 'color' }, }, } as Meta; const Template: Story = (args) => <COMPONENTTEMPLATE {...args} />; export const Default = Template.bind({}); Default.args = {}; package.jsonに登録 あとはpackage.jsonのscriptsの中で、以下のように追記すればOKです! package.json { "scripts": { ~省略~, "page:codegen": "node ./scripts/page-codegen.mjs", "layout:codegen": "node ./scripts/layout-codegen.mjs", "comp:codegen": "node ./scripts/comp-codegen.mjs" }, } そんなこんなで いつも手動でファイル作っていたのですが、cliで作れるようになりました。 まとめ 今回はよくわかんないモチベーションから非常に泥臭い感じの自己満なcliが完成しました。 特に予め用意したファイル読み込んで書き出す処理とか、なんかもっといいのないかなって思っております。 まあでも、こういうちょっとした自動化するのはなんか楽しいです。楽しいのでヨシ! 補足ですが、簡単にcliの作り方を調べた際に、もっとカラフルであったりアニメーションを付けたりできる高機能なcliアプリを作るためのフレームワークやライブラリがありました。npmに登録してってやる方はそういったもの使われた方が良い感じかと思います。 初めての記事作成で、お目汚し失礼しました。 記事書くの楽しかったのでまた書きたいと思います。 参考記事 Node.jsの標準機能で超単純な対話的CLIを作るサンプル Node.jsでのCLIの作り方と便利なライブラリまとめ
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UXデザイナーとして4ヶ月で学んだこと

初めまして、NSSOLにてUXデザイナーをしている1年目の濱岡と申します。 今回縁あってQiita Advent Calendarに投稿させて頂くことになりました。 本記事の要件は以下になります。 目的 新卒配属からUXデザイナーとして、約4ヶ月で取り組んできたことと所感の共有 想定している読者 Qiita Advent Calendarの参加メンバー、Qiitaの閲覧者。あわよくばUXデザイナー/NSSOL/サービスデザイン部に興味がある就活生も。 読者の方々に伝えたいこと UXデザイナーがどんなことをしているのかを理解し、面白い!と思ってもらう。また、自分がこれまでの取り組みから得た学びを実践してもらう。 目次 1.自己紹介 2.11月までにやったこと 3.これまでに得た学び 4.おわりに それでは記事の内容に入ります。 1. 自己紹介 まずお主誰じゃ、というツッコミが入るかと思うのでサラッと自己紹介します。自分は現在NSSOLのDXIC(Digital Transformation & Innovation Center)という事業部の、サービスデザイン部に所属しています(新卒1年目)。趣味は旅行、食べログランキング上位のお店巡り、読書、サウナ、韓ドラの視聴です。大学では材料科学の分野を専攻していました。入社時のITスキルはというと、Progateを触ったり基本情報技術者試験の勉強をしたぐらい。デザインの事もノンデザイナーズ・デザインブックを、興味本位で読んだことがあるぐらいのまっさらな状態でした。 ではなぜUXデザイナーを志望したか、理由は2つあります。 1つ目は、好奇心が強く色々なことをしてみたいと思ったからです。かなりのミーハーなので、新しいもの・面白そうなものがあったら飛びついてしまうんですね。SI業界を選んだのも、同様の理由です。 2つ目は、人の体験に関わるような事をしてみたかったから。これまでの人生を振り返ると、自分の人生を豊かにしてきたのは「モノ」よりも「体験」だと感じていました。外車に乗るとか、良い時計を付けたいなどの野心的な物欲があまりなく、それよりも旅行やスポーツなどを通じ、自分の記憶に残るような体験を毎日したいと考えていました。それが転じて、自分のみならず人の体験を豊かにできるような仕事をしたいと思うようになったのだと思います。 2. 11月までにやったこと 次に自分が4月から現在(11月末)までにやってきたことをざっくり紹介します。 4~6月:全体研修(ビジネススキル、WF開発の進め方、Java・基盤系の基礎) 7月上旬〜7月中旬:デザイン&アジャイル研修(デザイン思考とアジャイルのマインドを身につける) 7月下旬〜9月上旬:サービスデザイン部に本配属され、社内サービスをスクラムで開発していくPJに参加。UXデザインで具体的にやったことは以下になります。 ユーザインタビュー ペルソナの作成 OOUI(オブジェクト指向UI)の概念の学習 Material Designの読み込み スタイルガイドの作成 Adobe XDを使って画面をデザイン 9月中旬〜9月末:内定者向けの事業部紹介資料をリデザイン 資料の用途や目的、ターゲット及びターゲットに起こして欲しいアクションの整理 DXICの所長や、各部署の部長にインタビュー(緊張しました!) スタイルガイドの作成 インタビュー内容を元に、各スライドの中身をメッセージが強調されるよう修正 10月〜11月末(現在):模擬PJに復帰 Reactを用いて実装(HTML/CSS/JavaScript) 開発しているサービスのブランディング 途中で色彩検定/基本情報技術者試験/応用情報技術者試験/認定スクラムマスター研修などの資格も取得したり、10月末にDesignshipというイベントに参加したりもしましたが、やってきたことは大体こんな感じです。 3. これまでに得た学び さて、ここからの内容は自分がこれまでに得た学びになります。 チームワークがめちゃ大事 これは自分がスクラムチームに参加してから強く感じ、かなり衝撃でした。なにせ自分の中ではデザイン/エンジニア/リモートワークという言葉からは、黙々と個人作業を進めていくイメージが想起されていたからです。ところが現在行っているスクラム開発では、スクラム/アジャイル的にこの考え方・振る舞いはどうか?チームとして問題解決に取り組めているか?と、チームやメンバーの動きに関する議論が非常に多く交わされています。 スクラムやアジャイルに関するドキュメントは下記を参照。 就活時に「チームで働くのが好きな人はSIerに向いている」と聞いていましたが、こういうことなのかなと実感しています。実案件でスクラムに取り組んでいる先輩方の話を聞いていても、技術的な問題よりもスクラムとして成立しているかどうかがPJの成否を分けると耳にするので、スクラムやアジャイルの価値観を大事にしてチームとして動いていこうと思います。 使いやすいものの裏にはデザインの営みがある Googleの公開している、「Material Design」をご存知でしょうか?これはGoogleが提唱しているデザインのガイドラインのことで、「見やすく、直感的に操作できるWebページ・サービス」を作ることを目的としています。ユーザビリティの高いアプリやサイトは、このMaterial Design、ないしはAppleの公開している「Human Interface Guidelines」に準拠して作られています。 世の中の使いやすいWebサイトはこれらのガイドラインに沿って作られているという事を知り、自分が画面のデザインをする際にはMaterial Designを辞書の如く参照するようになりました。使いやすさの裏にはこのような共通した法則というか、ガイドラインがあるのですね。 皆が惹かれるモノの裏にもデザインの営みがある これはDesignShipでマツダのデザイナー、前田 育男さんがお話されていた事になります。前田さんは車のデザインをアートに昇華すべく、美しいクルマづくりに挑戦されています。マツダの車といえば高いデザイン性が特徴として挙げられますが、その裏にはこんな取り組みがありました。 マツダでは車を、ヒトと心を通わせ一体となれるような生き物のようにしたいと考えていました。そこで、「クルマに命を吹き込む」ために野生動物の躍動感ある写真のスケッチを行い、それを抽象化した立体である「御神体」を1年がかりで作成。そしてそれを作成してからそれをクルマのフォルムに落とし込む段階では、全てをCADのようなデジタルツールで行うのではなく、必ずクレイ(粘土)モデルを作り、感触を確かめながら手で削って形を作っていくそう。こうした取り組みから生まれた車体には独特のフォルムに絶妙な陰影が付いており、その美しさは世界的に高い評価を受けるようになりました。 1台のクルマが生まれるまでにここまで徹底したデザインのプロセスがあることに感服し、世の中のモノを見る視点が変わりました。美しいと感じるもの、何故か心惹かれるものの裏にはデザインという仕掛けがある。自分もデザインというプロセスを通じて、そういうものを作っていきたいですね。 デザインと実装の二刀流がシナジーを生む えっ、デザイナーってプログラミングするの...?と思われた方もいらっしゃるかと思います(自分もそうでした)。スクラムチームでは、スクラムマスター/プロダクトオーナー/開発者という3つの役割があるのですが、「開発者」にはエンジニアもデザイナーも関係なくひとくくりにして含まれています。機能横断的なチームがあるべき姿なので、自分はデザインしかやらない!基盤しかやらない!なんてことはありません。なので自分も実装をするようになりました。 ちなみにスクラムに限らず、今後はデザイナーとエンジニアの境目がどんどん曖昧になると言われています(下記の記事を参照)。 とはいえ自分はデザインも初心者だったのでまずはデザインを学ぼう、ということで9月まではAdobe XDを用いて画面を描いていましたが、実装はほとんどしていませんでした。先輩から「実装をした方がUIも描けるようになる」と言われていましたが、その意味をこの時点では理解出来ず。しかし10、11月と実装をしてみて、デザインと実装の両方を経験する以下のメリットに気づきました。 挙動をイメージできるようになる 当たり前ですが、デザインツールを用いて画面を描く際は画面は動きません(画面遷移などをプレビューできるプロトタイプ機能ぐらいはありますが)。しかし実際に作るものは「動くソフトウェア」なので、画面の各要素の挙動を想定してデザインをする必要があります。実装を経験したことで、必須項目が入力されていない時のエラーメッセージはどのように表示されるか、画面幅を縮めた際にはレイアウトがどう変わるか、文章が長い場合は「...」で表示するか、などを想定してデザインするようになりました。 divが見える これは実装をしてみてのアハ体験でした。実装の際には各セクションをdiv(ないしは他のHTMLタグ)で区切って要素を配置しますが、それを一度経験すると画面上のdivの区切りが見えてくるようになります。例えば左下の図を見ただけでも、脳内には右下のようにdivがうっすらと浮かびます。 divを意識するようになったことで、デザインをする際に親要素のdiv幅内に子要素を配置するなど実装上無理のないUIをデザインできるようになりました。「実装をした方がUIも描けるようになる」とは、まさにこの事ですね! ユーザ目線でのレビューができる 前述のMaterial Designを一読した上で自分で一度デザインをすると、要素同士の間隔は4or8の倍数になっているか、ユーザが入力する箇所のフォントサイズは16pxで指定されているか、などCSSの指定をかなり細かくチェックするようになりました。実装だけをしていると実際に書かれたコードを見て、コードの可読性や処理の書き方に注目するあまりユーザ目線が抜けがちですが、ユーザにとって価値があるのは「動くソフトウェア」なのでこの視点は忘れないようにしたいです。 複雑性を担う覚悟が生まれる UXデザインをする上で意識すべき1つの法則として、「テスラーの法則」というものがあります。これは、「どんなシステムであってもそれ以上シンプルにすることのできない固有の複雑さがあり、その複雑さはユーザか開発側のどちらかが担わなければならない」というものです。 例えばメールアプリでは、差出人と宛先の2つの情報が必要になり、これらはいずれも必要不可欠な複雑性になります。この複雑性をユーザに担わせないために、最近のメールアプリでは差出人(自分)を予め入力しておくこと、また過去のメールや連絡帳から宛先を予想し候補を表示してくれます。つまり、差出人と宛先の入力という複雑性を、ユーザに代わって引き受けるようなメールアプリをデザイン・実装することで、メールを書くことを楽にしてくれているのです。 このようなことを開発側として実際にやろうとなると、なかなか面倒に感じました。ユーザにとってあったら嬉しいけど必須じゃないし、の割に実装やデザインがややこしかったりするし...イチ開発者としては、できればやりたくない!と思うこともありました。デザイナーもエンジニアも、自分たちで複雑性を担うのってかなりの覚悟が必要なのだなと。 なのでGoogleやAppleの提供するようなシンプルでUI/UXの優れたサービスは、エンジニアとデザイナーがユーザの代わりに複雑性を担ってくれている賜物で、サービス提供側の本気度の表れなんだと尊敬の念を抱くようになりました。と同時に、デザイナーがエンジニアに対して何でこのデザインにするのか、そのこだわりについて語れなければUI/UXの優れたサービスは実現できない、と感じました。開発者に納得してもらえるよう、誰よりもユーザを中心に考えこだわっていきたいです。 予防線を張らない これはDesignshipで、HI(NY) design というデザイン会社の渡邊デルーカ 瞳さんがお話されていた内容になります。 渡邉さんは過去にNYのSVAという美大に留学した際に、アメリカの学生よりも日本の学生の方がアウトプットの質は高いが、ストーリーテリングが上手いのはアメリカの方だと感じたそうです。正直作品のクオリティは高くないのに、自信満々に自分の作品をプレゼンする。そんなアメリカの学生を見て、「予防線を張るような発言をしてしまうと作品の良さが半減する。批判されるのは当たり前と思って、その作品の良さを最大限伝えよう!」と考えるようになった、とお話されていました。 自分も「あんまり自信がないですが」「ちょっと初めてだったので」のように、成果物を見せる際に予防線を張ってしまう事は多々ありました。謙遜の意味合いの場合もありますが、自信があるからこそ批判されて傷つきたくないがために予防線を張ってしまう事がほとんどだったので、このお話を聞いてハッとしました。作品の価値を落とさないために、予防線は極力貼らないように気を付けています。 4. おわりに 4ヶ月で多くの学びを得ましたが、スキル的にはまだまだ見習いの域を出ません。本職のデザインの力を伸ばすにもまずは実装の基礎体力をつけるべく、年内はReactの勉強に注力します(今は下記の本で勉強中)。 モダンJavaScriptの基本から始める React実践の教科書 そんなにロジカルな人間ではないので実装に向いてるとは思いませんが、新しい知識を習得したときや、あれこれ試行錯誤して動くソフトウェアができた時の喜びを大切にしていきたいです。年明けごろにはデザインの勉強にシフトして、Google UX Design Certificateの習得を始めたいですね。 最後になりますが、まさか自分がこんな分野の事を勉強しているとは学生の頃には想像がつきませんでした(DesignshipもReactも、名前すら聞いたことがありませんでした)。 自分の好きなUXデザイナーの安藤 剛さんが、以前Youtubeで「技術的なキャッチアップは組織に所属していなくても可能だが、文化的なキャッチアップは組織に所属していないと難しい」とお話されていましたが、まさしくそれを実感しています(動画は下記リンク)。 今の時代はネットや本から技術は学べるものの、アジャイルやデザインの文化・トレンドを学べるのは組織に所属している人の特権ですよね。自分は組織に所属しているメリットを最大限に活かし、技術と文化をこれからもアップデートしていきたいと思います! ここまで読んで頂き、ありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む