くろおーかみ*てっく

しがないくろおーかみの勉強記

Storybook 5.3以降に採用されている ./storybook/preview.js でBulmaのCSSをimportしようとしたらpostcss-loaderのエラーが出る

TL;DR

Storybookで表示しているVueコンポーネント全部にBulmaのCSSを適用させたい。

Storybook 5.3から採用された ./storybook/preview.js にBulmaのCSSを読み込ませようとすると、
postcss-loaderのエラーでStorybookが起動しない。

./storybook/preview.js

import './storybook/bulma/css/bulma.css'

Storybook 5.3から採用された設定ファイルに合わせたい

Storybook 5.3からファイル構成が変わるとのことなので、Storybookで管理しているコンポーネントCSSを共通して適用させる方法を調べていました。

Declarative Storybook configuration - Storybook - Medium. https://medium.com/storybookjs/declarative-storybook-configuration-49912f77b78

CSSフレームワークに依存したコンポーネントをStorybookでもみたい、というユースケースです。
Vue/NuxtでCSSフレームワークを採用しても、ご存知のとおりWebpackが別物になっているためStorybookでは反映されません。

共通CSSを適用したコンポーネントの中にねじ込む方法

Storybook 5.2を使っていたときは addDecorator を用いて、BulmaのSASSを読み込んだVueコンポーネントに無理やりStoryを入れる方法を採っていました。

tacamy.hatenablog.com

共通のスタイルを適用できるようにする

qiita.com

しかし、Storybook内でCSSは適用されるものの 読み込んだはずのコンポーネントが"Unknown custom element"になるなど
無理矢理感の強い方法だったので「なんとかできないか」と思いました。

[Vue warn]: Unknown custom element: - did you register the component correctly? For recursive components, make sure to provide the "name" option.

CSSをWebpackで読み込む方法を試す

Storybook 5.2以前の ./storybook/config.js に読み込みたいCSSを指定して、対応するWebpackのloaderを呼び出せば実現する例があります。

qiita.com

そこで、Storybook 5.3以降に対応させたWebpackの設定と ./storybook/preview.jsCSSを読み込ませようとしました。

/storybook/main.js

const path = require('path');
module.exports = {
  stories: ['../components/**/*.stories.js'],
  addons: ['@storybook/addon-actions', '@storybook/addon-links'],
  webpackFinal: async (config, { configType }) => {
    config.resolve.alias['@'] = path.resolve(__dirname, '../')
    config.module.rules.push({
      test  : /\.css$/,
      loader : ['style-loader', 'css-loader'],
    },);
    return config;
  },
};

./storybook/preview.js

import './storybook/bulma/css/bulma.css'

…が、できなかった

postcss-loaderのエラーについて調べると、 loader の順序を変えるとか複数回loadしようとしているとか出ますが、そこをいじっても全く改善されません。

これで1時間ぐらい溶けました。あんまり本質的じゃないところなのにー

ERROR in ./node_modules/bulma/css/bulma.css (./node_modules/css-loader/dist/cjs.js??ref--3-1!./node_modules/postcss-loader/src??postcss!./node_modules/style-loader/dist/cjs.js!./node_modules/css-loader/dist/cjs.js!./node_modules/postcss-loader/src!./node_modules/bulma/css/bulma.css) Module build failed (from ./node_modules/postcss-loader/src/index.js): SyntaxError

(1:1) Unknown word

1 | var api = require("!../../style-loader/dist/runtime/injectStylesIntoStyleTag.js"); | ^ 2 | var content = require("!!../../css-loader/dist/cjs.js!../../postcss-loader/src/index.js!./bulma.css"); 3 |

まだ調べています

解決法がございましたら教えていただけると助かります🙇‍♂️
見つかり次第 体が持ったら 追記します。

WEBエンジニア勉強会 #14 (東京都, 泉岳寺) に参加しました #WEM14

今日は勉強会に参加したので、レポートを書きます✨

マイクロサービスやGoogle App Engineで高速開発するお話があったのがきっかけです。

