電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報4/5いってみようか。 NFTが身近に デジタルでも“本物保証” LINE参入でNFTが身近に?【WBS】 「LINE Blockchainの展望と未来の経済圏」LVCインタビュー LINE、4月にNFT電子取引市場開始-ペイペイ決済検討 「LINE NFT」 はソフトバンク経済圏の確立か CEOに聞く、真の狙い 【取材】加藤ミリヤや松井秀喜がNFT活用へ、ナッジがクレカ特典の実証実施 インスタグラム、NFTのメインストリーム化を加速:ドイツ銀行 その他のニュース OpenSea、ソラナNFTの取り扱い開始へ 業績絶好調の暗号通貨取引所が社員に高額ボーナスを支給 ゲームをやるだけでお金が稼げる!?」ビジネス系YouTuberが教えるWeb3.0時代の副業のヒント NFTが身近に LINEがNFTに参入することで、NFTがより身近になることが期待されています。LINEのIDを持っていて、LINE BITMAXに口座を開けば、使えるようになるので、これまでより身近になったのは間違いないと思います。 デジタルでも“本物保証” LINE参入でNFTが身近に?【WBS】 「LINE Blockchainの展望と未来の経済圏」LVCインタビュー LINE、4月にNFT電子取引市場開始-ペイペイ決済検討 「LINE NFT」 はソフトバンク経済圏の確立か CEOに聞く、真の狙い 有名人がNFTを発行する例も増えてきました。 【取材】加藤ミリヤや松井秀喜がNFT活用へ、ナッジがクレカ特典の実証実施 Instagram がNFTをサポートすることで、NFTのメインストリーム化が進むことも期待されています。 インスタグラム、NFTのメインストリーム化を加速:ドイツ銀行 その他のニュース OpenSea、ソラナNFTの取り扱い開始へ 業績絶好調の暗号通貨取引所が社員に高額ボーナスを支給 ゲームをやるだけでお金が稼げる!?」ビジネス系YouTuberが教えるWeb3.0時代の副業のヒント 自民党、Web3時代のNFT戦略でホワイトペーパー案を公表──ルール整備と規制緩和急ぐ 執筆: @higa ( Shodo で執筆されました )
みなさんこんにちは、ISIDテックブログ編集部の 電通国際情報サービス (ISID) 金融ソリューション事業部の石沢です。ISIDは2021年11月にISIDテックブログを開始し、現時点で50記事を公開しました! これまでISIDテックブログは社内的に「トライアル」の位置付けでしたが、今月から正式運用へ移行することにもなりました。本記事では、ISIDテックブログをはじめようと思った理由、ねらい、やってみてわかったことについて、ふりかえってみたいと思います。 ISIDがテックブログをはじめた理由 現在、さまざまな企業がそれぞれの目的でテックブログを運用しています。 マーケティング や人事施策などの トップダウン なアプローチでテックブログを運用している企業も多いと思います。それとは逆に、エンジニア社員の「やってみたい」という気持ちを中心として ボトムアップ に開始する場合もあるでしょう。ISIDテックブログは、まさにエンジニア社員の「やってみたい」から生まれています。より正確に言うと「やってみた」というところです。 ISIDは、 ボトムアップ の改善活動が実は活発です。部門を横断したさまざまな組織改善のプログラムが常時実行されています。専門の本部部署が何かを検討するというよりは、顧客もビジネス形態も異なる部門のメンバーが集結して、社の課題について議論を行い、解決策を組織マネジメントに提言し、実行することが許されるような文化です。 ぶっちゃけ「やってみたい」と言えば「やってみれば」と言われる雰囲気があります(本記事では深く取扱いませんが、自社の行動指針も AHEAD というワードを採用しています)。 2020年に発足した、ISIDグループの長期成長を支える事業基盤の構築を目指し、新たな業務プロセスや働き方を検討する社内プロジェクトの一つである「ワークトランスフォーメーションプロジェクト」というものがあります。ここから派生した技術分科会の2021年度活動から出てきたア イデア の一つが「テックブログの開設」でした。 そもそも社内でもいろいろな事にチャレンジしているエンジニアがたくさんいるけど、情報がうまく共有できていない 社会から見るとISIDのエンジニア像がまったく見えていない(見せていない) そもそもISIDにエンジニアがいると思われていないかも(広告会社のシステム部という誤解もありそう) ISIDのエンジニア像を知ってもらい、共感した人にジョインしてもらいたい ブログを書くのはエンジニアとしての成長機会でもあるよね 実際、個人ブログをやっている人もいるけど、続けるのは大変 もし会社で書けるハコがあれば、書く事はいっぱいある もう、社としてのテックブログをやってみればいいのでは…… いまから準備始めれば、今年(2021年)の アドベントカレンダー に参戦できるんじゃないの? 夏ごろに上記のような話をして、もうあとは勢いでテックブログの開設へ! ISIDテックブログのトライアルをはじめるにあたって テックブログを実現する技術スタックの選定については、本テックブログの以下記事で紹介しているので本記事では省略します。テックブログの運用はトライアルであっても業務として扱うため、運用コストを抑えることが重要なテーマでした。そこで文章校正もできる執筆管理 SaaS のShodoの採用は重要でした。 テックブログ始めました。 ISIDテックブログは社としての情報発信に当たることから広報部門との調整、組織が有している ソーシャルメディア 利用に関する ガイドライン 、レビュープロセスを簡単に固めていきました。トライアルということもあり、問題が発生したら見直せば良いので骨子程度の簡単なもので済ませています。 だいたいの方向性が出たところで、ツール類の諸費用およびブログ執筆者とレビュアーの人件費をざっくり見積ってコストを取りまとめて、Makrdownで1ページくらいの企画書を書いてマネジメントと関係者に説明・承諾を得てスタートです。社内で執筆者を公募したところ、あまり苦労せず多様な執筆者を集めることができました(ちょっと心配だったのですが杞憂でした)。 結果として、2021年の アドベントカレンダー では一日も欠かすことなく25記事を投稿することができました。記事の一覧は以下のとおりです。 電通国際情報サービス Advent Calendar 2021 - Adventar トライアルでわかったこと 狙っていなかったのでよいのですが、テックブログは炎上もバズりもせずに、たんたんと続いています。一方で、いろいろとやってみてわかったことがあります。そのいくつかをご紹介します。 ISIDテックブログを始めたことがおどろかれた ある程度予想していたことではありますが、 SNS などの反応を見ているとISIDがテックブログ始めたこと自体にいくつか反応をいただいていました。そもそもISIDが何をやっている企業かわかりにくいこともあると思います。多様なエンジニアが在席していることが示せたのは良かったと思います。 社内コミュニケーション活性化の効果もあった 社内の情報共有の仕組みは各種とりそろえてあるのですが、それでもなお、社内コミュニケーション活性化の効果があったと思います。ISIDテックブログは個人の視点で等身大の技術情報を発信することが特徴です。社内の情報共有というと「プロジェクトや仕事」「お客様」「活躍した人」を中心とすることが多く、割と(いろいろな意味で)デカい話ばかりになりがちです。テックブログに蓄積されるような、小さな情報も大事なんだと改めて気づかされたような気がします。 また「普段仕事で関わらない人の活動や考え方」「他部門、他部署の技術的なこと」がわかることも大きなメリットだと思います。他部門の同世代・同期の書いた記事に刺激を受けている人もいるとか・・・ 個人の成長機会になることもわかった アウトプットを通じて学びが深まり、自己成長するという話はよく聞きます。テックブログに記事を書く事が自己研鑽の機会づくりとして有効だったという声は社内からも上がりました。内容を整理し文書化するという活動が有意義なことに加えて、内容によってはシニアエンジニアや広報部門のレビューも入ります。普段の研究開発やクライアントワーク、プロジェクト活動では経験しにくい活動が良い刺激となっているようです。 そして正式運用へ 現時点で、ISIDテックブログを始めたことにはメリットしかなく、デメリットはほとんどないことがわかりました。そこで(別になにも変わらないのですが)改めて、ISIDテックブログはトライアルから「正式運用」へ移行することになりました。 テック ブログ界 には以下のような記事があり、当然参考とさせていただいています。 テックブログは続かない - 何サイトか潰した後にブログが有名な企業に転職しての気づきと反省|久松剛/IT百物語の蒐集家|note ISIDテックブログは当面以下の方針で継続する予定です。 編集長は配置しない(有志による編集部で運用) 数値目標などは設定しない(目安として週1程度の更新頻度は維持したいけど、ゆるく考える) 匿名化はしない。レビューはやる。記事の執筆は業務。 死なないといいな・・・(上記ブログ記事に書かれている「テックブログが死ぬ条件」を意識しています) テックブログのねらい、これから 改めて、ISIDテックブログのねらいを私たちはこのように定義しています。 等身大のISID社員の姿をオープンに伝えていく ISID社員が技術的な取組みを公開していく 自らのアウトプットをする機会を通じて自分たち自身の能力を高める 実はISIDテックブログを企画推進していくにあたってよくあった意見の一つに「もっとトガった人が書くべきではないか・先進的な内容で技術をアピールしたほうが良いのでは」というものがありました。世の中にはそういった方針のアピールメディアとしてのブログもたくさんあることは理解していますが、議論の結果、われわれがやりたいことは違う、と結論づけています。わたしたちは、等身大の自分たちを共有していく方向で、これからもISIDテックブログを継続していこうと考えています。 最後までお読みいただきありがとうございます。ISIDテックブログを引続きよろしくお願いします。 執筆: Ishizawa Kento (@kent) 、レビュー: @higa ( Shodo で執筆されました )
みなさんこんにちは、ISIDテックブログ編集部の 電通国際情報サービス (ISID) 金融ソリューション事業部の石沢です。ISIDは2021年11月にISIDテックブログを開始し、現時点で50記事を公開しました! これまでISIDテックブログは社内的に「トライアル」の位置付けでしたが、今月から正式運用へ移行することにもなりました。本記事では、ISIDテックブログをはじめようと思った理由、ねらい、やってみてわかったことについて、ふりかえってみたいと思います。 ISIDがテックブログをはじめた理由 現在、さまざまな企業がそれぞれの目的でテックブログを運用しています。 マーケティング や人事施策などの トップダウン なアプローチでテックブログを運用している企業も多いと思います。それとは逆に、エンジニア社員の「やってみたい」という気持ちを中心として ボトムアップ に開始する場合もあるでしょう。ISIDテックブログは、まさにエンジニア社員の「やってみたい」から生まれています。より正確に言うと「やってみた」というところです。 ISIDは、 ボトムアップ の改善活動が実は活発です。部門を横断したさまざまな組織改善のプログラムが常時実行されています。専門の本部部署が何かを検討するというよりは、顧客もビジネス形態も異なる部門のメンバーが集結して、社の課題について議論を行い、解決策を組織マネジメントに提言し、実行することが許されるような文化です。 ぶっちゃけ「やってみたい」と言えば「やってみれば」と言われる雰囲気があります(本記事では深く取扱いませんが、自社の行動指針も AHEAD というワードを採用しています)。 2020年に発足した、ISIDグループの長期成長を支える事業基盤の構築を目指し、新たな業務プロセスや働き方を検討する社内プロジェクトの一つである「ワークトランスフォーメーションプロジェクト」というものがあります。ここから派生した技術分科会の2021年度活動から出てきたア イデア の一つが「テックブログの開設」でした。 そもそも社内でもいろいろな事にチャレンジしているエンジニアがたくさんいるけど、情報がうまく共有できていない 社会から見るとISIDのエンジニア像がまったく見えていない(見せていない) そもそもISIDにエンジニアがいると思われていないかも(広告会社のシステム部という誤解もありそう) ISIDのエンジニア像を知ってもらい、共感した人にジョインしてもらいたい ブログを書くのはエンジニアとしての成長機会でもあるよね 実際、個人ブログをやっている人もいるけど、続けるのは大変 もし会社で書けるハコがあれば、書く事はいっぱいある もう、社としてのテックブログをやってみればいいのでは…… いまから準備始めれば、今年(2021年)の アドベントカレンダー に参戦できるんじゃないの? 夏ごろに上記のような話をして、もうあとは勢いでテックブログの開設へ! ISIDテックブログのトライアルをはじめるにあたって テックブログを実現する技術スタックの選定については、本テックブログの以下記事で紹介しているので本記事では省略します。テックブログの運用はトライアルであっても業務として扱うため、運用コストを抑えることが重要なテーマでした。そこで文章校正もできる執筆管理 SaaS のShodoの採用は重要でした。 テックブログ始めました。 ISIDテックブログは社としての情報発信に当たることから広報部門との調整、組織が有している ソーシャルメディア 利用に関する ガイドライン 、レビュープロセスを簡単に固めていきました。トライアルということもあり、問題が発生したら見直せば良いので骨子程度の簡単なもので済ませています。 だいたいの方向性が出たところで、ツール類の諸費用およびブログ執筆者とレビュアーの人件費をざっくり見積ってコストを取りまとめて、Makrdownで1ページくらいの企画書を書いてマネジメントと関係者に説明・承諾を得てスタートです。社内で執筆者を公募したところ、あまり苦労せず多様な執筆者を集めることができました(ちょっと心配だったのですが杞憂でした)。 結果として、2021年の アドベントカレンダー では一日も欠かすことなく25記事を投稿することができました。記事の一覧は以下のとおりです。 電通国際情報サービス Advent Calendar 2021 - Adventar トライアルでわかったこと 狙っていなかったのでよいのですが、テックブログは炎上もバズりもせずに、たんたんと続いています。一方で、いろいろとやってみてわかったことがあります。そのいくつかをご紹介します。 ISIDテックブログを始めたことがおどろかれた ある程度予想していたことではありますが、 SNS などの反応を見ているとISIDがテックブログ始めたこと自体にいくつか反応をいただいていました。そもそもISIDが何をやっている企業かわかりにくいこともあると思います。多様なエンジニアが在席していることが示せたのは良かったと思います。 社内コミュニケーション活性化の効果もあった 社内の情報共有の仕組みは各種とりそろえてあるのですが、それでもなお、社内コミュニケーション活性化の効果があったと思います。ISIDテックブログは個人の視点で等身大の技術情報を発信することが特徴です。社内の情報共有というと「プロジェクトや仕事」「お客様」「活躍した人」を中心とすることが多く、割と(いろいろな意味で)デカい話ばかりになりがちです。テックブログに蓄積されるような、小さな情報も大事なんだと改めて気づかされたような気がします。 また「普段仕事で関わらない人の活動や考え方」「他部門、他部署の技術的なこと」がわかることも大きなメリットだと思います。他部門の同世代・同期の書いた記事に刺激を受けている人もいるとか・・・ 個人の成長機会になることもわかった アウトプットを通じて学びが深まり、自己成長するという話はよく聞きます。テックブログに記事を書く事が自己研鑽の機会づくりとして有効だったという声は社内からも上がりました。内容を整理し文書化するという活動が有意義なことに加えて、内容によってはシニアエンジニアや広報部門のレビューも入ります。普段の研究開発やクライアントワーク、プロジェクト活動では経験しにくい活動が良い刺激となっているようです。 そして正式運用へ 現時点で、ISIDテックブログを始めたことにはメリットしかなく、デメリットはほとんどないことがわかりました。そこで(別になにも変わらないのですが)改めて、ISIDテックブログはトライアルから「正式運用」へ移行することになりました。 テック ブログ界 には以下のような記事があり、当然参考とさせていただいています。 テックブログは続かない - 何サイトか潰した後にブログが有名な企業に転職しての気づきと反省|久松剛/IT百物語の蒐集家|note ISIDテックブログは当面以下の方針で継続する予定です。 編集長は配置しない(有志による編集部で運用) 数値目標などは設定しない(目安として週1程度の更新頻度は維持したいけど、ゆるく考える) 匿名化はしない。レビューはやる。記事の執筆は業務。 死なないといいな・・・(上記ブログ記事に書かれている「テックブログが死ぬ条件」を意識しています) テックブログのねらい、これから 改めて、ISIDテックブログのねらいを私たちはこのように定義しています。 等身大のISID社員の姿をオープンに伝えていく ISID社員が技術的な取組みを公開していく 自らのアウトプットをする機会を通じて自分たち自身の能力を高める 実はISIDテックブログを企画推進していくにあたってよくあった意見の一つに「もっとトガった人が書くべきではないか・先進的な内容で技術をアピールしたほうが良いのでは」というものがありました。世の中にはそういった方針のアピールメディアとしてのブログもたくさんあることは理解していますが、議論の結果、われわれがやりたいことは違う、と結論づけています。わたしたちは、等身大の自分たちを共有していく方向で、これからもISIDテックブログを継続していこうと考えています。 最後までお読みいただきありがとうございます。ISIDテックブログを引続きよろしくお願いします。 執筆: Ishizawa Kento (@kent) 、レビュー: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。今回取り上げるのはTailwind CSS 。 Tailwind CSS は、最近人気急上昇の CSS フレームワーク です。 メジャーなBootstrapなどの フレームワーク は、あらかじめ見栄えの良い コンポーネント が用意されていて、それをカスタマイズします。それに対し、Tailwind CSS は、 CSS の便利なclassが大量に用意されているだけです。それではなぜTailwind CSS の人気が上昇しているのでしょうか。 一番の原因はBootstrapなどの コンポーネント を使うと、見た目が同じ様になってしまうのでサイトの個性が出せなくなることです。 サイトの個性を出すために、出来合いの コンポーネント は使わず自前でデザインを組み立てていくとコストが掛かります。そのコストをできるだけ下げるために、Tailwind CSS では便利なクラスがたくさん用意されています。 最近は、 Adobe XDを使ってプロトタイプを作ることも多くなってきていると思います。XDで作ったものをHTMLに落とし込むときに、出来合いの コンポーネント があってもあまり役に立ちません。自前でかつローコストでデザインするのにTailwind CSS は向いているのです。 Clubhouse や Netflix Top 10 もTailwind CSS を使っているそうです。 前準備 first.html rectangles.html responsive_design.html まとめ 前準備 今回使うHTMLを前もって用意しておいたので、ダウンロードしてください。 tailwindcss_samples.zip あなたが、 VS Code を使っているなら、とても便利なTailwind CSS の機能拡張が用意されているのでインストールしましょう。 メニューの機能拡張(Extensions)を開いて、tainwindで検索してください。Tailwind CSS IntelliSenseという機能拡張があるので、それをインストールしてください。 次のようにclassの補完ができます。 Tailwind CSS にはたくさんのclassが用意されているので、それを全部覚えるのは大変です。しかし、ある程度なれてくるとテキストに関するclassはtextで始まるということが自然に覚えられるので、textと入力し補完すればclassがどんなにたくさんあろうと対応できます。 Tailwind CSS を使うための方法はいくつかありますが、 CDN を使うのが最も簡単です。この記事では CDN を使います。headタグの子要素に次のlinkタグを追加してください。 < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> first.html それでは、first.htmlを Chrome で開きましょう。 Mac を使っている場合は、first.htmlを右クリック -> このアプリケーションで開く -> Google Chrome .appを選んでください。 Windows を使っている場合は、first.htmlを右クリック -> 情報を見る -> このアプリケーションで開くで、 Chrome を選んでください。 <!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.0" /> < title > Document </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body > < span class = "text-red-500" > あああ </ span > </ body > </ html > text-red-500をtext-blue-500に変えてHTMLを保存し、ブラウザをリロードしましょう。文字の色が青くなったはずです。 text-blue-500の500は何を表しているのでしょうか。これは文字の色の濃さです。500を消して補完させると次のような選択肢があることがわかります。 数字が大きくなるほど色も濃くなります。それでは、text-blue-100に変更してHTMLを保存し、ブラウザをリロードしましょう。文字の色が薄くなりましたね。 rectangles.html それでは、いろいろなclassを試してみましょう。rectangles.htmlを Chrome で開きましょう。 <!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.0" /> < title > Rectabgles </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4" > < div > w-4 = 1 rem = 16px </ div > < div class = "text-white bg-blue-500 w-4" > あああ </ div > < div class = "mt-4" > w-12 </ div > < div class = "text-white bg-blue-500 w-12" > あああ </ div > < div class = "mt-4" > w-20 </ div > < div class = "text-white bg-blue-500 w-20" > あああ </ div > < div class = "mt-4" > w-20 text-center </ div > < div class = "text-white bg-blue-500 w-20 text-center" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 rounded-xl </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 bg-opacity-80 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 font-bold </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 border-8 border-red-500 </ div > < div class = "w-20 text-center py-2 border-8 border-red-500" > あああ </ div > </ body > </ html > 左側が16px空いています。 これは、bodyタグのclassに指定したpl-4の効果です。pl-4とは、padding left 16pxのことです。1が4pxになります。 < body class = "pl-4" > 上のタグと距離を開けるには、mt-xxを使います。mtはmargin topの略です。 < div class = "mt-4" > w-12 </ div > 背景色を指定するには、bg-色-濃さで指定します。濃さは500が真ん中の値で、濃くなると数値も大きくなります。900が最も大きい値です。 幅を指定するには、w-数値で指定します。数値は先程と同様1が4pxになります。Tailwind CSS では、数値の4が16px = 1 rem = 1文字分の幅になります。 < div class = "text-white bg-blue-500 w-4" > あああ </ div > ちょうど、1文字の幅で改行されていますね。 次は、w-12 = 3 remにしてみましょう。 < div class = "text-white bg-blue-500 w-12" > あああ </ div > ちょうど文字幅と同じになっています。 w-20にするとどうなるでしょうか。 < div class = "text-white bg-blue-500 w-20" > あああ </ div > 左寄せになりました。 中央寄せにしてみましょう。text-centerを使います。 < div class = "text-white bg-blue-500 w-20 text-center" > あああ </ div > 文字の上下にスペースを入れてみましょう。py(padding y方向)を使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2" > あああ </ div > 角丸にしてみましょう。roundedを使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > あああ </ div > roundedでどのような値が使えるかは、roundedと入力し、補完で確かめましょう。 背景の不透明度を設定しましょう。bg-opacity-xxを使います。xxは0から100までの数字が入ります。数字が大きいほど不透明度は高く、100の場合は透明度なし(何も指定しないのと一緒)です。xxで、どの値が使えるかは補完で確かめましょう。 < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > あああ </ div > フォントを太くしてみましょう。font-boldを使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > あああ </ div > 枠線を設定しましょう。border-太さとborder-色-濃さで指定します。 < div class = "w-20 text-center py-2 border-8 border-red-500" > あああ </ div > それでは、幅(width)を4の倍数以外の23pxにしたい場合はどうするのでしょうか。w-[23px]のように[]の中にサイズを指定します。ただし、 CDN 版ではできません。npmでtailwindcssをインストールする必要があります。詳しくは下記をご覧ください。 Installation: Tailwind CLI using-arbitrary-values responsive_design.html Tailwind CSS を使うと簡単にレスポンシブデザインにできます。responsive_design.htmlを Chrome で開いてください。 <!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.0" /> < title > Responsive Design </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4 pt-4" > < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > </ body > </ html > Chrome のWindowの幅をできるだけ小さくしてください。次のような青い四角が表示されましたね。 少しづつWindowの幅を大きくしてください。768px以上で四角の幅が16px増えましたね。同様に、1024px、1280px以上で四角の幅が増えたはずです。 タグの定義を見てみましょう。 < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > w-xxの プレフィックス としてmd:, lg:, xl:が指定されています。これを解釈すると次のようになります。 768px未満は、w-16。 md: 768px以上1024px未満は、w-32。 lg: 1024px以上1280px未満は、w-48。 xl: 1280px以上は、w-60。 レスポンシブデザインでよくあるのが スマホ ではスペースがないので縦に表示し、 タブレット 以上のスペースがある場合は、横に表示するやり方です。 まず、 スマホ で縦に表示するには、普通にdivを使います。 < div > < div > コンテンツ1 </ div > < div > コンテンツ2 </ div > </ div > 幅が768px以上のときに、横に表示するには、md: flex を使います。 < div class = "md:flex" > < div > コンテンツ1 </ div > < div > コンテンツ2 </ div > </ div > つまり、md: flex を使えば、 スマホ では縦に表示し、幅768px以上なら横に表示するということが簡単にできます。 < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > 幅が768px未満。 幅が768px以上 mt-1 md:mt-0 md:ml-1を説明しておきましょう。幅が768px未満のときは、縦に並ぶので、mt-1(margin top 4px)で上の要素と4pxあけます。 幅が768px以上のときは、横に並ぶので、md:mt-0(margin top 0px)で上の要素とのスペースを0pxにし、md:ml-1で左の要素とのスペースを4pxあけます。 まとめ Tailwind CSS いかがだったでしょうか。HTMLをみれば、class属性に必要な情報があるため、どういうデザインになるのか予想できます。これによりかなり見通しが良くなります。 ストレスフリーな CSS ライフをお過ごしください。 執筆: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。今回取り上げるのはTailwind CSS 。 Tailwind CSS は、最近人気急上昇の CSS フレームワーク です。 メジャーなBootstrapなどの フレームワーク は、あらかじめ見栄えの良い コンポーネント が用意されていて、それをカスタマイズします。それに対し、Tailwind CSS は、 CSS の便利なclassが大量に用意されているだけです。それではなぜTailwind CSS の人気が上昇しているのでしょうか。 一番の原因はBootstrapなどの コンポーネント を使うと、見た目が同じ様になってしまうのでサイトの個性が出せなくなることです。 サイトの個性を出すために、出来合いの コンポーネント は使わず自前でデザインを組み立てていくとコストが掛かります。そのコストをできるだけ下げるために、Tailwind CSS では便利なクラスがたくさん用意されています。 最近は、 Adobe XDを使ってプロトタイプを作ることも多くなってきていると思います。XDで作ったものをHTMLに落とし込むときに、出来合いの コンポーネント があってもあまり役に立ちません。自前でかつローコストでデザインするのにTailwind CSS は向いているのです。 Clubhouse や Netflix Top 10 もTailwind CSS を使っているそうです。 前準備 first.html rectangles.html responsive_design.html まとめ 前準備 今回使うHTMLを前もって用意しておいたので、ダウンロードしてください。 tailwindcss_samples.zip あなたが、 VS Code を使っているなら、とても便利なTailwind CSS の機能拡張が用意されているのでインストールしましょう。 メニューの機能拡張(Extensions)を開いて、tainwindで検索してください。Tailwind CSS IntelliSenseという機能拡張があるので、それをインストールしてください。 次のようにclassの補完ができます。 Tailwind CSS にはたくさんのclassが用意されているので、それを全部覚えるのは大変です。しかし、ある程度なれてくるとテキストに関するclassはtextで始まるということが自然に覚えられるので、textと入力し補完すればclassがどんなにたくさんあろうと対応できます。 Tailwind CSS を使うための方法はいくつかありますが、 CDN を使うのが最も簡単です。この記事では CDN を使います。headタグの子要素に次のlinkタグを追加してください。 < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> first.html それでは、first.htmlを Chrome で開きましょう。 Mac を使っている場合は、first.htmlを右クリック -> このアプリケーションで開く -> Google Chrome .appを選んでください。 Windows を使っている場合は、first.htmlを右クリック -> 情報を見る -> このアプリケーションで開くで、 Chrome を選んでください。 <!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.0" /> < title > Document </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body > < span class = "text-red-500" > あああ </ span > </ body > </ html > text-red-500をtext-blue-500に変えてHTMLを保存し、ブラウザをリロードしましょう。文字の色が青くなったはずです。 text-blue-500の500は何を表しているのでしょうか。これは文字の色の濃さです。500を消して補完させると次のような選択肢があることがわかります。 数字が大きくなるほど色も濃くなります。それでは、text-blue-100に変更してHTMLを保存し、ブラウザをリロードしましょう。文字の色が薄くなりましたね。 rectangles.html それでは、いろいろなclassを試してみましょう。rectangles.htmlを Chrome で開きましょう。 <!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.0" /> < title > Rectabgles </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4" > < div > w-4 = 1 rem = 16px </ div > < div class = "text-white bg-blue-500 w-4" > あああ </ div > < div class = "mt-4" > w-12 </ div > < div class = "text-white bg-blue-500 w-12" > あああ </ div > < div class = "mt-4" > w-20 </ div > < div class = "text-white bg-blue-500 w-20" > あああ </ div > < div class = "mt-4" > w-20 text-center </ div > < div class = "text-white bg-blue-500 w-20 text-center" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 rounded-xl </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 bg-opacity-80 </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 font-bold </ div > < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > あああ </ div > < div class = "mt-4" > w-20 text-center py-2 border-8 border-red-500 </ div > < div class = "w-20 text-center py-2 border-8 border-red-500" > あああ </ div > </ body > </ html > 左側が16px空いています。 これは、bodyタグのclassに指定したpl-4の効果です。pl-4とは、padding left 16pxのことです。1が4pxになります。 < body class = "pl-4" > 上のタグと距離を開けるには、mt-xxを使います。mtはmargin topの略です。 < div class = "mt-4" > w-12 </ div > 背景色を指定するには、bg-色-濃さで指定します。濃さは500が真ん中の値で、濃くなると数値も大きくなります。900が最も大きい値です。 幅を指定するには、w-数値で指定します。数値は先程と同様1が4pxになります。Tailwind CSS では、数値の4が16px = 1 rem = 1文字分の幅になります。 < div class = "text-white bg-blue-500 w-4" > あああ </ div > ちょうど、1文字の幅で改行されていますね。 次は、w-12 = 3 remにしてみましょう。 < div class = "text-white bg-blue-500 w-12" > あああ </ div > ちょうど文字幅と同じになっています。 w-20にするとどうなるでしょうか。 < div class = "text-white bg-blue-500 w-20" > あああ </ div > 左寄せになりました。 中央寄せにしてみましょう。text-centerを使います。 < div class = "text-white bg-blue-500 w-20 text-center" > あああ </ div > 文字の上下にスペースを入れてみましょう。py(padding y方向)を使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2" > あああ </ div > 角丸にしてみましょう。roundedを使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2 rounded-xl" > あああ </ div > roundedでどのような値が使えるかは、roundedと入力し、補完で確かめましょう。 背景の不透明度を設定しましょう。bg-opacity-xxを使います。xxは0から100までの数字が入ります。数字が大きいほど不透明度は高く、100の場合は透明度なし(何も指定しないのと一緒)です。xxで、どの値が使えるかは補完で確かめましょう。 < div class = "text-white bg-blue-500 w-20 text-center py-2 bg-opacity-80" > あああ </ div > フォントを太くしてみましょう。font-boldを使います。 < div class = "text-white bg-blue-500 w-20 text-center py-2 font-bold" > あああ </ div > 枠線を設定しましょう。border-太さとborder-色-濃さで指定します。 < div class = "w-20 text-center py-2 border-8 border-red-500" > あああ </ div > それでは、幅(width)を4の倍数以外の23pxにしたい場合はどうするのでしょうか。w-[23px]のように[]の中にサイズを指定します。ただし、 CDN 版ではできません。npmでtailwindcssをインストールする必要があります。詳しくは下記をご覧ください。 Installation: Tailwind CLI using-arbitrary-values responsive_design.html Tailwind CSS を使うと簡単にレスポンシブデザインにできます。responsive_design.htmlを Chrome で開いてください。 <!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.0" /> < title > Responsive Design </ title > < link href = "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel = "stylesheet" /> </ head > < body class = "pl-4 pt-4" > < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > </ body > </ html > Chrome のWindowの幅をできるだけ小さくしてください。次のような青い四角が表示されましたね。 少しづつWindowの幅を大きくしてください。768px以上で四角の幅が16px増えましたね。同様に、1024px、1280px以上で四角の幅が増えたはずです。 タグの定義を見てみましょう。 < div class = "bg-blue-500 w-16 md:w-32 lg:w-48 xl:w-60 h-8" ></ div > w-xxの プレフィックス としてmd:, lg:, xl:が指定されています。これを解釈すると次のようになります。 768px未満は、w-16。 md: 768px以上1024px未満は、w-32。 lg: 1024px以上1280px未満は、w-48。 xl: 1280px以上は、w-60。 レスポンシブデザインでよくあるのが スマホ ではスペースがないので縦に表示し、 タブレット 以上のスペースがある場合は、横に表示するやり方です。 まず、 スマホ で縦に表示するには、普通にdivを使います。 < div > < div > コンテンツ1 </ div > < div > コンテンツ2 </ div > </ div > 幅が768px以上のときに、横に表示するには、md: flex を使います。 < div class = "md:flex" > < div > コンテンツ1 </ div > < div > コンテンツ2 </ div > </ div > つまり、md: flex を使えば、 スマホ では縦に表示し、幅768px以上なら横に表示するということが簡単にできます。 < div class = "mt-4 md:flex" > < div class = "w-72 h-8 bg-indigo-500" ></ div > < div class = "mt-1 md:mt-0 md:ml-1 w-72 h-8 bg-pink-500" ></ div > </ div > 幅が768px未満。 幅が768px以上 mt-1 md:mt-0 md:ml-1を説明しておきましょう。幅が768px未満のときは、縦に並ぶので、mt-1(margin top 4px)で上の要素と4pxあけます。 幅が768px以上のときは、横に並ぶので、md:mt-0(margin top 0px)で上の要素とのスペースを0pxにし、md:ml-1で左の要素とのスペースを4pxあけます。 まとめ Tailwind CSS いかがだったでしょうか。HTMLをみれば、class属性に必要な情報があるため、どういうデザインになるのか予想できます。これによりかなり見通しが良くなります。 ストレスフリーな CSS ライフをお過ごしください。 執筆: @higa ( Shodo で執筆されました )
こんにちは。XI本部、 AIトランスフォーメーションセンター の徳原 光です。 日ごろの業務では、お客様から預かったデータの分析や、AIシステムの開発を担当しています。 実際にやっていることは、データ理解のために EDA (探索的データ分析)を実施したり、分析やAIモデル開発を行うためにデータのクリーニングを行ったり、いわゆるデータサイエンスのどろくさい部分がほとんどになります。 これらの作業は基本的にjupyter notebook上で行っています。jupyter notebookはAIやデータサイエンスに関わっている方なら誰もが触ったことのあるメジャーなツールです。きっと、この記事を読んでくださっている多くの方も日常的に利用しているのではないでしょうか。 jupyter notebookはこれがないと仕事にならないくらい強力なものですが欠点もあって、複数人で同じnotebookを共有して作業を進めていくには不向だったりします。 ということで、そんなjupyter notebookをGitを用いて管理することで、複数人で同時に分析プロジェクトを進めることを可能にする便利なツールJupytextを紹介しようと思います。 なぜJupytextなのか? Jupytextの使い方 インストールの仕方 Jupytextの設定 ファイルの保存方法 pyファイルからnotebookを復元する Jupytextを使ってみて デメリットは対応している環境が限られていること なぜJupytextなのか? 経験のある方もいらっしゃると思いますが、jupyter notebookが出力するipynbファイルをGitで管理しようとするとコンフリクトが頻繁に起こります。 ipynbファイルの中身は json になっていて、コード以外に メタデータ や実行結果が含まれます。それらのデータが実行される度に書き換わるので、処理内容が一緒だとしても複数箇所で異なる部分が生じてしまいます。 また、コンフリクトを解決しようとしても、 json ファイルの差異を比較するのは不可能なので人力では無理です。 Jupytextを使用すると、notebookを保存する度にipynbファイルからコード部分を抽出したpyファイルを自動で作成してくれます。そして作成されたpyファイルのみ、Git上で管理すれば競合の発生を防げるというわけです。 もちろん、ローカルにはipynbファイルが残されるので、実行結果や メタデータ はローカルにしっかりと残ります。 ファイルの復元も簡単でpullしてきたpyファイルをJupyter Notebookで読み込めば、自動でipynbファイルに復元できます。 ※jupyterを VS code で利用している場合、Jupytextは使用できません。 VS code でJupytextを適用しているnotebooのipynbファイルを開いてしまうとipynbファイルが破損します。また、jupytextが適用されていないJupyter Notebookで開いてもipynbファイルが破損するので気をつけてください。 ※この記事では、頭文字が大文字のJupyter NotebookはJupyter Project純正の実行環境を指しています。JupytextはJupyter Notebook以外にJupyter Labでも使用できるようですが、挙動は確認していないです。 Jupytextの使い方 インストールの仕方 まずは導入の仕方から。 公式のドキュメント に書いてあるようにJupytextの導入はpipもしくはcondaを用いて行います。 プロジェクトごとにJupytextの使用の有無を切り替えたい場合は、condaやpyenvを使って仮想環境に導入することをおすすめします。 pip install jupytext --upgrade または conda install jupytext -c conda-forge これだけです。 正常にインストールできていれば、次回のJupyter Notebookの起動時に、 [I 10:28:31.646 LabApp] [Jupytext Server Extension] Changing NotebookApp.contents_manager_class from LargeFileManager to jupytext.TextFileContentsManager と表示されます。 Jupytextの設定 ここまでで、すでにJupytextを使用する準備は整っていますが、後々のことを考えてJupytextの設定をしておきましょう。 Jupytextの設定方法は複数存在しますが、プロジェクト直下のフォルダ(Jupyter Notebookを立ち上げるフォルダ)にjupytext.ymlという yaml ファイルを作成しておくのが簡単な方法みたいです とりあえず、以下を設定ファイルに追加して、保存時にデフォルトで作成されるファイルのフォーマットを指定しましょう。 default_jupytext_formats: "ipynb,py:percent" ipynb はipynbファイルのことです。 py:percent を指定すると、パーセント記号2つ %% でセル間を分けた表記でコードを抽出したpyファイルを作成できます。こうしておくことで、この表記で保存しておけばもし VS code で開いてもセルごとに分割された形で表示、実行できます。 この他に、選択できるフォーマットが複数存在します。こちらの 公式ドキュメント に選択できるフォーマットの詳細が載っています。 保存ファイルのフォーマットを2つ以上選択することも可能です。 設定はJupyter Notebookを再起動すれば、この後作成するすべてのnotebookに対してこの設定が適応されます。すでに作成済みのnotebookに対しては手動で設定する必要があるので、 ツールバー からファイル→Jupyterを選択し、表示されるメニューから保存ファイルのフォーマットを選択してください。 ファイルの保存方法 通常通りnotebookを保存すれば指定された形式でファイルが保存されます。特になにかする必要はないです。 ipynb形式以外にコード部分を抽出したファイルが保存されたら、gitignoreを設定してコード部分を抽出したファイルのみが管理されるように設定します。こうすることで、Gitでjupyter notebookを安全に管理できます。 ちなみに、notebooksというフォルダ上でjupyter notebookを管理している場合、gitignoreファイルを以下のように編集すると、ipynb形式のファイルがGitの管理対象から外れます。 /notebooks/*.ipynb pyファイルからnotebookを復元する こちらも特に何もする必要性はありません。Jupytextが導入されたJupyter Notebookでコード部分が抽出されたpyファイルを開けば、notebookを復元できます。 Jupytextを使ってみて 使い始めてまだ日が浅いですが非常にいい感じに使えています。 jupyter notebookの用途的に、複数の人が1つのnotebookを分担して編集するという使い方はあまりないと思いますが、もし別々の人が1つのnotebookを編集してしまっても簡単にdiffを取ることができるので、gitでのバージョン管理は格段にやりやすくなりました。 さらに、一番恩恵を受けられるのが特にコードに変更を加えていないけどnotebookを実行した場合です。コードに変更がないなら変更を破棄してしまえばいいですが、Jupytextを使っていればそもそもコンフリクトすら生じないのでipynbファイルの差異を意識する必要性がなくなります。 デメリットは対応している環境が限られていること Jupyter Notebook以外にもjupyter notebookを実行できる環境は増えてきていますよね。自分の周りでは VS code にjupyter用の 拡張機能 を入れて利用している人が多く、最近は私も VS code で実行することが増えてきています。 ただ、冒頭でお伝えしたようにJupytextは VS code には対応しておらず、プロジェクトにJupytextを導入するにはメンバー全員にJupyter Notebookまたは、Jupyter Labを使ってもらう必要があります。 現状、Jupyter Notebookよりも VS code のほうが高機能なので、そこは残念なところですね・・・。 jupyter notebookをGitで管理しやすくしてくれるツールJupytextの紹介でした。デメリットもありますがjupyter notebookをGit上で管理している人にはmustなツールだと思います。 この記事を読んで興味が湧いた方は試しに使ってみてください。 最後に、私が所属している AIトランスフォーメーションセンターのwebサイト では、毎月2、3記事のペースでコラムを公開しています。 Kaggle MasterによるKaggleコンペのはじめ方解説や最新の論文に基づいたAIモデル構築手法の提案、さらにAIソフトウェア開発のリアルな現状など、データサイエンスやAIにまつわる様々な情報を発信していますのでぜひ閲覧ください。 それでは。 執筆: @tokuhara.hikaru 、レビュー: @higa ( Shodo で執筆されました )
こんにちは。XI本部、 AIトランスフォーメーションセンター の徳原 光です。 日ごろの業務では、お客様から預かったデータの分析や、AIシステムの開発を担当しています。 実際にやっていることは、データ理解のために EDA (探索的データ分析)を実施したり、分析やAIモデル開発を行うためにデータのクリーニングを行ったり、いわゆるデータサイエンスのどろくさい部分がほとんどになります。 これらの作業は基本的にjupyter notebook上で行っています。jupyter notebookはAIやデータサイエンスに関わっている方なら誰もが触ったことのあるメジャーなツールです。きっと、この記事を読んでくださっている多くの方も日常的に利用しているのではないでしょうか。 jupyter notebookはこれがないと仕事にならないくらい強力なものですが欠点もあって、複数人で同じnotebookを共有して作業を進めていくには不向だったりします。 ということで、そんなjupyter notebookをGitを用いて管理することで、複数人で同時に分析プロジェクトを進めることを可能にする便利なツールJupytextを紹介しようと思います。 なぜJupytextなのか? Jupytextの使い方 インストールの仕方 Jupytextの設定 ファイルの保存方法 pyファイルからnotebookを復元する Jupytextを使ってみて デメリットは対応している環境が限られていること なぜJupytextなのか? 経験のある方もいらっしゃると思いますが、jupyter notebookが出力するipynbファイルをGitで管理しようとするとコンフリクトが頻繁に起こります。 ipynbファイルの中身は json になっていて、コード以外に メタデータ や実行結果が含まれます。それらのデータが実行される度に書き換わるので、処理内容が一緒だとしても複数箇所で異なる部分が生じてしまいます。 また、コンフリクトを解決しようとしても、 json ファイルの差異を比較するのは不可能なので人力では無理です。 Jupytextを使用すると、notebookを保存する度にipynbファイルからコード部分を抽出したpyファイルを自動で作成してくれます。そして作成されたpyファイルのみ、Git上で管理すれば競合の発生を防げるというわけです。 もちろん、ローカルにはipynbファイルが残されるので、実行結果や メタデータ はローカルにしっかりと残ります。 ファイルの復元も簡単でpullしてきたpyファイルをJupyter Notebookで読み込めば、自動でipynbファイルに復元できます。 ※jupyterを VS code で利用している場合、Jupytextは使用できません。 VS code でJupytextを適用しているnotebooのipynbファイルを開いてしまうとipynbファイルが破損します。また、jupytextが適用されていないJupyter Notebookで開いてもipynbファイルが破損するので気をつけてください。 ※この記事では、頭文字が大文字のJupyter NotebookはJupyter Project純正の実行環境を指しています。JupytextはJupyter Notebook以外にJupyter Labでも使用できるようですが、挙動は確認していないです。 Jupytextの使い方 インストールの仕方 まずは導入の仕方から。 公式のドキュメント に書いてあるようにJupytextの導入はpipもしくはcondaを用いて行います。 プロジェクトごとにJupytextの使用の有無を切り替えたい場合は、condaやpyenvを使って仮想環境に導入することをおすすめします。 pip install jupytext --upgrade または conda install jupytext -c conda-forge これだけです。 正常にインストールできていれば、次回のJupyter Notebookの起動時に、 [I 10:28:31.646 LabApp] [Jupytext Server Extension] Changing NotebookApp.contents_manager_class from LargeFileManager to jupytext.TextFileContentsManager と表示されます。 Jupytextの設定 ここまでで、すでにJupytextを使用する準備は整っていますが、後々のことを考えてJupytextの設定をしておきましょう。 Jupytextの設定方法は複数存在しますが、プロジェクト直下のフォルダ(Jupyter Notebookを立ち上げるフォルダ)にjupytext.ymlという yaml ファイルを作成しておくのが簡単な方法みたいです とりあえず、以下を設定ファイルに追加して、保存時にデフォルトで作成されるファイルのフォーマットを指定しましょう。 default_jupytext_formats: "ipynb,py:percent" ipynb はipynbファイルのことです。 py:percent を指定すると、パーセント記号2つ %% でセル間を分けた表記でコードを抽出したpyファイルを作成できます。こうしておくことで、この表記で保存しておけばもし VS code で開いてもセルごとに分割された形で表示、実行できます。 この他に、選択できるフォーマットが複数存在します。こちらの 公式ドキュメント に選択できるフォーマットの詳細が載っています。 保存ファイルのフォーマットを2つ以上選択することも可能です。 設定はJupyter Notebookを再起動すれば、この後作成するすべてのnotebookに対してこの設定が適応されます。すでに作成済みのnotebookに対しては手動で設定する必要があるので、 ツールバー からファイル→Jupyterを選択し、表示されるメニューから保存ファイルのフォーマットを選択してください。 ファイルの保存方法 通常通りnotebookを保存すれば指定された形式でファイルが保存されます。特になにかする必要はないです。 ipynb形式以外にコード部分を抽出したファイルが保存されたら、gitignoreを設定してコード部分を抽出したファイルのみが管理されるように設定します。こうすることで、Gitでjupyter notebookを安全に管理できます。 ちなみに、notebooksというフォルダ上でjupyter notebookを管理している場合、gitignoreファイルを以下のように編集すると、ipynb形式のファイルがGitの管理対象から外れます。 /notebooks/*.ipynb pyファイルからnotebookを復元する こちらも特に何もする必要性はありません。Jupytextが導入されたJupyter Notebookでコード部分が抽出されたpyファイルを開けば、notebookを復元できます。 Jupytextを使ってみて 使い始めてまだ日が浅いですが非常にいい感じに使えています。 jupyter notebookの用途的に、複数の人が1つのnotebookを分担して編集するという使い方はあまりないと思いますが、もし別々の人が1つのnotebookを編集してしまっても簡単にdiffを取ることができるので、gitでのバージョン管理は格段にやりやすくなりました。 さらに、一番恩恵を受けられるのが特にコードに変更を加えていないけどnotebookを実行した場合です。コードに変更がないなら変更を破棄してしまえばいいですが、Jupytextを使っていればそもそもコンフリクトすら生じないのでipynbファイルの差異を意識する必要性がなくなります。 デメリットは対応している環境が限られていること Jupyter Notebook以外にもjupyter notebookを実行できる環境は増えてきていますよね。自分の周りでは VS code にjupyter用の 拡張機能 を入れて利用している人が多く、最近は私も VS code で実行することが増えてきています。 ただ、冒頭でお伝えしたようにJupytextは VS code には対応しておらず、プロジェクトにJupytextを導入するにはメンバー全員にJupyter Notebookまたは、Jupyter Labを使ってもらう必要があります。 現状、Jupyter Notebookよりも VS code のほうが高機能なので、そこは残念なところですね・・・。 jupyter notebookをGitで管理しやすくしてくれるツールJupytextの紹介でした。デメリットもありますがjupyter notebookをGit上で管理している人にはmustなツールだと思います。 この記事を読んで興味が湧いた方は試しに使ってみてください。 最後に、私が所属している AIトランスフォーメーションセンターのwebサイト では、毎月2、3記事のペースでコラムを公開しています。 Kaggle MasterによるKaggleコンペのはじめ方解説や最新の論文に基づいたAIモデル構築手法の提案、さらにAIソフトウェア開発のリアルな現状など、データサイエンスやAIにまつわる様々な情報を発信していますのでぜひ閲覧ください。 それでは。 執筆: @tokuhara.hikaru 、レビュー: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの比嘉です。 それでは、今週も ブロックチェーン 週報3/23いってみようか。 NFTバブル NFTバブルのニュース NFTの発行が活発 NFTの発行が活発のニュース NFTの取り扱いを簡単にしようというソリューションが出てきた NFTの取り扱いを簡単にしようというソリューションが出てきたのニュース ブロックチェーンゲームが活発 ブロックチェーンゲームが活発のニュース NFTバブル NFTバブルの親玉とも言えるYuga LabsがCryptoPunksの 知的財産権 を取得しました。Yuga Labsは、Bored Ape Yacht Clubを作ったところです。取得金額は明らかになっていませんが、Bored ApesとCryptoPunksをあわせて、4200億円以上の価値があると言われているのでかなりの金額が動いたと思われます。 これにより、Bored Apeの持ち主はBored Apeの商用利用権を得られるようになると期待されています。 ここは、注目ポイントです。現在のBored Apeの持ち主は、高額(数億円のものもある)で落札したにもかかわらず、単に 保有 しているだけで商用利用権はないのです。これは、どのNFTでも同じです。 保有 者に商用利用権がついてくるNFTは、ごくまれです。 米ミュージシャンのス ティー ブ・アオキ氏が、過去にリリースした6枚のアルバムから得られた印税よりも、1回のNFTから得られた収入のほうが多かったという報告がありました。 10年間音楽をやってきて、これまで6枚のアルバムをリリースしたけど、 それらを全部合わせた収入よりも 去年のわずか一回のNFTドロップによる収入が上回ったんだ。 NFTの取引高は、2021年8月をピークに減少し、12月に少し盛り返しました。NFTのピークは過ぎたと言われることもありますが、ここに来てバブルな話が出てきたのは要注目です。 本当にバブルが再来しているのか、それとももう一度バブルを起こそうとして誰かが仕掛けているのか。 NFTバブルのニュース Yuga LabsがCryptoPunksのNFTコレクションの権利をクリエイターLarva Labsから取得 Bored ApesのNFTプロジェクトに公式の「ApeCoin」トークンができた プロフィール画像NFTは暗号資産アートを苦しめている スティーブ・アオキ氏「NFT収入が音楽収入を上回った」 NFTの発行が活発 最近、日本でもNFTを発行する例が増えてきました。 2021年のNFTの盛り上がりを見て、自分たちもNFTに取り組もうと思った企業が、ちょうど今ごろ発行しているのかもしれません。 NFTの発行が活発のニュース 明和町の神社で “デジタル御朱印” 配布 「LAWSON TICKET NFT」を発表--思い入れのあるイベントチケットをNFTに NFTの取り扱いを簡単にしようというソリューションが出てきた NFTを売買するには、現状だと暗号資産の知識/経験がそれなりに必要です。一般の人には敷居が高いので、できるだけ簡単にしようというソリューションが出始めてきました。 今のところ、決定的なソリューションはありませんが、NFTが普及するには解決しなければならない問題なので、引き続きウォッチする必要があります。 NFTの取り扱いを簡単にしようというソリューションが出てきたのニュース NFTマーケットプレイスnanakusaが「SBINFT」としてリニューアル。パートナーにはスプツニ子!も PPRP、国内初のNFT購入代行サービスを開始 ブロックチェーン ゲームが活発 ブロックチェーン ゲームが続々と出てきました。どれも、Play to earnが基本コンセプトです。「稼ぐために遊ぶ」ということで、ゲーム内での活動に応じて トーク ンがもらえ、その トーク ンを現金に変えることができます。 また、ゲーム内アイテムがNFTになっていて、 マーケットプレイス で売買できるようになっています。 RMT が可能になったということです。 ブロックチェーン ゲームが活発のニュース ネットマーブル、独自のブロックチェーンエコシステム「MBX」「MARBLEXウォレット」のサービス開始 HashPort、遊んで稼ぐブロックチェーンゲーム「エルフマスターズ」を6月上旬に配信 NFTは4月リリース予定のマーケットプレイス「PLT Place」で販売 XLGAMES,ブロックチェーン適用のMMORPG「ArcheWorld」を発表。7月のグローバルサービス開始を目指す 執筆: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの比嘉です。 それでは、今週も ブロックチェーン 週報3/23いってみようか。 NFTバブル NFTバブルのニュース NFTの発行が活発 NFTの発行が活発のニュース NFTの取り扱いを簡単にしようというソリューションが出てきた NFTの取り扱いを簡単にしようというソリューションが出てきたのニュース ブロックチェーンゲームが活発 ブロックチェーンゲームが活発のニュース NFTバブル NFTバブルの親玉とも言えるYuga LabsがCryptoPunksの 知的財産権 を取得しました。Yuga Labsは、Bored Ape Yacht Clubを作ったところです。取得金額は明らかになっていませんが、Bored ApesとCryptoPunksをあわせて、4200億円以上の価値があると言われているのでかなりの金額が動いたと思われます。 これにより、Bored Apeの持ち主はBored Apeの商用利用権を得られるようになると期待されています。 ここは、注目ポイントです。現在のBored Apeの持ち主は、高額(数億円のものもある)で落札したにもかかわらず、単に 保有 しているだけで商用利用権はないのです。これは、どのNFTでも同じです。 保有 者に商用利用権がついてくるNFTは、ごくまれです。 米ミュージシャンのス ティー ブ・アオキ氏が、過去にリリースした6枚のアルバムから得られた印税よりも、1回のNFTから得られた収入のほうが多かったという報告がありました。 10年間音楽をやってきて、これまで6枚のアルバムをリリースしたけど、 それらを全部合わせた収入よりも 去年のわずか一回のNFTドロップによる収入が上回ったんだ。 NFTの取引高は、2021年8月をピークに減少し、12月に少し盛り返しました。NFTのピークは過ぎたと言われることもありますが、ここに来てバブルな話が出てきたのは要注目です。 本当にバブルが再来しているのか、それとももう一度バブルを起こそうとして誰かが仕掛けているのか。 NFTバブルのニュース Yuga LabsがCryptoPunksのNFTコレクションの権利をクリエイターLarva Labsから取得 Bored ApesのNFTプロジェクトに公式の「ApeCoin」トークンができた プロフィール画像NFTは暗号資産アートを苦しめている スティーブ・アオキ氏「NFT収入が音楽収入を上回った」 NFTの発行が活発 最近、日本でもNFTを発行する例が増えてきました。 2021年のNFTの盛り上がりを見て、自分たちもNFTに取り組もうと思った企業が、ちょうど今ごろ発行しているのかもしれません。 NFTの発行が活発のニュース 明和町の神社で “デジタル御朱印” 配布 「LAWSON TICKET NFT」を発表--思い入れのあるイベントチケットをNFTに NFTの取り扱いを簡単にしようというソリューションが出てきた NFTを売買するには、現状だと暗号資産の知識/経験がそれなりに必要です。一般の人には敷居が高いので、できるだけ簡単にしようというソリューションが出始めてきました。 今のところ、決定的なソリューションはありませんが、NFTが普及するには解決しなければならない問題なので、引き続きウォッチする必要があります。 NFTの取り扱いを簡単にしようというソリューションが出てきたのニュース NFTマーケットプレイスnanakusaが「SBINFT」としてリニューアル。パートナーにはスプツニ子!も PPRP、国内初のNFT購入代行サービスを開始 ブロックチェーン ゲームが活発 ブロックチェーン ゲームが続々と出てきました。どれも、Play to earnが基本コンセプトです。「稼ぐために遊ぶ」ということで、ゲーム内での活動に応じて トーク ンがもらえ、その トーク ンを現金に変えることができます。 また、ゲーム内アイテムがNFTになっていて、 マーケットプレイス で売買できるようになっています。 RMT が可能になったということです。 ブロックチェーン ゲームが活発のニュース ネットマーブル、独自のブロックチェーンエコシステム「MBX」「MARBLEXウォレット」のサービス開始 HashPort、遊んで稼ぐブロックチェーンゲーム「エルフマスターズ」を6月上旬に配信 NFTは4月リリース予定のマーケットプレイス「PLT Place」で販売 XLGAMES,ブロックチェーン適用のMMORPG「ArcheWorld」を発表。7月のグローバルサービス開始を目指す 執筆: @higa ( Shodo で執筆されました )
こんにちは。 電通国際情報サービス (ISID) 金融ソリューション事業部の水野です。 go言語で開発しているプロジェクトで、DIを導入する機会があったので紹介します。 開発環境 Visual Studio Code 1.64.2 go 1.17.8 なぜDIが必要なのか goと言えば go generateに典型的な自動生成をイメージされる方が多く、他の言語で良く使用されるDIコンテナとは縁が薄いと思われる方も多いのではないでしょうか。 私も実はそう考えていたクチですが、依存性を切り離して状況に応じて必要な実装をInjection(注入)するという アーキテクチャ は、言語を問わず有用であるケースはあります。 以下に例を挙げます。 ローカル開発環境ではDBアクセスを伴わないモックを使うが、デプロイされた環境ではDBアクセスを伴うモジュールに差し替えたい 単体テスト では各種通信( API コールなど)を行わないが、それ以外では実際に通信を行うモジュールを稼働させる ファイル入出力を行う機能で、特定の条件下ではファイルを扱わずにエミュレートするモードに切り替えたい インタフェースは確定したが実装が未完の場合。一旦スタブ実装を充ててローカルでの開発は滞らないようにするが、デプロイ時は正式なモジュールを用いる 別の話ですが、このケースは本番モジュールの実装が完成するまでは、panicする等で意図を明確にする方が良いでしょう。 など、一定の規模かつ複雑度のシステムを構築する場合、DIコンテナが欲しくなるケースは多いです。 プロダクト選定 goのDIコンテナとしては、 Google さんの wire や Uber さんの fx が有名です 1 。 GitHub のStar数は wire が一番多いですが、我々はfxを採用しました。 選定には決定的と呼べるほどの理由はなく、強いて挙げると wire は依存性を解決するコードを自動生成しますが、fxは明示的に依存性を解決する実装をするという点です。 wire のメリットとして コンパイル 時に依存性の確 からし さを検証出来ますが、実際ローカルで一度も稼働確認をしないケースは有り得ないので、fxで特段困る事はないと考えました。 また、直近のコミットログ量やリリース頻度( wireのリリース 、 fxのリリース )を見ると、 wire はここ最近停滞気味でfxの方が活発に活動していそうというのも理由です。 fxの使い方 導入は他のライブラリ同様 go get go.uber.org/fx で完了です。(ただしgo modules前提) fxの公式ドキュメントは こちら ですが、利用方法とサンプルコードを示します。 利用方法 初期化用のfx.Appを構築する fx.New を呼び、初期化用の App を構築します。 モジュールの依存関係を定義する fx.Newの引数には、推移的な依存も含めて依存関係のモジュール定義を渡します。 モジュール定義とは、fx.Optionインタフェースを満たすもので、 シグニチャ は以下です。 type Option interface { fmt.Stringer apply(*module) } モジュール定義にはコンスト ラク タ関数を与える fx.Povide 、起動関数を与える fx.Invoke 等を含みます (fx.Optionを満たすため)。 fx.Newには Invoke で得られた1つ以上の起動関数と、依存関係の解決に必要な全てのコンスト ラク タ関数を与えて得られたProviveの戻り値が必要 WithLogger( https://pkg.go.dev/go.uber.org/fx#WithLogger )など、その他Optionを返す関数は type Option 参照 fx.Appを実行する 実行するもっとも単純な方法はApp.Runを呼びだす事ですが、Runで事足りないケースも多いでしょう。 きめ細かい制御をする場合、 fx.App のApp.Startで起動を開始し、App.Stopで明示的に終了します。 fx.Appの起動にあたっての特徴は以下です。 App.Startはエラーが発生した場合を除き、App.Stopが呼ばれるまで処理を終了させない App.Start、App.Stopは LifeCycle による起動時と終了時のフックが可能で、何らかの処理を挟み込める App.Runは、明示的に指定しない限りデフォルトの タイムアウト 値を用い、内部的には Done (ブロックするシグナルのチャンネル)とStartを用いたシンプルな起動処理 Runの実装は以下の3行のみ if code := app.run(app.Done()); code != 0 { app.exit(code) } サンプル fxを用いたある程度実践的な依存性を解決するコードを書いてみます。 起動と終了でロギングするような fx.Hook も仕込んでみました。 利用方法 で示した3点は、 ソースコード 中の「①初期化用のfx.Appを構築する」、「②モジュールの依存関係を定義する」、「③fx.Appを実行する」のコメントに対応しています。 // ユースケースのインタフェースです。 // 便宜上1ファイルで書いていますが、本体の実装が終わる前は暫定実装をDIするなどが可能です。 // 今回は、数行下のpaymentUsecaseを本インタフェースの実装してDIします。 type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { // お金を調達して支払うユースケース実装 fmt.Println( "Paid!!" ) } // ユースケースのファクトリ関数で、fxがPaymentUsecaseの実装を得るために必要です。 // fx.Newの際にこのファクトリ関数を与えていないと、依存性を解決できずに実行時エラーになります。 func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} //Usecaseインタフェースの実装を返す } // リポジトリインタフェースです。 // モジュールが実際にDBアクセスするかどうかなどを、DIするオブジェクトで切り替えが可能です。 type AccountRepository interface { GetByNo(AccountNo) Account } // リポジトリの実装です。後述しますが、モックリポジトリに差し替えてDIするなども可能です。 type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { return Account{ 1 } // 実装は適当 } // リポジトリのファクトリ関数で、fxがAccountRepositoryの実装を得るために必要です。 func NewAccountRepository() AccountRepository { return &accountRepository{} //AccountRepositoryインタフェースの実装を返す } func ExecUsecase(usecase PaymentUsecase) { usecase.Pay() } // 起動時にStart, 終了にStopと出力するライフサイクルフックです。 func AssignLifeCycleLogging(lc fx.Lifecycle) { hook := fx.Hook{ OnStart: func (context.Context) error { fmt.Println( "Start!" ) return nil }, OnStop: func (context.Context) error { fmt.Println( "Stop!" ) return nil }, } lc.Append(hook) } // goアプリケーションのエントリポイントで、ここでfx.Appの作成と実行を行います。 func main() { // ①初期化用のfx.Appを構築する app := fx.New( //②モジュールの依存関係を定義する。依存関係を定義したfx.Optionの実装を引数で与える fx.Provide( NewPaymentUsecase, NewAccountRepository, ), fx.Invoke(AssignLifeCycleLogging, ExecUsecase), ) if err := app.Err(); err != nil { log.Fatalf(err.Error()) } startCtx, cancel := context.WithTimeout(context.Background(), config.StartTimeOut) defer cancel() if err := app.Start(startCtx); err != nil { //③fx.Appを実行する log.Fatal(err) } stopCtx, cancel := context.WithTimeout(context.Background(), config.StopTimeOut) defer cancel() if err := app.Stop(stopCtx); err != nil { log.Fatal(err) } } このように、利用するだけならば導入はさして難しくありません。 ですが、一定の規模のプロジェクト(数十名の開発者がいるイメージ)となると、他にも考えなければならない課題がいくつかあります。 逆に、ある程度の規模でない限り、DIコンテナのような複雑な仕掛けを導入するメリットは希薄です。 我々が、fx導入にあたってどのような開発運用をしたのか、次節以降でご紹介します。 プロジェクトでfxを使う 開発の規模が大きくなってくると、1つのパッケージに複数の ソースコード が並び、総数数千になることも珍しくありません。 管理対象となるオブジェクトを返すファクトリ関数をどのように定義し、統治するかは重要なテーマです。 この課題を「管理対象オブジェクトとファクトリ関数の実装指針」、「モジュール定義方法」、「ビルドタグ」の3つのアプローチから解決しました。 この方向性自体は、 wire と少し重なりあう部分もあります。 管理対象オブジェクトとファクトリ関数の実装指針 特別なことはなく、以下としました。 管理対象とするオブジェクトはインタフェースを設け、対象インタフェースを実装する構造体を作成する 構造体に依存するオブジェクトをフィールドとして保持する 構造体名はインタフェース名称の先頭を小文字としてexportせず、ファクトリ関数でのみ生成可能とする ファクトリ関数の シグニチャ ではインタフェースを宣言し、構造体の実装を返す 管理対象のインタフェース1つにつき、1ファイルを作成する モック実装が必要な場合は、インタフェースにgo:generateを付与する サンプル の実装サンプルでは、 type PaymentUsecase interface から NewPaymentUsecase までの以下が該当します。 type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { fmt.Println( "Paid!!" ) } func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} } 別ファイルでgo:generateを宣言した リポジトリ 実装の例を見て見ましょう。 account_repository.go package repository //go:generate mockgen -source ./account_repository.go -destination ./account_repository_mock.generated.go -package repository type AccountRepository interface { GetByNo(AccountNo) Account } type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { // ・・・省略 } これで、コマンドでも IDE からでもモック生成が可能です。 IDE に VS Code を用いていれば、以下をクリックすれば生成されます。 モジュール定義方法 管理対象のオブジェクトとファクトリ関数の実装を、モジュールとしてどう管理するかが次の課題です。 provider.goというファクトリ関数を集約する実装と、ファクトリ関数とFxを結びつけるmodule.goを実装することにしました。 具体的には以下です。 各パッケージ毎に1つ、provider.goというファイルを設け、当該パッケージのファクトリ関数を並べる ファクトリ関数とFxを結びつけるため、各パッケージ毎に1つmodule.goを設ける module.goはfx.Provideにパッケージ内の全ファクトリ関数を渡した結果得られるfx.Optionを返す 得られたfx.Optionは Module という名称でexportする 管理対象オブジェクトが必要な場合、利用者側が該当するパッケージの Module を fx.Options に与えて依存性を解決する provider.goは用途毎にビルドタグ [^2]で切り替える。 プロダクション用はprovider.goだが、 単体テスト 時はprovider_ut.go、内部 結合テスト 時はprovider_it.goといった具合 リポジトリ に依存するUsecaseが複数ある例で、呼び出し側のコードと合わせて確認します。 provider.go package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } module.go package usecase import "go.uber.org/fx" var Module = fx.Provide(NewPaymentUsecase, NewRcvUsecase) 利用側は、fx.Appに Module を与えて依存性を解決します。 fx.New( fx.Options( repository.Module, //リポジトリの依存性を解決するモジュール usecase.Module, //Usecaseの依存性を解決するモジュール ), fx.Invoke( ・・・省略 ) ビルドタグ provier.go、module.goで依存性は解決できるようになりました。 ただ、これではまだ環境や状況に応じてインタフェースの実装を切り替えることは出来ません。 そこで、ビルドタグを用います。 ビルドタグとはGo tool によって提供される ビルド制約システム です。 コードの先頭に //go:build [タグ名] を付与することで、ビルド対象ファイルを指定します。 go build のtagsオプションで複数個のタグ名が指定可能で、該当するタグ名のgoファイルのみビルド対象となります。 これを踏まえ、provider.goと組み合わせたビルド戦術は以下です。 provider.goに用途毎のビルドタグを付与する。 事前に付与するタグを決めておく。ut( 単体テスト )、it(内部 結合テスト )など provider.goのファイル名 サフィックス にタグ名を付与する。これにより、プロダクション用はprovider.goだが、 単体テスト 時はprovider_ut.go、内部 結合テスト 時はprovider_it.goといった具合で制御可能になる モジュール定義方法 のサンプルコードに、utビルドタグとその他タグを付与したprovider.goの実装は以下です。 なお、モック実装には gomock を利用しています。 provider_ut.go //go:build ut package usecase import ( "github.com/golang/mock/gomock" ) func NewPaymentUsecase(ctrl *gomock.Controller) PaymentUsecase { return NewMockPaymentUsecase(ctrl) } func NewRcvUsecase(ctrl *gomock.Controller) RcvUsecase { return NewMockRcvUsecase(ctrl) } provider.go //go:build it || stg package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } リポジトリ に依存するUsecaseが複数あるケースで、provider_ut.goとprovider.goで実装を切り替えます。 単体テスト (ut) 時は自動生成したUsecaseのモック実装が用いられ、内部 結合テスト 以降は正規の実装が用いられます。 Module.goや呼び出し側のコードに変更はありません。 その他の便利機能 他にfxで積極的に使用している機能は fx.In です。 依存関係が増えてくると、ファクトリ関数の引数が相当数になり、コードの見通しや保守性が著しく低下します。 そういった場合、依存関係のオブジェクトを全て定義した構造体を作成してInjectionします。 この構造体をパラメータ構造体と呼びます。 依存関係が増えた場合でもパラメータ構造体にフィールドを追加するだけで済み、かなり強力な機能です。 サンプルコードで違いを確認します。 SetlUsecaseという、複数のオブジェクトに依存する ユースケース を例に、モジュール定義と生成を見てみます。 パラメータ構造体を使わない例 type SetlUsecase interface { Settle() } type setlUsecase struct { config *Config repoAccount AccountRepository repoSetl SettlementRepository repoCode CodeMasterRepository cal *Calendar setlExecutor SetlExecutor priorityJudger PriorityJudger } func NewSetlUsecase(config *Config, repoAccount AccountRepository, repoSetl SettlementRepository, repoCode CodeMasterRepository, cal *Calendar, setlExecutor SetlExecutor, priorityJudger PriorityJudger) SetlUsecase { return &setlUsecase{ config: config, repoAccount: repoAccount, repoSetl: repoSetl, repoCode: repoCode, cal: cal, setlExecutor: setlExecutor, priorityJudger: priorityJudger, } } この程度ならそこまででもないですが、実際の開発ではもっと多くのオブジェクトに依存するケースもあります。 これ以上ファクトリ関数の引数が増えるのは辛いでしょう。 パラメータ構造体で置き換えたコードを見てみましょう。 パラメータ構造体で実装した例 // SetlUsecaseとsetlUsecaseは「パラメータ構造体を使わない例」と同様のため省略 type UsecaseParams struct { fx.In Config *Config RepoAccount AccountRepository RepoSetl SettlementRepository RepoCode CodeMasterRepository Cal *Calendar SetlExecutor SetlExecutor PriorityJudger PriorityJudger } func NewSetlUsecase(params UsecaseParams) SetlUsecase { return &setlUsecase{ config: params.Config, repoAccount: params.RepoAccount, repoSetl: params.RepoSetl, repoCode: params.RepoCode, cal: params.Cal, setlExecutor: params.SetlExecutor, priorityJudger: params.PriorityJudger, } } NewSetlUsecaseがすっきりしました。 ただし、パラメータ構造体を使う上で、以下の2点はご注意ください。 パラメータ構造体のフィールドはexportしなければならない ファクトリ関数に与えるパラメータ構造体は、ポインタで渡すことが出来ないので値として渡す 上記1, 2に違反する場合、実行時fxがエラーを出力します。 エラー出力例: cannot depend on a pointer to a parameter object, use a value instead: *main.UsecaseParams is a pointer to a struct that embeds dig.In これで、setlUsecaseに依存するオブジェクトが増えたとしても、コンスト ラク タ関数に引数を追加せず、パラメータ構造体への追加で済みます。 まとめ 今回はgo開発でDIを導入したお話でした。 当初の目的 は全て達成できており、大きなハマりもなく快適に開発出来ています。 オブジェクトの生成処理を一元的に管理する意義は大きく、稼働確認を一発すれば初期化に伴う実装ミスはほぼなくなりました。 また副次的な効果として、モジュール間の依存関係を意識することで、インタフェースが洗練された印象があります。 結果、様々な言語のDIコンテナが目指すところである、インターフェースと実装を分離して抽象度を高め、変更容易性を向上するという点を達成できました。 go開発でDI導入を検討中なら、 uber-go/fx を選択肢の一つとしてお考えになってはいかがでしょうか。 執筆: @mizuno.kazuhiro 、レビュー: @sato.taichi ( Shodo で執筆されました ) Facebook さんの inject は、2022年3月現在 アーカイブ されており、選定から外しました。 ↩
こんにちは。 電通国際情報サービス (ISID) 金融ソリューション事業部の水野です。 go言語で開発しているプロジェクトで、DIを導入する機会があったので紹介します。 開発環境 Visual Studio Code 1.64.2 go 1.17.8 なぜDIが必要なのか goと言えば go generateに典型的な自動生成をイメージされる方が多く、他の言語で良く使用されるDIコンテナとは縁が薄いと思われる方も多いのではないでしょうか。 私も実はそう考えていたクチですが、依存性を切り離して状況に応じて必要な実装をInjection(注入)するという アーキテクチャ は、言語を問わず有用であるケースはあります。 以下に例を挙げます。 ローカル開発環境ではDBアクセスを伴わないモックを使うが、デプロイされた環境ではDBアクセスを伴うモジュールに差し替えたい 単体テスト では各種通信( API コールなど)を行わないが、それ以外では実際に通信を行うモジュールを稼働させる ファイル入出力を行う機能で、特定の条件下ではファイルを扱わずにエミュレートするモードに切り替えたい インタフェースは確定したが実装が未完の場合。一旦スタブ実装を充ててローカルでの開発は滞らないようにするが、デプロイ時は正式なモジュールを用いる 別の話ですが、このケースは本番モジュールの実装が完成するまでは、panicする等で意図を明確にする方が良いでしょう。 など、一定の規模かつ複雑度のシステムを構築する場合、DIコンテナが欲しくなるケースは多いです。 プロダクト選定 goのDIコンテナとしては、 Google さんの wire や Uber さんの fx が有名です 1 。 GitHub のStar数は wire が一番多いですが、我々はfxを採用しました。 選定には決定的と呼べるほどの理由はなく、強いて挙げると wire は依存性を解決するコードを自動生成しますが、fxは明示的に依存性を解決する実装をするという点です。 wire のメリットとして コンパイル 時に依存性の確 からし さを検証出来ますが、実際ローカルで一度も稼働確認をしないケースは有り得ないので、fxで特段困る事はないと考えました。 また、直近のコミットログ量やリリース頻度( wireのリリース 、 fxのリリース )を見ると、 wire はここ最近停滞気味でfxの方が活発に活動していそうというのも理由です。 fxの使い方 導入は他のライブラリ同様 go get go.uber.org/fx で完了です。(ただしgo modules前提) fxの公式ドキュメントは こちら ですが、利用方法とサンプルコードを示します。 利用方法 初期化用のfx.Appを構築する fx.New を呼び、初期化用の App を構築します。 モジュールの依存関係を定義する fx.Newの引数には、推移的な依存も含めて依存関係のモジュール定義を渡します。 モジュール定義とは、fx.Optionインタフェースを満たすもので、 シグニチャ は以下です。 type Option interface { fmt.Stringer apply(*module) } モジュール定義にはコンスト ラク タ関数を与える fx.Povide 、起動関数を与える fx.Invoke 等を含みます (fx.Optionを満たすため)。 fx.Newには Invoke で得られた1つ以上の起動関数と、依存関係の解決に必要な全てのコンスト ラク タ関数を与えて得られたProviveの戻り値が必要 WithLogger( https://pkg.go.dev/go.uber.org/fx#WithLogger )など、その他Optionを返す関数は type Option 参照 fx.Appを実行する 実行するもっとも単純な方法はApp.Runを呼びだす事ですが、Runで事足りないケースも多いでしょう。 きめ細かい制御をする場合、 fx.App のApp.Startで起動を開始し、App.Stopで明示的に終了します。 fx.Appの起動にあたっての特徴は以下です。 App.Startはエラーが発生した場合を除き、App.Stopが呼ばれるまで処理を終了させない App.Start、App.Stopは LifeCycle による起動時と終了時のフックが可能で、何らかの処理を挟み込める App.Runは、明示的に指定しない限りデフォルトの タイムアウト 値を用い、内部的には Done (ブロックするシグナルのチャンネル)とStartを用いたシンプルな起動処理 Runの実装は以下の3行のみ if code := app.run(app.Done()); code != 0 { app.exit(code) } サンプル fxを用いたある程度実践的な依存性を解決するコードを書いてみます。 起動と終了でロギングするような fx.Hook も仕込んでみました。 利用方法 で示した3点は、 ソースコード 中の「①初期化用のfx.Appを構築する」、「②モジュールの依存関係を定義する」、「③fx.Appを実行する」のコメントに対応しています。 // ユースケースのインタフェースです。 // 便宜上1ファイルで書いていますが、本体の実装が終わる前は暫定実装をDIするなどが可能です。 // 今回は、数行下のpaymentUsecaseを本インタフェースの実装してDIします。 type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { // お金を調達して支払うユースケース実装 fmt.Println( "Paid!!" ) } // ユースケースのファクトリ関数で、fxがPaymentUsecaseの実装を得るために必要です。 // fx.Newの際にこのファクトリ関数を与えていないと、依存性を解決できずに実行時エラーになります。 func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} //Usecaseインタフェースの実装を返す } // リポジトリインタフェースです。 // モジュールが実際にDBアクセスするかどうかなどを、DIするオブジェクトで切り替えが可能です。 type AccountRepository interface { GetByNo(AccountNo) Account } // リポジトリの実装です。後述しますが、モックリポジトリに差し替えてDIするなども可能です。 type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { return Account{ 1 } // 実装は適当 } // リポジトリのファクトリ関数で、fxがAccountRepositoryの実装を得るために必要です。 func NewAccountRepository() AccountRepository { return &accountRepository{} //AccountRepositoryインタフェースの実装を返す } func ExecUsecase(usecase PaymentUsecase) { usecase.Pay() } // 起動時にStart, 終了にStopと出力するライフサイクルフックです。 func AssignLifeCycleLogging(lc fx.Lifecycle) { hook := fx.Hook{ OnStart: func (context.Context) error { fmt.Println( "Start!" ) return nil }, OnStop: func (context.Context) error { fmt.Println( "Stop!" ) return nil }, } lc.Append(hook) } // goアプリケーションのエントリポイントで、ここでfx.Appの作成と実行を行います。 func main() { // ①初期化用のfx.Appを構築する app := fx.New( //②モジュールの依存関係を定義する。依存関係を定義したfx.Optionの実装を引数で与える fx.Provide( NewPaymentUsecase, NewAccountRepository, ), fx.Invoke(AssignLifeCycleLogging, ExecUsecase), ) if err := app.Err(); err != nil { log.Fatalf(err.Error()) } startCtx, cancel := context.WithTimeout(context.Background(), config.StartTimeOut) defer cancel() if err := app.Start(startCtx); err != nil { //③fx.Appを実行する log.Fatal(err) } stopCtx, cancel := context.WithTimeout(context.Background(), config.StopTimeOut) defer cancel() if err := app.Stop(stopCtx); err != nil { log.Fatal(err) } } このように、利用するだけならば導入はさして難しくありません。 ですが、一定の規模のプロジェクト(数十名の開発者がいるイメージ)となると、他にも考えなければならない課題がいくつかあります。 逆に、ある程度の規模でない限り、DIコンテナのような複雑な仕掛けを導入するメリットは希薄です。 我々が、fx導入にあたってどのような開発運用をしたのか、次節以降でご紹介します。 プロジェクトでfxを使う 開発の規模が大きくなってくると、1つのパッケージに複数の ソースコード が並び、総数数千になることも珍しくありません。 管理対象となるオブジェクトを返すファクトリ関数をどのように定義し、統治するかは重要なテーマです。 この課題を「管理対象オブジェクトとファクトリ関数の実装指針」、「モジュール定義方法」、「ビルドタグ」の3つのアプローチから解決しました。 この方向性自体は、 wire と少し重なりあう部分もあります。 管理対象オブジェクトとファクトリ関数の実装指針 特別なことはなく、以下としました。 管理対象とするオブジェクトはインタフェースを設け、対象インタフェースを実装する構造体を作成する 構造体に依存するオブジェクトをフィールドとして保持する 構造体名はインタフェース名称の先頭を小文字としてexportせず、ファクトリ関数でのみ生成可能とする ファクトリ関数の シグニチャ ではインタフェースを宣言し、構造体の実装を返す 管理対象のインタフェース1つにつき、1ファイルを作成する モック実装が必要な場合は、インタフェースにgo:generateを付与する サンプル の実装サンプルでは、 type PaymentUsecase interface から NewPaymentUsecase までの以下が該当します。 type PaymentUsecase interface { Pay() } type paymentUsecase struct { repo AccountRepository } func (paymentUsecase) Pay() { fmt.Println( "Paid!!" ) } func NewPaymentUsecase(repo AccountRepository) PaymentUsecase { return &paymentUsecase{repo: repo} } 別ファイルでgo:generateを宣言した リポジトリ 実装の例を見て見ましょう。 account_repository.go package repository //go:generate mockgen -source ./account_repository.go -destination ./account_repository_mock.generated.go -package repository type AccountRepository interface { GetByNo(AccountNo) Account } type accountRepository struct {} func (repo accountRepository) GetByNo(acntNo AccountNo) Account { // ・・・省略 } これで、コマンドでも IDE からでもモック生成が可能です。 IDE に VS Code を用いていれば、以下をクリックすれば生成されます。 モジュール定義方法 管理対象のオブジェクトとファクトリ関数の実装を、モジュールとしてどう管理するかが次の課題です。 provider.goというファクトリ関数を集約する実装と、ファクトリ関数とFxを結びつけるmodule.goを実装することにしました。 具体的には以下です。 各パッケージ毎に1つ、provider.goというファイルを設け、当該パッケージのファクトリ関数を並べる ファクトリ関数とFxを結びつけるため、各パッケージ毎に1つmodule.goを設ける module.goはfx.Provideにパッケージ内の全ファクトリ関数を渡した結果得られるfx.Optionを返す 得られたfx.Optionは Module という名称でexportする 管理対象オブジェクトが必要な場合、利用者側が該当するパッケージの Module を fx.Options に与えて依存性を解決する provider.goは用途毎にビルドタグ [^2]で切り替える。 プロダクション用はprovider.goだが、 単体テスト 時はprovider_ut.go、内部 結合テスト 時はprovider_it.goといった具合 リポジトリ に依存するUsecaseが複数ある例で、呼び出し側のコードと合わせて確認します。 provider.go package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } module.go package usecase import "go.uber.org/fx" var Module = fx.Provide(NewPaymentUsecase, NewRcvUsecase) 利用側は、fx.Appに Module を与えて依存性を解決します。 fx.New( fx.Options( repository.Module, //リポジトリの依存性を解決するモジュール usecase.Module, //Usecaseの依存性を解決するモジュール ), fx.Invoke( ・・・省略 ) ビルドタグ provier.go、module.goで依存性は解決できるようになりました。 ただ、これではまだ環境や状況に応じてインタフェースの実装を切り替えることは出来ません。 そこで、ビルドタグを用います。 ビルドタグとはGo tool によって提供される ビルド制約システム です。 コードの先頭に //go:build [タグ名] を付与することで、ビルド対象ファイルを指定します。 go build のtagsオプションで複数個のタグ名が指定可能で、該当するタグ名のgoファイルのみビルド対象となります。 これを踏まえ、provider.goと組み合わせたビルド戦術は以下です。 provider.goに用途毎のビルドタグを付与する。 事前に付与するタグを決めておく。ut( 単体テスト )、it(内部 結合テスト )など provider.goのファイル名 サフィックス にタグ名を付与する。これにより、プロダクション用はprovider.goだが、 単体テスト 時はprovider_ut.go、内部 結合テスト 時はprovider_it.goといった具合で制御可能になる モジュール定義方法 のサンプルコードに、utビルドタグとその他タグを付与したprovider.goの実装は以下です。 なお、モック実装には gomock を利用しています。 provider_ut.go //go:build ut package usecase import ( "github.com/golang/mock/gomock" ) func NewPaymentUsecase(ctrl *gomock.Controller) PaymentUsecase { return NewMockPaymentUsecase(ctrl) } func NewRcvUsecase(ctrl *gomock.Controller) RcvUsecase { return NewMockRcvUsecase(ctrl) } provider.go //go:build it || stg package usecase import ( "sample-prj/domain/repository" ) func NewPaymentUsecase(repo repository.AccountRepository) PaymentUsecase { return &paymentUsecase{repo} } func NewRcvUsecase(repo repository.AccountRepository) RcvUsecase { return &rcvUsecase{repo} } リポジトリ に依存するUsecaseが複数あるケースで、provider_ut.goとprovider.goで実装を切り替えます。 単体テスト (ut) 時は自動生成したUsecaseのモック実装が用いられ、内部 結合テスト 以降は正規の実装が用いられます。 Module.goや呼び出し側のコードに変更はありません。 その他の便利機能 他にfxで積極的に使用している機能は fx.In です。 依存関係が増えてくると、ファクトリ関数の引数が相当数になり、コードの見通しや保守性が著しく低下します。 そういった場合、依存関係のオブジェクトを全て定義した構造体を作成してInjectionします。 この構造体をパラメータ構造体と呼びます。 依存関係が増えた場合でもパラメータ構造体にフィールドを追加するだけで済み、かなり強力な機能です。 サンプルコードで違いを確認します。 SetlUsecaseという、複数のオブジェクトに依存する ユースケース を例に、モジュール定義と生成を見てみます。 パラメータ構造体を使わない例 type SetlUsecase interface { Settle() } type setlUsecase struct { config *Config repoAccount AccountRepository repoSetl SettlementRepository repoCode CodeMasterRepository cal *Calendar setlExecutor SetlExecutor priorityJudger PriorityJudger } func NewSetlUsecase(config *Config, repoAccount AccountRepository, repoSetl SettlementRepository, repoCode CodeMasterRepository, cal *Calendar, setlExecutor SetlExecutor, priorityJudger PriorityJudger) SetlUsecase { return &setlUsecase{ config: config, repoAccount: repoAccount, repoSetl: repoSetl, repoCode: repoCode, cal: cal, setlExecutor: setlExecutor, priorityJudger: priorityJudger, } } この程度ならそこまででもないですが、実際の開発ではもっと多くのオブジェクトに依存するケースもあります。 これ以上ファクトリ関数の引数が増えるのは辛いでしょう。 パラメータ構造体で置き換えたコードを見てみましょう。 パラメータ構造体で実装した例 // SetlUsecaseとsetlUsecaseは「パラメータ構造体を使わない例」と同様のため省略 type UsecaseParams struct { fx.In Config *Config RepoAccount AccountRepository RepoSetl SettlementRepository RepoCode CodeMasterRepository Cal *Calendar SetlExecutor SetlExecutor PriorityJudger PriorityJudger } func NewSetlUsecase(params UsecaseParams) SetlUsecase { return &setlUsecase{ config: params.Config, repoAccount: params.RepoAccount, repoSetl: params.RepoSetl, repoCode: params.RepoCode, cal: params.Cal, setlExecutor: params.SetlExecutor, priorityJudger: params.PriorityJudger, } } NewSetlUsecaseがすっきりしました。 ただし、パラメータ構造体を使う上で、以下の2点はご注意ください。 パラメータ構造体のフィールドはexportしなければならない ファクトリ関数に与えるパラメータ構造体は、ポインタで渡すことが出来ないので値として渡す 上記1, 2に違反する場合、実行時fxがエラーを出力します。 エラー出力例: cannot depend on a pointer to a parameter object, use a value instead: *main.UsecaseParams is a pointer to a struct that embeds dig.In これで、setlUsecaseに依存するオブジェクトが増えたとしても、コンスト ラク タ関数に引数を追加せず、パラメータ構造体への追加で済みます。 まとめ 今回はgo開発でDIを導入したお話でした。 当初の目的 は全て達成できており、大きなハマりもなく快適に開発出来ています。 オブジェクトの生成処理を一元的に管理する意義は大きく、稼働確認を一発すれば初期化に伴う実装ミスはほぼなくなりました。 また副次的な効果として、モジュール間の依存関係を意識することで、インタフェースが洗練された印象があります。 結果、様々な言語のDIコンテナが目指すところである、インターフェースと実装を分離して抽象度を高め、変更容易性を向上するという点を達成できました。 go開発でDI導入を検討中なら、 uber-go/fx を選択肢の一つとしてお考えになってはいかがでしょうか。 執筆: @mizuno.kazuhiro 、レビュー: @sato.taichi ( Shodo で執筆されました ) Facebook さんの inject は、2022年3月現在 アーカイブ されており、選定から外しました。 ↩
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの比嘉です。 それでは、 ブロックチェーン 週報3/15いってみようか。 非常時の暗号資産 非常時の暗号資産のニュース NFT詐欺 NFT詐欺のニュース その他のニュース 非常時の暗号資産 ロシアの暗号資産を凍結する動きが出ていますが、あまり効果はないんじゃないかと思います。どうしてかというと凍結しようとしている口座は、暗号資産取引所の口座なので、すでに暗号資産は別の個人口座に送金されている可能性が高いからです。暗号資産は、非中央集権的に個人口座が簡単に作れます。 非常時の暗号資産のニュース 政府、仮想通貨取引の停止要請 露制裁で30社に NFT詐欺 NFTは、NFTの発行元(ク リエータ ー)がちゃんとした権利者であることを確認するのが難しいので、詐欺が横行しています。発行元が信頼できないNFTは、今の段階では買わないほうが良いと思います。 NFTのなりすまし対策をしているサービスもあります。 NFT Spoofing(なりすまし)対策 Adobe もク リエータ ーが自身の作品であることを証明する機能を提供しています。 NFT詐欺のニュース ある日を境に姿を消しちゃった最悪なNFT詐欺ワースト7(2022年2月版) 2月だけで、10億円弱が被害にあったとか、醜すぎます。 アドビの「Behance」がソラナ対応 Ethereumは、手数料が高い/処理が遅い/環境に悪いという問題を抱えているのでSolanaにも対応したみたいですね。 その他のニュース 博報堂DY、NFTマーケットプレイス開設へ──スポーツやアニメ、音楽で ホワイトハウスが暗号通資産に関する大統領令を発表 イーサリアム互換ブロックチェーン構築クラウドなどを手がけるG.U.テクノロジーズがプレシリーズAで2.6億円の追加調達 これも脱Ethereumの流れ 決済大手Stripe、暗号資産決済のサポートを再開 内村航平、引退記念デジタルアートNFT販売へ 絵(似顔絵?)の予定最低入札価格は400万円相当のETH( イーサリアム )とのこと。動画の方は300点限定で、定価8万円とのことです。 執筆: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの比嘉です。 それでは、 ブロックチェーン 週報3/15いってみようか。 非常時の暗号資産 非常時の暗号資産のニュース NFT詐欺 NFT詐欺のニュース その他のニュース 非常時の暗号資産 ロシアの暗号資産を凍結する動きが出ていますが、あまり効果はないんじゃないかと思います。どうしてかというと凍結しようとしている口座は、暗号資産取引所の口座なので、すでに暗号資産は別の個人口座に送金されている可能性が高いからです。暗号資産は、非中央集権的に個人口座が簡単に作れます。 非常時の暗号資産のニュース 政府、仮想通貨取引の停止要請 露制裁で30社に NFT詐欺 NFTは、NFTの発行元(ク リエータ ー)がちゃんとした権利者であることを確認するのが難しいので、詐欺が横行しています。発行元が信頼できないNFTは、今の段階では買わないほうが良いと思います。 NFTのなりすまし対策をしているサービスもあります。 NFT Spoofing(なりすまし)対策 Adobe もク リエータ ーが自身の作品であることを証明する機能を提供しています。 NFT詐欺のニュース ある日を境に姿を消しちゃった最悪なNFT詐欺ワースト7(2022年2月版) 2月だけで、10億円弱が被害にあったとか、醜すぎます。 アドビの「Behance」がソラナ対応 Ethereumは、手数料が高い/処理が遅い/環境に悪いという問題を抱えているのでSolanaにも対応したみたいですね。 その他のニュース 博報堂DY、NFTマーケットプレイス開設へ──スポーツやアニメ、音楽で ホワイトハウスが暗号通資産に関する大統領令を発表 イーサリアム互換ブロックチェーン構築クラウドなどを手がけるG.U.テクノロジーズがプレシリーズAで2.6億円の追加調達 これも脱Ethereumの流れ 決済大手Stripe、暗号資産決済のサポートを再開 内村航平、引退記念デジタルアートNFT販売へ 絵(似顔絵?)の予定最低入札価格は400万円相当のETH( イーサリアム )とのこと。動画の方は300点限定で、定価8万円とのことです。 執筆: @higa ( Shodo で執筆されました )
こんにちは。 電通国際情報サービス (ISID) X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの山口です。 ISIDでセキュリティの担当をしていますが、 AWS やAzure等の クラウド サービスを利用したシステム構築が一般的になり、オンプレミスでシステム構築をしていた頃よりも不用意な設定ミスによる セキュリティインシデント がより簡単に起こってしまう時代になったと感じています。 このような セキュリティインシデント を防止するための解決策の1つとして、 AWS Security Hub 1 があります。 Security Hubはセキュリティ情報を収集・チェック・評価を行うCSPM(Cloud Security Posture Management)機能を有するサービスです。 今回は、Security Hubを使っていて困ったことや不明な点を詳しく調べたことについてご紹介します。 1. Secrets Managerを使用しても警告が出る件 1.1. 対象のセキュリティ基準2 1.2. 設定方法 1.3. 疑問点 1.4.ちなみに 2. NOT_AVAILABLE 問題 2.1. 困ったこと 2.2. 解決方法 2.3. ちなみに 3. 消せないS3バケット問題 3.1. 対象のセキュリティ基準[^2] 3.2. 設定方法 3.3. 困ったこと 3.4. 解決方法 4. HTTPヘッダーの削除とDesync緩和モード 4.1. 対象のセキュリティ基準[^2] 4.2. 分からなかったこと 4.3. 確認したこと 5. おわりに 1. Secrets Managerを使用しても警告が出る件 1.1. 対象のセキュリティ基準 2 [CodeBuild.2] CodeBuild プロジェクト 環境変数 にクリアテキストの認証情報を含めることはできません これは「CodeBuild 内で AWS _ ACCESS _KEY_ID や AWS _SECRET_ ACCESS _KEY などの認証情報はプレーンテキスト(クリアテキスト)で保存しないでください。」という内容です。 1.2. 設定方法 設定はビルドプロジェクトの作成時に行えます。 設定画面を見ると下記の3つの中から選択できることが分かります。 CodeBuild.2 のアラートを検出されないようにするための正解は「パラメータ」です。 Systems Manager パラメータストアから認証情報を取得するようにできます。 プレーンテキスト(クリアテキスト) パラメータ Secrets Manager 1.3. 疑問点 プレーンテキストがセキュリティ上問題となることは分かりますが、Secrets Managerを使うのはよさそうに思えます。 ですが、実際にSecrets Managerを指定すると CodeBuild.2 でしっかりアラートが上がります。 このことを AWS サポートに問合せしましたが、Security Hubの仕様とのことでアラートを検出させたくない場合は、対象のルール(セキュリティ基準)を無効化するしかないようです。 1.4.ちなみに CodeBuildの実行環境から AWS リソースにアクセスしたい場合 AWS _ ACCESS _KEY_ID や AWS _SECRET_ ACCESS _KEY をCodeBuildの 環境変数 に設定するのではなく、CodeBuildプロジェクトのサービスロールに必要な権限を付与することで解決できます。 2. NOT_AVAILABLE 問題 2.1. 困ったこと 今回検証した環境では下図のように集約アカウントを準備して、複 数の子 アカウントの検出結果を集約アカウントで確認できるようにしました。 (Security Hubの動作イメージ) ところが一部のアカウントに対して、特定のセキュリティ基準の検出結果で「NOT_AVAILABLE」と表示されていることに気が付きました。 2.2. 解決方法 AWS サポートに問い合わせたところ、「 AWS Configに AWS リソースの設定詳細を取得するための権限が足りていないのではないか。」という回答でした。 Security Hubは AWS Configに AWS リソースのチェックを代行してもらう動作のため、 AWS Configに各種リソースへのアクセス権限が必要となります。 今回は AWS の管理ポリシー AWS_ConfigRole を AWS Configのロールに割り当てることで正常に検出結果が表示されるようになりました。 2.3. ちなみに AWS Configの設定画面から「 AWS Config サービスにリンクされたロールの作成」を選択すると AWSConfigServiceRolePolicy を含むロールが AWS Configに割り当てられます。 下記のリンクからも、分かるように AWSConfigServiceRolePolicy と AWS_ConfigRole はどちらを使用しても同じアクセス許可(2022年2月現在)となるため、その使い分けについては不明です。 https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/security-iam-awsmanpol.html 3. 消せないS3 バケット 問題 3.1. 対象のセキュリティ基準[^2] [S3.5] S3 バケット は、Secure Socket Layer を使用するためのリク エス トが必要です これは「S3 バケット のポリシーで、Secure Socket Layer ( SSL ) でのアクセスを必須に設定してください。」という内容です。 3.2. 設定方法 設定はS3 バケット の バケット ポリシーで行います。 { " Id ": " ExamplePolicy ", " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " AllowSSLRequestsOnly ", " Action ": " s3:* ", " Effect ": " Deny ", " Resource ": [ " S3 バケットの ARN ", " S3 バケットの ARN/* " ] , " Condition ": { " Bool ": { " aws:SecureTransport ": " false " } } , " Principal ": " * " } ] } 3.3. 困ったこと 普段から HTTPS でアクセスしているため、上記の設定が有効になっているかを判断できなかったので、軽い気持ちで バケット ポリシーを変更しました。 (変更前) "aws:SecureTransport": "false" (変更後) "aws:SecureTransport": "true" そうすると当然ですが、S3 バケット に対するブラウザからの HTTPS 通信は全て許可されなくなります。 あわてて元に戻そうとするも下記のように バケット ポリシー自体にもアクセスできなくなってしまいました。 3.4. 解決方法 ルートアカウントでログインすれば バケット ポリシーを削除できるようですが、権限がなかったのでCloudShellから下記のコマンドを実行して バケット ポリシーを削除しました。 aws s3api delete-bucket-policy --bucket "バケット名" --endpoint-url http://s3.ap-northeast-1.amazonaws.com 4. HTTPヘッダーの削除とDesync緩和モード 4.1. 対象のセキュリティ基準[^2] [ELB.4] HTTP ヘッダーを削除するようにアプリケーション ロードバランサー を設定する必要があります これは「HTTP desync 攻撃を防ぐために、Application Load Balancerで無効な HTTP ヘッダー値をドロップするように設定してください。」という内容です。 4.2. 分からなかったこと 「 ロードバランサー 属性の編集」画面にて「無効なHTTPヘッダーを削除」 チェックボックス をオンにすることで、セキュリティ基準はクリアできます。 ここで、画面の上にある「Desync 緩和モード」という似たような目的に思える チェックボックス があったので違いを AWS サポートに聞いてみました。 4.3. 確認したこと 前提として、Desync 緩和モードは下記のURLにあるように、リク エス トの分類とALBのモード設定に基づいて動作が決定します。 詳細は下記のURLをご覧ください。 https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancers.html 2つの チェックボックス の違いを表にまとめると下記のようになります。 比較項目 無効なHTTPヘッダーを削除 Desync 緩和モード 設定パラメータ routing.http. drop _invalid_header_fields.enabled routing.http.desync_mitigation_mode 検査対象 HTTPヘッダー HTTPリク エス ト全体 不正なHTTPヘッダーの扱い HTTPヘッダーを削除してリク エス トをターゲットに転送 HTTPリク エス トを破棄 評価順 先 後 AWS サポートからの回答をまとめると「無効なHTTPヘッダーを削除」と「Desync 緩和モード」の両方で不正と判断されるHTTPヘッダーを含むHTTPリク エス トの場合は下図のような動作イメージになるようです。 3 「Desync 緩和モード」の検証でドロップされていたHTTPリク エス トが、「無効なHTTPヘッダーを削除」を有効にすることでターゲットまで到着するような動作になることが面白いですね。 このように、「無効なHTTPヘッダーを削除」と「Desync 緩和モード」は関連が強い設定項目のようです。 5. おわりに Security Hubは導入が簡単で、サービス利用コストもあまり掛からず、人間のうっかりミスを淡々とチェックしてくれる頼もしいサービスだと思います。これから AWS のセキュリティ対策を始める方にはすごくお薦めできます。今回の記事がSecurity Hubを導入する際の参考になれば幸いです。 執筆: @yamaguchi.masahiro 、レビュー: @higa ( Shodo で執筆されました ) https://aws.amazon.com/jp/security-hub/ ↩ AWS 基礎セキュリティのベストプ ラク ティス( https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html ) ↩ 2022年2月現在のALBの動作であり、正式に公表されている仕様ではない。 ↩
こんにちは。 電通国際情報サービス (ISID) X(クロス) イノベーション 本部 ソフトウェアデザインセンター セキュリティグループの山口です。 ISIDでセキュリティの担当をしていますが、 AWS やAzure等の クラウド サービスを利用したシステム構築が一般的になり、オンプレミスでシステム構築をしていた頃よりも不用意な設定ミスによる セキュリティインシデント がより簡単に起こってしまう時代になったと感じています。 このような セキュリティインシデント を防止するための解決策の1つとして、 AWS Security Hub 1 があります。 Security Hubはセキュリティ情報を収集・チェック・評価を行うCSPM(Cloud Security Posture Management)機能を有するサービスです。 今回は、Security Hubを使っていて困ったことや不明な点を詳しく調べたことについてご紹介します。 1. Secrets Managerを使用しても警告が出る件 1.1. 対象のセキュリティ基準2 1.2. 設定方法 1.3. 疑問点 1.4.ちなみに 2. NOT_AVAILABLE 問題 2.1. 困ったこと 2.2. 解決方法 2.3. ちなみに 3. 消せないS3バケット問題 3.1. 対象のセキュリティ基準[^2] 3.2. 設定方法 3.3. 困ったこと 3.4. 解決方法 4. HTTPヘッダーの削除とDesync緩和モード 4.1. 対象のセキュリティ基準[^2] 4.2. 分からなかったこと 4.3. 確認したこと 5. おわりに 1. Secrets Managerを使用しても警告が出る件 1.1. 対象のセキュリティ基準 2 [CodeBuild.2] CodeBuild プロジェクト 環境変数 にクリアテキストの認証情報を含めることはできません これは「CodeBuild 内で AWS _ ACCESS _KEY_ID や AWS _SECRET_ ACCESS _KEY などの認証情報はプレーンテキスト(クリアテキスト)で保存しないでください。」という内容です。 1.2. 設定方法 設定はビルドプロジェクトの作成時に行えます。 設定画面を見ると下記の3つの中から選択できることが分かります。 CodeBuild.2 のアラートを検出されないようにするための正解は「パラメータ」です。 Systems Manager パラメータストアから認証情報を取得するようにできます。 プレーンテキスト(クリアテキスト) パラメータ Secrets Manager 1.3. 疑問点 プレーンテキストがセキュリティ上問題となることは分かりますが、Secrets Managerを使うのはよさそうに思えます。 ですが、実際にSecrets Managerを指定すると CodeBuild.2 でしっかりアラートが上がります。 このことを AWS サポートに問合せしましたが、Security Hubの仕様とのことでアラートを検出させたくない場合は、対象のルール(セキュリティ基準)を無効化するしかないようです。 1.4.ちなみに CodeBuildの実行環境から AWS リソースにアクセスしたい場合 AWS _ ACCESS _KEY_ID や AWS _SECRET_ ACCESS _KEY をCodeBuildの 環境変数 に設定するのではなく、CodeBuildプロジェクトのサービスロールに必要な権限を付与することで解決できます。 2. NOT_AVAILABLE 問題 2.1. 困ったこと 今回検証した環境では下図のように集約アカウントを準備して、複 数の子 アカウントの検出結果を集約アカウントで確認できるようにしました。 (Security Hubの動作イメージ) ところが一部のアカウントに対して、特定のセキュリティ基準の検出結果で「NOT_AVAILABLE」と表示されていることに気が付きました。 2.2. 解決方法 AWS サポートに問い合わせたところ、「 AWS Configに AWS リソースの設定詳細を取得するための権限が足りていないのではないか。」という回答でした。 Security Hubは AWS Configに AWS リソースのチェックを代行してもらう動作のため、 AWS Configに各種リソースへのアクセス権限が必要となります。 今回は AWS の管理ポリシー AWS_ConfigRole を AWS Configのロールに割り当てることで正常に検出結果が表示されるようになりました。 2.3. ちなみに AWS Configの設定画面から「 AWS Config サービスにリンクされたロールの作成」を選択すると AWSConfigServiceRolePolicy を含むロールが AWS Configに割り当てられます。 下記のリンクからも、分かるように AWSConfigServiceRolePolicy と AWS_ConfigRole はどちらを使用しても同じアクセス許可(2022年2月現在)となるため、その使い分けについては不明です。 https://docs.aws.amazon.com/ja_jp/config/latest/developerguide/security-iam-awsmanpol.html 3. 消せないS3 バケット 問題 3.1. 対象のセキュリティ基準[^2] [S3.5] S3 バケット は、Secure Socket Layer を使用するためのリク エス トが必要です これは「S3 バケット のポリシーで、Secure Socket Layer ( SSL ) でのアクセスを必須に設定してください。」という内容です。 3.2. 設定方法 設定はS3 バケット の バケット ポリシーで行います。 { " Id ": " ExamplePolicy ", " Version ": " 2012-10-17 ", " Statement ": [ { " Sid ": " AllowSSLRequestsOnly ", " Action ": " s3:* ", " Effect ": " Deny ", " Resource ": [ " S3 バケットの ARN ", " S3 バケットの ARN/* " ] , " Condition ": { " Bool ": { " aws:SecureTransport ": " false " } } , " Principal ": " * " } ] } 3.3. 困ったこと 普段から HTTPS でアクセスしているため、上記の設定が有効になっているかを判断できなかったので、軽い気持ちで バケット ポリシーを変更しました。 (変更前) "aws:SecureTransport": "false" (変更後) "aws:SecureTransport": "true" そうすると当然ですが、S3 バケット に対するブラウザからの HTTPS 通信は全て許可されなくなります。 あわてて元に戻そうとするも下記のように バケット ポリシー自体にもアクセスできなくなってしまいました。 3.4. 解決方法 ルートアカウントでログインすれば バケット ポリシーを削除できるようですが、権限がなかったのでCloudShellから下記のコマンドを実行して バケット ポリシーを削除しました。 aws s3api delete-bucket-policy --bucket "バケット名" --endpoint-url http://s3.ap-northeast-1.amazonaws.com 4. HTTPヘッダーの削除とDesync緩和モード 4.1. 対象のセキュリティ基準[^2] [ELB.4] HTTP ヘッダーを削除するようにアプリケーション ロードバランサー を設定する必要があります これは「HTTP desync 攻撃を防ぐために、Application Load Balancerで無効な HTTP ヘッダー値をドロップするように設定してください。」という内容です。 4.2. 分からなかったこと 「 ロードバランサー 属性の編集」画面にて「無効なHTTPヘッダーを削除」 チェックボックス をオンにすることで、セキュリティ基準はクリアできます。 ここで、画面の上にある「Desync 緩和モード」という似たような目的に思える チェックボックス があったので違いを AWS サポートに聞いてみました。 4.3. 確認したこと 前提として、Desync 緩和モードは下記のURLにあるように、リク エス トの分類とALBのモード設定に基づいて動作が決定します。 詳細は下記のURLをご覧ください。 https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/application-load-balancers.html 2つの チェックボックス の違いを表にまとめると下記のようになります。 比較項目 無効なHTTPヘッダーを削除 Desync 緩和モード 設定パラメータ routing.http. drop _invalid_header_fields.enabled routing.http.desync_mitigation_mode 検査対象 HTTPヘッダー HTTPリク エス ト全体 不正なHTTPヘッダーの扱い HTTPヘッダーを削除してリク エス トをターゲットに転送 HTTPリク エス トを破棄 評価順 先 後 AWS サポートからの回答をまとめると「無効なHTTPヘッダーを削除」と「Desync 緩和モード」の両方で不正と判断されるHTTPヘッダーを含むHTTPリク エス トの場合は下図のような動作イメージになるようです。 3 「Desync 緩和モード」の検証でドロップされていたHTTPリク エス トが、「無効なHTTPヘッダーを削除」を有効にすることでターゲットまで到着するような動作になることが面白いですね。 このように、「無効なHTTPヘッダーを削除」と「Desync 緩和モード」は関連が強い設定項目のようです。 5. おわりに Security Hubは導入が簡単で、サービス利用コストもあまり掛からず、人間のうっかりミスを淡々とチェックしてくれる頼もしいサービスだと思います。これから AWS のセキュリティ対策を始める方にはすごくお薦めできます。今回の記事がSecurity Hubを導入する際の参考になれば幸いです。 執筆: @yamaguchi.masahiro 、レビュー: @higa ( Shodo で執筆されました ) https://aws.amazon.com/jp/security-hub/ ↩ AWS 基礎セキュリティのベストプ ラク ティス( https://docs.aws.amazon.com/ja_jp/securityhub/latest/userguide/securityhub-standards-fsbp-controls.html ) ↩ 2022年2月現在のALBの動作であり、正式に公表されている仕様ではない。 ↩
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報3/8いってみようか。 非常時の暗号資産 非常時の暗号資産のニュース Web3 Web3のニュース その他のニュース 非常時の暗号資産 ロシアも ウクライナ も暗号資産を活用していますね。特にロシアにおいては、制裁回避の意味合いが強そうです。暗号資産の特定の中央集権組織に管理されていないという特徴が実感できますね。 暗号資産と言ってもCEX(中央集権型の取引所)の場合(例えばCoinbase)は、特定の組織が管理しているので、規制することも可能です。しかし、単なる送金なら取引所を通さずWalletだけで実現できます。 もともと Bitcoin は規制されない通貨として設計されてますからね。 通常、 中央銀行 によって発行された通貨は国境を越えるのに、時間と高額な手数料がかかります。それに対し、暗号資産は国境の概念がないので、どんな送金も同じ扱いになります。 非常時の暗号資産のニュース ロシアが「暗号通貨で制裁回避」の可能性、専門家が警告 ウクライナ情報変革副大臣インタビュー「IT軍団と29億円相当の暗号資産による寄付」について語る クレカ事業停止 暗号資産規制も対ロ制裁で金融包囲網 Web3 Alchemy(アルケミー)が2億ドル(約232億円)のシリーズC1資金調達ラウンドをクローズし、同社の 企業価値 は110億2000万ドル(約1兆2760億円)となりました。 Alchemyは、Web3プロジェクトのためのインフラを提供していて、 AWS のWeb3版と言われています。 ゴールドラッシュで儲けたのは、金鉱掘りではなく、ツルハシ売りだと言われています。Web3という金鉱を掘り当てようとしている人に、ツルハシを売るのはとても賢い戦略だと思います。 ゴールドラッシュ教訓 一番儲かった人、金鉱掘りそれともツルハシ売り? Web3のニュース Web3サイト構築デベロッパーの事実上の標準プラットフォームを目指すAlchemyの評価額が約1兆2760億円に その他のニュース 米国政府はドル支配を維持するためにステーブルコインを受け入れなければならない グリーンとは正反対… ビットコインマイナーアメリカ移住で化石燃料消費アップ NVIDIAを攻撃のハッキンググループLapsus$、「イーサリアムのマイニング制限回避ツールを1億円以上で買い取れ」と脅迫か 執筆: @higa ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの 比嘉康雄 です。 それでは、 ブロックチェーン 週報3/8いってみようか。 非常時の暗号資産 非常時の暗号資産のニュース Web3 Web3のニュース その他のニュース 非常時の暗号資産 ロシアも ウクライナ も暗号資産を活用していますね。特にロシアにおいては、制裁回避の意味合いが強そうです。暗号資産の特定の中央集権組織に管理されていないという特徴が実感できますね。 暗号資産と言ってもCEX(中央集権型の取引所)の場合(例えばCoinbase)は、特定の組織が管理しているので、規制することも可能です。しかし、単なる送金なら取引所を通さずWalletだけで実現できます。 もともと Bitcoin は規制されない通貨として設計されてますからね。 通常、 中央銀行 によって発行された通貨は国境を越えるのに、時間と高額な手数料がかかります。それに対し、暗号資産は国境の概念がないので、どんな送金も同じ扱いになります。 非常時の暗号資産のニュース ロシアが「暗号通貨で制裁回避」の可能性、専門家が警告 ウクライナ情報変革副大臣インタビュー「IT軍団と29億円相当の暗号資産による寄付」について語る クレカ事業停止 暗号資産規制も対ロ制裁で金融包囲網 Web3 Alchemy(アルケミー)が2億ドル(約232億円)のシリーズC1資金調達ラウンドをクローズし、同社の 企業価値 は110億2000万ドル(約1兆2760億円)となりました。 Alchemyは、Web3プロジェクトのためのインフラを提供していて、 AWS のWeb3版と言われています。 ゴールドラッシュで儲けたのは、金鉱掘りではなく、ツルハシ売りだと言われています。Web3という金鉱を掘り当てようとしている人に、ツルハシを売るのはとても賢い戦略だと思います。 ゴールドラッシュ教訓 一番儲かった人、金鉱掘りそれともツルハシ売り? Web3のニュース Web3サイト構築デベロッパーの事実上の標準プラットフォームを目指すAlchemyの評価額が約1兆2760億円に その他のニュース 米国政府はドル支配を維持するためにステーブルコインを受け入れなければならない グリーンとは正反対… ビットコインマイナーアメリカ移住で化石燃料消費アップ NVIDIAを攻撃のハッキンググループLapsus$、「イーサリアムのマイニング制限回避ツールを1億円以上で買い取れ」と脅迫か 執筆: @higa ( Shodo で執筆されました )
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 最近、Rustにさわり始めたので Windows ユーザー向けの開発環境を構築する手順をご紹介します。 前回書いた Gitワークフロー設計について という記事は重厚でしたが、今回は軽めです。 Microsoftの用意している手順通りにインストールする Microsoft C++ Build Tools と Visual Studioのどちらをインストールするのか? VS Codeで使えるRust用拡張は複数あるが? デバッガーは何を使えばいい? デバッグしてたらマシン語みたいなものが出てきた デバッグ時にソースコードをアタッチする方法 デバッグビューからの起動にソースコードをアタッチする方法 さいごに 追記:rust-analyzer は Rust 公式になりそうです。 Microsoft の用意している手順通りにインストールする 基本的には、以下のページに書いてある通り手順を進めていけば開発環境を構築できます。 Windows で Rust 用の開発環境を設定する このページを読んで分かり辛い部分を補足します。 Microsoft C++ Build Tools と Visual Studio のどちらをインストールするのか? Microsoft C++ Build Tools をインストールしてください。 VS Code で使えるRust用拡張は複数あるが? rust-analyzer と Rust support for Visual Studio Code という二つの拡張があります。 Rust公式なのはRust support for Visual Studio Code ですが、開発が活発でより多機能なのはrust-analyzerです。 つまり、rust-analyzerがおすすめです。 rust-analyzerは VS Code 拡張とLSPサーバの実装が単一のgit リポジトリ に入っています https://github.com/rust-analyzer/rust-analyzer Rust support for Visual Studio Code は VS Code 拡張とLSPサーバの実装が別な リポジトリ になっています。 https://github.com/rust-lang/vscode-rust https://github.com/rust-lang/rls デバッガーは何を使えばいい? デバッグ したいなら CodeLLDB がおすすめです。 デバッグ してたら マシン語 みたいなものが出てきた こういうのが画面に出力されたらびっくりしますよね。分かります。 これを解決するための手順をこの後で説明します。 デバッグ 時に ソースコード をアタッチする方法 まずは、rustの標準ライブラリが置いてある ディレクト リを調べます。 rustup show を実行してみましょう。筆者の環境では以下のように出力されました。 Default host: x86_64-pc-windows-msvc rustup home: C:\Users\taichi\scoop\persist\rustup-msvc\.rustup stable-x86_64-pc-windows-msvc (default) rustc 1.57.0 (f1edd0429 2021-11-29) rustup home と (default) が末尾に付いているtoolchain名を後で使います。 次にライブラリのバージョンとコミットハッシュを調べるために、 rustc --version --verbose を実行します。筆者の環境では以下のように出力されました。 rustc 1.57.0 (f1edd0429 2021-11-29) binary: rustc commit-hash: f1edd0429582dd29cccacaf50fd134b05593bd9c commit-date: 2021-11-29 host: x86_64-pc-windows-msvc release: 1.57.0 LLVM version: 13.0.0 ここで使うのは、 commit-hash ですね。この例では f1edd0429582dd29cccacaf50fd134b05593bd9c となっていますね。 そして ワークスペース の設定をするために .vscode/settings.json を作成します。 { " lldb.launch.sourceMap ": { " /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c ": " C: \\ Users \\ taichi \\ scoop \\ persist \\ rustup-msvc \\ .rustup \\ toolchains \\ stable-x86_64-pc-windows-msvc \\ lib \\ rustlib \\ src \\ rust " } } lldb.launch.sourceMap が ソースコード をアタッチするための設定項目です。この設定項目ではキー部分に、アタッチしたい ソースコード の 名前空間 を設定します。そして、値部分に ソースコード の 絶対パス を設定します。 今回のケースでは標準ライブラリに ソースコード をアタッチしようとしています。 /rustc/ が プレフィックス で、その後ろにコミットハッシュである f1edd0429582dd29cccacaf50fd134b05593bd9c を連結していますね。 ソースコード の 絶対パス は 先ほど調べた rustup home に .rustup\\toolchains 、そして toolchain名 、末尾に lib\\rustlib\\src\\rust を連結しています。 ここまでの説明を図にするとこうなります。 筆者の環境は日本語 Windows なのでファイルパスの区切り文字はエンサインです。そのまま JSON に書いてしまうと期待通りの値にならないので、エンサインを重ねて エス ケープしています。 ここまで設定したら、 ソースコード 上に表示された Debug をクリックして デバッグ 実行できます。 デバッグ ビューからの起動に ソースコード をアタッチする方法 CodeLLDBには デバッグ を開始する方法が二つ用意されています。一つ目は、既に説明した方法です。 これから説明するのは、 VS Code の デバッグ ビューから実行する方法です。 まずは、CodeLLDBの機能を使ってlaunch. json を自動生成しましょう。 この Run and Debug ボタンを押すとモーダルダイアログが2回程出力されますので、それぞれOKとYesを押してください。 出力されたlaunch. json の中から説明に必要な部分だけを抜粋したのが、以下の JSON です。 { " type ": " lldb ", " request ": " launch ", " name ": " Debug executable 'learn-rust' ", " cargo ": { " args ": [ " build ", " --bin=learn-rust ", " --package=learn-rust " ] , " filter ": { " name ": " learn-rust ", " kind ": " bin " } } , " args ": [] , " cwd ": " ${workspaceFolder} " } ワークスペース のルート ディレクト リにあるCargo.tomlの内容次第で詳細は違うでしょうが、似たようなファイルが作成されれているはずです。 この JSON に sourceMap というキーで先ほど設定したのと同じ値を設定したものがこれです。 { " type ": " lldb ", " request ": " launch ", " name ": " Debug executable 'learn-rust' ", " cargo ": { " args ": [ " build ", " --bin=learn-rust ", " --package=learn-rust " ] , " filter ": { " name ": " learn-rust ", " kind ": " bin " } } , " args ": [] , " cwd ": " ${workspaceFolder} ", " sourceMap ": { " /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c ": " C: \\ Users \\ taichi \\ scoop \\ persist \\ rustup-msvc \\ .rustup \\ toolchains \\ stable-x86_64-pc-windows-msvc \\ lib \\ rustlib \\ src \\ rust " } } このように設定した上で、 デバッグ ビューの デバッグ 開始ボタンを押すと標準ライブラリに ソースコード がアタッチされた状態で デバッグ できます。 さいごに Rustで快適に デバッグ する環境ができましたと言えれば、非常に良いのですが、実はまだ課題があります。 デバッグ 実行時に日本語を標準出力するといわゆる文字化け状態になってしまいます。 デバッグ 実行しなければ文字化けしないので、恐らくCodeLLDBの問題であろうと類推しているのですが、上手く解決できていません。 解決方法をご存じの方がいらっしゃったら是非共有してくださると非常にありがたいです。 追記:rust-analyzer は Rust 公式になりそうです。 rust-analyzer joins the Rust organization! 執筆: @sato.taichi 、レビュー: @mizuno.kazuhiro ( Shodo で執筆されました )
みなさんこんにちは、 電通国際情報サービス (ISID)X イノベーション 本部ソフトウェアデザインセンターの佐藤太一です。 最近、Rustにさわり始めたので Windows ユーザー向けの開発環境を構築する手順をご紹介します。 前回書いた Gitワークフロー設計について という記事は重厚でしたが、今回は軽めです。 Microsoftの用意している手順通りにインストールする Microsoft C++ Build Tools と Visual Studioのどちらをインストールするのか? VS Codeで使えるRust用拡張は複数あるが? デバッガーは何を使えばいい? デバッグしてたらマシン語みたいなものが出てきた デバッグ時にソースコードをアタッチする方法 デバッグビューからの起動にソースコードをアタッチする方法 さいごに 追記:rust-analyzer は Rust 公式になりそうです。 Microsoft の用意している手順通りにインストールする 基本的には、以下のページに書いてある通り手順を進めていけば開発環境を構築できます。 Windows で Rust 用の開発環境を設定する このページを読んで分かり辛い部分を補足します。 Microsoft C++ Build Tools と Visual Studio のどちらをインストールするのか? Microsoft C++ Build Tools をインストールしてください。 VS Code で使えるRust用拡張は複数あるが? rust-analyzer と Rust support for Visual Studio Code という二つの拡張があります。 Rust公式なのはRust support for Visual Studio Code ですが、開発が活発でより多機能なのはrust-analyzerです。 つまり、rust-analyzerがおすすめです。 rust-analyzerは VS Code 拡張とLSPサーバの実装が単一のgit リポジトリ に入っています https://github.com/rust-analyzer/rust-analyzer Rust support for Visual Studio Code は VS Code 拡張とLSPサーバの実装が別な リポジトリ になっています。 https://github.com/rust-lang/vscode-rust https://github.com/rust-lang/rls デバッガーは何を使えばいい? デバッグ したいなら CodeLLDB がおすすめです。 デバッグ してたら マシン語 みたいなものが出てきた こういうのが画面に出力されたらびっくりしますよね。分かります。 これを解決するための手順をこの後で説明します。 デバッグ 時に ソースコード をアタッチする方法 まずは、rustの標準ライブラリが置いてある ディレクト リを調べます。 rustup show を実行してみましょう。筆者の環境では以下のように出力されました。 Default host: x86_64-pc-windows-msvc rustup home: C:\Users\taichi\scoop\persist\rustup-msvc\.rustup stable-x86_64-pc-windows-msvc (default) rustc 1.57.0 (f1edd0429 2021-11-29) rustup home と (default) が末尾に付いているtoolchain名を後で使います。 次にライブラリのバージョンとコミットハッシュを調べるために、 rustc --version --verbose を実行します。筆者の環境では以下のように出力されました。 rustc 1.57.0 (f1edd0429 2021-11-29) binary: rustc commit-hash: f1edd0429582dd29cccacaf50fd134b05593bd9c commit-date: 2021-11-29 host: x86_64-pc-windows-msvc release: 1.57.0 LLVM version: 13.0.0 ここで使うのは、 commit-hash ですね。この例では f1edd0429582dd29cccacaf50fd134b05593bd9c となっていますね。 そして ワークスペース の設定をするために .vscode/settings.json を作成します。 { " lldb.launch.sourceMap ": { " /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c ": " C: \\ Users \\ taichi \\ scoop \\ persist \\ rustup-msvc \\ .rustup \\ toolchains \\ stable-x86_64-pc-windows-msvc \\ lib \\ rustlib \\ src \\ rust " } } lldb.launch.sourceMap が ソースコード をアタッチするための設定項目です。この設定項目ではキー部分に、アタッチしたい ソースコード の 名前空間 を設定します。そして、値部分に ソースコード の 絶対パス を設定します。 今回のケースでは標準ライブラリに ソースコード をアタッチしようとしています。 /rustc/ が プレフィックス で、その後ろにコミットハッシュである f1edd0429582dd29cccacaf50fd134b05593bd9c を連結していますね。 ソースコード の 絶対パス は 先ほど調べた rustup home に .rustup\\toolchains 、そして toolchain名 、末尾に lib\\rustlib\\src\\rust を連結しています。 ここまでの説明を図にするとこうなります。 筆者の環境は日本語 Windows なのでファイルパスの区切り文字はエンサインです。そのまま JSON に書いてしまうと期待通りの値にならないので、エンサインを重ねて エス ケープしています。 ここまで設定したら、 ソースコード 上に表示された Debug をクリックして デバッグ 実行できます。 デバッグ ビューからの起動に ソースコード をアタッチする方法 CodeLLDBには デバッグ を開始する方法が二つ用意されています。一つ目は、既に説明した方法です。 これから説明するのは、 VS Code の デバッグ ビューから実行する方法です。 まずは、CodeLLDBの機能を使ってlaunch. json を自動生成しましょう。 この Run and Debug ボタンを押すとモーダルダイアログが2回程出力されますので、それぞれOKとYesを押してください。 出力されたlaunch. json の中から説明に必要な部分だけを抜粋したのが、以下の JSON です。 { " type ": " lldb ", " request ": " launch ", " name ": " Debug executable 'learn-rust' ", " cargo ": { " args ": [ " build ", " --bin=learn-rust ", " --package=learn-rust " ] , " filter ": { " name ": " learn-rust ", " kind ": " bin " } } , " args ": [] , " cwd ": " ${workspaceFolder} " } ワークスペース のルート ディレクト リにあるCargo.tomlの内容次第で詳細は違うでしょうが、似たようなファイルが作成されれているはずです。 この JSON に sourceMap というキーで先ほど設定したのと同じ値を設定したものがこれです。 { " type ": " lldb ", " request ": " launch ", " name ": " Debug executable 'learn-rust' ", " cargo ": { " args ": [ " build ", " --bin=learn-rust ", " --package=learn-rust " ] , " filter ": { " name ": " learn-rust ", " kind ": " bin " } } , " args ": [] , " cwd ": " ${workspaceFolder} ", " sourceMap ": { " /rustc/f1edd0429582dd29cccacaf50fd134b05593bd9c ": " C: \\ Users \\ taichi \\ scoop \\ persist \\ rustup-msvc \\ .rustup \\ toolchains \\ stable-x86_64-pc-windows-msvc \\ lib \\ rustlib \\ src \\ rust " } } このように設定した上で、 デバッグ ビューの デバッグ 開始ボタンを押すと標準ライブラリに ソースコード がアタッチされた状態で デバッグ できます。 さいごに Rustで快適に デバッグ する環境ができましたと言えれば、非常に良いのですが、実はまだ課題があります。 デバッグ 実行時に日本語を標準出力するといわゆる文字化け状態になってしまいます。 デバッグ 実行しなければ文字化けしないので、恐らくCodeLLDBの問題であろうと類推しているのですが、上手く解決できていません。 解決方法をご存じの方がいらっしゃったら是非共有してくださると非常にありがたいです。 追記:rust-analyzer は Rust 公式になりそうです。 rust-analyzer joins the Rust organization! 執筆: @sato.taichi 、レビュー: @mizuno.kazuhiro ( Shodo で執筆されました )
電通国際情報サービス 、クロス イノベーション 本部、オープン イノベーション ラボの比嘉です。 ブロックチェーン 週報3/1いってみようか。今週から基本、火曜日に出すことにしました。 Web3 Web3のニュース PoWへの批判 PoWへの批判のニュース その他の記事 Web3 前回 、Web3とは、サービスの運営者(中央管理者)がサービスを独占せず、ユーザーもサービスの運営に関われるようなサービスのことだという話をしました。 これだとまだ抽象的なので、イメージがわかないでしょう。 DeSciの記事がWeb3の流れそのものなので、記事を見た上で僕の説明を読むとWeb3が理解できるんじゃないかと思います。 DeSciを求める科学者の背景 ver 1.0 科学者は、自分の研究や論文が多くの人たちに役立てられることを望んでいます。しかし、力の強い出版社がいるので、それがかないません。 研究にはお金がかかりますがその調達も難しくなっています。 だから、自分たちの研究が多くの人に役立てられるようなプラットフォームを望んでいます。資金調達がしやすくなることも望んでいます。 Web3は、音楽がわかりやすいので、音楽にたとえます。 アーティストは、自分の音楽を多くの人に聞いてほしいと思っています。 しかし、力の強いレーベルがいるのでそれがかないません。 レーベルが売れると思った曲しか世に出ないので、自分の自由に音楽を世に出すこともできないのです。 音楽業界では、売上のうちアーティストに払われる割合は、わずか12%です。プラットフォームやレーベルが残りを全部持っていきます。 アーティストは自由に曲を発表でき、ファンに聞いてもらえるようなプラットフォームを望んでいます。そして、そのプラットフォームから活動資金を得ることを望んでいます。プラットフォームやレーベルが過剰にお金をとっていくことは望んでいません。 ほとんど構造は一緒です。科学者やアーティストが自分のやりたいことをできないのは、強い出版社や強いレーベル/ストリーミングプラットフォームがあるからです。 「そこを排除して、サービスを自分たちの手に取り戻し、活動資金も調達しやすくしたい」この動きがWeb3なんじゃないかと思います。 Web3のニュース 「YouTubeの将来を語るうえでメタバースに触れないわけにはいきません」YouTubeがメタバース参入検討、Web3も示唆 カニエ・ウエストの最新アルバム『Donda 2』は専用プレイヤーのみで販売。配信はされません! 技術的にはWeb3とは無関係ですが、アーティストが音楽を自分で管理しようとするWeb3的な動きです。 PoWへの批判 PoWとは、Proof of Workの略で、 Bitcoin やEthereumで使われている仕組みで、ブロックを生成するときに解くのに時間がかかる暗号問題を解く必要があります。 PoWにおける電気消費量が多く、環境に優しくないと批判されています。この批判の声がより大きくなってきました。 PoWへの批判のニュース テスラ取締役のキンバル・マスク氏、同社がビットコインを購入した際の環境影響について「無知だった」と発言 EUがビットコインを禁止へ! 法案では、2025年初から、EU内ではビットコインに関するすべてのサービスは違法となる。PoWで電力を浪費し、「環境にやさしくない」のが禁止の理由のよう。 その他の記事 三菱 UFJ 信託銀行: 優待等を対象とした NFT「Progmat UT」及びデジタルアセット用ウォレットサービスの開発について NFTを破棄するとネガフィルムがもらえる。コロナ禍の東京を写したメタバース写真展 MUFG、ブロックチェーン活用の次世代決済事業を1年で停止へ 執筆: @higa 、レビュー: @sato.taichi ( Shodo で執筆されました )