web-engineer-meetup.connpass.com

もくじ

前座

speakerdeck.com

お肉おいし〜い 環境問題から発展した?Fake Meatについてです🍖

何故マイクロサービスにするんだっけ? (スポンサーセッション) @suke_masa

speakerdeck.com

直近でマイクロサービスの話が出てきたので気になりました!

  • マイクロサービスにしたから疎結合になるのではなく、 疎結合に作る必要がある
  • マイクロサービス化は大変なので そもそも頻繁な変更が必要かどうか探る
  • マイクロサービス化するには多数の技術と「テストから始める」開発方法に転換する必要がある

マイクロサービスを導入するかカンタンに判断するポイントが載っていてよかったです!

失敗例から知るサーバレス ~ APIGateway Lambda編 ~ (10分) @pal_of_pome

www.slideshare.net

サーバレスを用いてシステムを提案して失敗する話です😅

サーバレスを導入するときは次のポイントを考えましょう。 分かりづらい仕様とかに悩まされたなぁ

  • サーバレスは安くならない
  • サーバレスに精通していないと(上限とかに)引っかかる
  • サーバーレスにすることが目的ではないですか

愛されるダッシュボードの作り方 (10分) @ikedaosushi

speakerdeck.com

最初はワクワクするけども、全く使われないダッシュボードが生まれるのがよくある…話

ダッシュボードを長く使ってもらうには次のポイントを挙げていました

アジャイル好きのウォーターフォール (10分) @takeki1967

speakerdeck.com

SchemaSpyなどのツールを使いウォーターフォールの各作業(データベース設計書・テスト設計)をコードで解決するお話で、
辛い作業を楽しい作業に置き換えることを目指しているそうです✨

MDX-Deck v3 と Code-Surfer v3 (10分) @natural_clar

code-surfer-v3.naturalclar.now.sh

MDX-Deck/Code Surferのアップデートについてで、MDX-Deckについては別のスライドに譲っていますが、

_人人人人人人人人人人人人人人人人_  
> 楽しいスライドを楽に作ろう! <  
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄  

コレに尽きます。

#コードをスライドに載せる Code-Surfer で Diffがアニメーションでわかる などのアップデートがあったそうです

GAEによるPythonWEBアプリケーションの高速開発 (10分) @shimakaze_soft

*資料を探しています…

  • GAE(Google App Engine)を使えばPythonのWebアプリが高速に開発できるよ!!
  • ECSよりも価格が安い!!

とのことですが、デプロイが3-10分かかる点が辛いとのこと。

テーマ確認中 (10分) @yu__ya4

機械学習の論文を紹介: How Can They Know That? A Study of Factors Affecting the Creepiness of Recommendations

*資料を探しています…

今日発表だということを今日知って 昼頃に読んだ論文を紹介!という技で発表されています。

性能が高すぎるRS(推薦システム)はユーザーのネガティブな感情(Creepiness)を買うのでは? というポイントについて調査した論文になります。
ネガティブな感情として例えば推薦システムが的確に推薦しすぎて "なんでわかるの?????" とユーザーが思うこと などが挙げられます。

#一度表示してしまうとしつこく推薦しようとするシステムはどのようにCreepinessがあるのか気になります

まとめ・所感

主催の方から「ジョークが少ない真面目な発表だな?!」というコメントがありましたが…
#2回目の参加なのでジョークたっぷりなところはあまり知らないかもしれません

マイクロサービスについてわかりやすい発表があり、その他にもMDX-DeckやSchemaSpyについて知ることができました!
また、実際に開発しているところを示していて、後に試しやすい・使いやすい発表もありました!

\ 勉強会の皆様、ありがとうございました! /

# 100DaysOfCode #30: Python(requests)でQiita API認証情報の有/無をよしなに処理する

やったこと (1h)

今日の進捗のコードはコチラ。

github.com

(Qiitaにまとめていますが)
Qiita APIは空のリクエストヘッダーを受け付けるので、 認証情報があれば空のリクエストヘッダーに値を入れるだけ、というカンタンなものです。

記事では認証情報を作るところから話しています。

qiita.com

# 100DaysOfCode #29: QiitaのAPIでユーザー名からTwitter/GitHubのユーザー名を取り出す

やったこと(1h)

今日の進捗のコードはコチラ。

github.com

Qiita APIでプロフィールを取得する!(認証不要)

https://qiita.com/api/v2/users/の後にQiitaのユーザーID(@で始まるやつです)を入れると、Qiitaのプロフィールページで見られるような情報が取得できます。

qiita.com

情報の取得にユーザー登録は必要ありません。

認証してもっとAPIを使う(60回/h -> 1,000回/h)

登録しないと (同一IPアドレスで)1時間に60回しか使えないため ユーザー登録をしてアプリケーションのIDを requests.get() と一緒に設定しましょう。

登録すると1IDにつき1,000回/1時間のレートで使うことができます。

「残り何回まで使えるのか」などレートに関わる情報は、取得した情報にくっついてくるレスポンスヘッダーに書いてあって、 requests.get() した結果の headers から確認できます。

 result = requests.get(api_url)
 print('残り {} 回 / {}'.format(result.headers['rate-remaining'], result.headers['rate-limit']))

qiita.com

感想

その中にOrganizationsのユーザーページでは出なかったTwitter/GitHubのユーザーIDがこのAPIで取得できます。
これからTwitterGitHubのアクティビティも加味して どれくらい活動しているか を調べてみたいものです。

# 100DaysOfCode #28: 自動でページをめくって取得する(BeautifulSoup + requests)

やったこと

  • すべてのユーザーを取得する(1h)

今日の進捗のコードはコチラ。

github.com

とりあえず1ページ目を取り出してから、パラパラと次のページをめくって気づいたことをまとめましょう。
次のページへ遷移するページネーションを見ると rel 属性で「次のページを表示するボタン」が示されています。

BeautifulSoupでは find() で要素が見つからなかったら None が返ってくるので、 ページを取得するたびに「次のページを表示するボタン」を探してすべてのユーザーの名前を取り出します。

# 100DaysOfCode #27: QiitaのOrganizations内ユーザーの取得/canvas要素をPNG化

やったこと

QiitaのOrganizations内で 誰が一番活動しているのか どれくらい頑張っているのか が知りたくて調べています(2h)

集計結果をHTMLで出せばWebフロントエンドにも関われる…はず。

今日の進捗のコードはコチラ。

Qiita内で特定のOrganizationsに所属しているユーザー一覧 例えばこちら を取得するAPIが無いため、ページのHTMLを取得して取り出しています(いわゆるスクレイピング

github.com

十数行しかないため、コチラにも貼り付けますが

  • requests でHTMLを取得して
  • BeautifulSoup でHTMLからユーザー名を取り出す

手順になります。

ユーザー名の部分は開発者ツールで要素/id/classを調べましょう

import requests
from bs4 import BeautifulSoup

# Organizationsのユーザーでとりあえず1ページ目を取り出す
o_s = requests.get("https://qiita.com/organizations/opst/members")

# ページ全体をBeautifulSoup
o_soup = BeautifulSoup(o_s.text, features="html.parser")

# メンバー表示部を選択
member = o_soup.find("ul", attrs={"class", "p-organization_memberlist"})

# メンバーのリストを取得
member_list = member.find_all("div", attrs={"class", "od-MemberCardContent"})

# メンバーの名前を出してみる
for m in member_list:
    name = m.contents[0].find("strong", attrs={"class", "od-MemberCardHeaderIdentities_username"}).contents
    print(name)

ピックアップ

今の作業には関係ないけど、次以降のネタで関わってくるものについて…

canvas要素をPNG化: toDataURL()

Twitterで映える?OGP画像を作るにはcanvas 要素で toDataURL() メソッドを使う。

toDataURL() を呼ぶと Base64になったPNGが出てくるので、 ごにょごにょしてその画像を保存・配信までもっていくとOGP画像を生み出すサービスになるらしい。

#ブラウザにある開発者ツールのConsoleで任意の canvasPNGにすることができました。

qiita.com

シェアするOGP画像はクライアントで生成・アップロードしているのかな?

#100DaysOfCode に失敗…したので8/7から#27にします

「手が回らなくなった」といえばそれまでだけど

  • そもそも途中で手を付けていない
  • 1日の作業が「表示してみただけ」など小さい

問題を抱えています。

今の段階ではVue.jsのチュートリアルを進めているので、 新しい技術に触れて/技術書を読んで実践したことを残すことを考えると 今のままではダメだということです

今の段階の 言い訳 問題と対策を考えてまとめました。

1. やり始めるときに「この時間が来たら終わらせる」という指定がなかった

  • チュートリアルであれば「この章まで終わらせてから」と決めて遅くまで作業してしまう
  • 「今日はどこまでやればいいのだろう」と見当がつかなくなる
  • 結果やり始めることにネガティブになってしまう…

そこで、 コードを書く時間は「ここまで」と時間制限を決める ことにしました。

2. 土曜・日曜に作業を始めることができなかった

休日は「この時間にやる」と決めていなかったので、プライベートで用事があるとそのまま力尽きてコードを書き始められませんでした。

これは「決めてください」ということでカレンダーに入れました。

3. ずっとチュートリアルをやり続けていいだろうか

これはどうすればいいのかわかりませんでした。

「Vueの基本を抑えておきたい」とVueのドキュメントで紹介されているセクション全てについてコードを書こうとしましたが、
オリジナルのコードに落とし込むレベルまで、となると理解するのは少し難しく 時間がかかります。

また「このまま作品ができなくてもいいのか」という誘惑があります。

作品のネタは書き溜めているのですが、そこから取り出すのも頭が一杯で……
一旦休んで頭の中をクリアにする必要があるのかな。

#あれ、ポートフォリオAdobe XDでコードを書いていないときはPaizaをやるのでは

4. ブログを書き始める障壁を減らす必要がある

Notion にテンプレートとリンクを用意してはあったのですが、 上記で頭が一杯になるとそれすら億劫になります

f:id:y-mix:20190812232110p:plain
Notionに貼り付けたテンプレート

  1. #100DaysOfCode の記事用にテンプレートをMarkdown形式で作り、CodeブロックとしてNotionのページに追加する
  2. Copy to Clipboard をクリックする
  3. Write! のリンクをクリックして記事作成画面へ、そして貼り付けて作業開始

コマンド一つでできないかな?

コマンド一つでテンプレートから下書きまですすめるようにして、 open (masOS) コマンドなどで記事投稿画面を開かせようかと考えています。

#100DaysOfCode の小さいプロジェクトごとにブランチを、作業日時ごとにTagを設定している状態なので

  1. コミットする
  2. 作業終了のコマンドを実行する
    1. 日付を入力して(深夜0時を超えて作業すると翌日扱いになるため)
    2. 日付を元にTagをセット & Push
    3. TagとブランチからGitHubのURLを取得してテンプレートに流し込む
    4. はてなブログAPIを叩き 下書き保存 で送信する
    5. 下書きされた記事をmacOSopen コマンドで開く

妄想 構想でいます。

5. やっぱり記事にこだわりすぎている

考えるの遅いくせにあれもこれも盛り込みたくなるの…

さいごに

始まったばかりなので、やり方直して進めてみます💦

もったいないので #27 から続けます。
「"連続しなかったからもうだめだー"と考えないことです」#100DaysOfCode の記事に書いてあります。

Q: Should I worry about streaks?
A: Streaks are nice and helpful, but as I mentioned above — don’t worry about them too much and don’t criticize yourself over missing a day. Instead, make sure you do everything to not let that happen again, and know that worrying and scolding yourself will not give you any results. (Ok, It will give you results, but only negative. I would call them consequences, not results) The best way to get out of that negative emotional state is to sit down and code.
https://www.freecodecamp.org/news/join-the-100daysofcode-556ddb4579e4/