Madogiwa Blog

主に技術系の学習メモに使っていきます。

Git管理されたプロジェクト内の配下のTypeScriptプロジェクトだけ型チェックを行うスクリプトメモ📝

Git管理されたプロジェクトにいくつかTypeScriptのプロジェクトがあり、それらをまとめて型チェックしたくスクリプトを書いたのでメモ📝

以下がそのスクリプトです。

git ls-files -- root/dir | \
grep "tsconfig.json" | sed 's/tsconfig.json//' | \
xargs -I {} sh -c "cd {}; echo \"\n\"; pwd; npm install; npm run tsc --noEmit"

git ls-files -- root/dirで特定ディレクトリ配下のGit管理下のファイルリストを出力し、 grep "tsconfig.json" | sed 's/tsconfig.json//'tsconfig.jsonが配置されているディレクトリリストを取得します。

その後、xargs -I {} sh -c "cd {}; echo \"\n\"; pwd; npm install; npm run tsc --noEmit"でそれぞれのディレクトリに移動し、npm install後にtscで型チェックします。 ※上述のスクリプトでは対象が分かりやすいようにpwdで現在のディレクトリも表示しています。

ちなみにxargsで実行された複数のスクリプトの一部が失敗した場合、exit codeは123になるようです。 GitHub Actionsはexit codeが0以外は失敗扱いになるから、xargsで成功と失敗が混在した場合には失敗になるので便利ですね!

docs.github.com

参考

yujiorama.hatenablog.com

git-scm.com

Ruby: Ruby 3.3アップデート後に`bin/rails`系のコマンド実行時にconcurrent-rubyでSegmentation faultが発生する件のメモ📝

個人のWebサービスRuby 3.3アップデート後にbin/rails系のコマンド実行時にconcurrent-rubyでSegmentation faultが発生したのでメモ📝

$ bin/rails c

/app/vendor/bundle/ruby/3.3.0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/atomic/lock_local_var.rb:14: [BUG] Segmentation fault at 0x007effff843e06c0
ruby 3.3.0 (2023-12-25 revision 5124f9ac75) [aarch64-linux]

結論としてはRuby v3.3のバグのようだった。(arm64系のCPUを利用していると発生するっぽい?)

bugs.ruby-lang.org

concurrent-ruby側でもrubyの問題として上記のチケットへ誘導するためのissueが立てられている🎫

github.com

masterには対応のPRがマージされておりRuby 3.3.1のリリースで修正されるとのこと🙏

github.com

アップデートはRuby 3.3.1まで待つことにした・・・!

余談) Ruby 3.3のバックポートのリストを見ると、今後リリースされる予定のbug fixとかを見れることを知った📝

bugs.ruby-lang.org

2023年振り返り📝

今年も一年が終わるということで今年も振り返ってみる。

今年の振り返り

アウトプット

BLOG

BLOGは、今年1年で51記事書いていて、1週間に1記事ぐらい書いてるので、そこそこ書いてた✍ (月間PV数は5000PVくらい)

pickup

madogiwa0124.hatenablog.com

madogiwa0124.hatenablog.com

madogiwa0124.hatenablog.com

madogiwa0124.hatenablog.com

公開したツールとか

今思い返すとgemとかツールとか作って公開した💎

RailsのView層を隠蔽してControllerから直接Vue.jsのコンポーネント等をpropsを渡しつつレンダリングできるgem

github.com

Vue.js/TypeScript/AstroでGitHub Pagesで公開したRails newのコマンドをブラウザからポチポチして作れるツール

github.com

OSS活動

今年はsimpackerのテストの修正やpicture_pack_tagを追加したり、

github.com

github.com

Vue.js系のドキュメントのtypo等々の修正をしたり、

github.com

github.com

chibivueというVue.jsの内部実装を解説しているドキュメントのtypo等々の修正をしたりしてました。

github.com

ref: 今年のPRリスト

インプット

今年は、結構頑張ってて107冊読んでました。 年間100冊以上読んだのは初めてでしたが、2~3日に1冊のペースで読めると、タイムラグが少なく必要なタイミングで書籍からインプットできるので良いなぁと今になっては思います。

印象に残ってる本を載せておきます。

技術書

オブジェクトに着目してUIを考えるというのがバックエンドからキャリアを始めたのもあってか分かりやすく納得感があった。

ボブおじさんの新作、Clean Coder等で語られている内容も多かったけど、改めて読んでも良い内容だった。

SmartHRさんのデザインシステムの検討から運用までの流れをベースにデザインシステムについて書かれた本、かなり現場感もあり良かった。

マネジメント系は結構あった気がするけど、技術系のエンジニアキャリアについて書かれており興味深かった。

CDNやnginxといったリバースプロキシを駆使して、どうパフォーマンス良く・安定的に配信するか書かれていて、この辺りの知識があんまり無かったので勉強になった。

ブラウザにおけるパフォーマンス改善の指標やツールの使い方が一通り解説されていて分かりやすく勉強になった。

その他

話題の三体とプロジェクト・ヘイルメアリーを読んだ。どちらもSF長編でドラマチックな展開で面白かった。

インテル元CEOの本、マネジメントの本だけど実際の業務を進め方を考える上でも本書で書かれている、テコ作用の利用や、モチベーションの向上と訓練といった内容は参考になったと思う。

ずっと読みたいなーと思っていた小説だったけど、読んでみたらやはり面白かった。

結構古典を色々読んでみたけど、やはり長く読まれている本は面白かった。

去年の目標と結果

目標 メモ 結果
心身ともに健やか/穏やかに過ごす 割と頑張りすぎず健やか・穏やかに過ごせた気がするので O
フロントエンド系のスキルをキャッチアップして一定活躍出来るようになる 静的解析やビルド周りのキャッチアップは結構できた。個人の開発でCSSフレームワークから独自実装に移行したりして一定のUI開発はできそうな感じがしてきたが、業務レベルかと言われると微妙 
身近な課題を解決するなにかを作る Vue.js、Astro、GitHub Pagesみたいな構成でツールを実装して公開できた O

今年の目標

目標 メモ
publicな場での活動をもうちょっと頑張る 会社のテックブログとか、登壇とかOSS活動とか今年よりも、もうちょっと頑張りたい。
新しい言語にチャレンジする 基本的な構文・思想を理解しており読み書きできる言語を増やす(Rustとか
フロントエンド技術を用いたUI実装の一定自信を持照るようになる フロントエンドエンジニアとしてのコアなスキルな気がするので自信を持っておきたい。
心身ともに穏やかに健康で過ごす あまり無理せず穏やかに検討で過ごす

おわりに

今年はプライベートで色々と大きなイベントがあり、バタバタした一年だったが一定コードも書きつつ目標もそこそこ達成できたかなと思うので、良い一年だったかなと思う。

業務的にもずっと対応していたVue3のバージョンアップをEOLまでにやり切ることができてよかった。

来年も、無理せず心身ともに健やか/穏やかに楽しみを感じて過ごしていけるようにしたい。

Vue.js: `eslint-plugin-vue-scoped-css`を使って静的解析でScoped CSSを強制するメモ📝

Vue.jsのSFCを利用している場合に極力Scoped CSSを利用してCSSの統制を取りたいと思いますが、eslint-plugin-vue-scoped-css を利用すると静的解析で強制することができることを最近学んだのでメモ📝

future-architect.github.io

やり方は簡単で公式ドキュメントの通りですが、以下でインストールし、

$ npm install --save-dev eslint-plugin-vue-scoped-css vue-eslint-parser

ESLintの設定ファイルに以下を追記するだけです。

module.exports = {
  extends: [
+ 'plugin:vue-scoped-css/base'
  ],
  rules: {
+ "vue-scoped-css/enforce-style-type": ["error", { allows: ["scoped"] }],
  }
}

これでScoped CSSを利用してない場合にESLintで以下のエラーが発生するようになりました✨

  159:1  error  Missing attribute `scoped`  vue-scoped-css/enforce-style-type

eslint-plugin-vue-scoped-css、他にもVue3で非推奨な::v-deepや、Vue3で破壊的変更があったtransition系のclassの利用も検知できるの非常に便利ですね🙌

Ruby: Haml v6アップデート時のカスタム属性の振る舞いの互換性を維持するメモ📝

Haml v6からHamlの内部実装がHamlitに置き換わりパフォーマンス向上等のメリットがありますが、

github.com

以下のissueでコメントされている通り、

github.com

Vue.js等を利用している場合に以下のようなfalsyの値がv5系では<cutsom-element />となっていたのが、

%cutsom-element{ ":costom-attributes": nil  }

Haml v6では<cutsom-element :costom-attributes='' />となってしまいます。

上記の場合Vue.jsを利用しているHaml v6の挙動ではpropsのデフォルト値が利用されなくなり、明示的にundefinedを渡すような実装に修正する必要があり非常に影響が大きいです😢

これに対応する仕組みが以下のHaml v6.2.2でリリースされたHaml::BOOLEAN_ATTRIBUTESに任意の属性名の文字列・正規表現を追加することでHaml v5相当の振る舞いにすることができます。

github.com

全部やるなら以下とすれば良さそうですが、

Haml::BOOLEAN_ATTRIBUTES.push(/.*/)

この変更自体がパフォーマンス向上のトレードオフで発生しているもののようなので、パフォーマンスに問題がないか等は計測して対応を入れる必要がありそうです。

It varies. No impact, as slow as Haml 5, or slower than Haml 5, depending on the benchmark.

https://github.com/haml/haml/issues/1148#issuecomment-1754421295

📝以下のようなスクリプトで既存のhamlファイルを読み込んで利用されているカスタムタグの属性のリストを抽出し、それがだけ許可するような感じでもいいのかもしれない🤔

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'haml'
end

require 'haml/parser'

haml = <<~HAML
  %h1 Hello!
  %custom-element{ ":custom-attributes1": false, "string-attributes1": "hello" }
  %custom-element{ ":custom-attributes2": nil, "string-attributes2": "" }
  %p
    %span World!
HAML

parser = Haml::Parser.new({})
parsedHaml = parser.call(haml)

def extract_tags_and_attributes(node)
  result = []

  node.children.each do |child|
    tag_name = child.value[:name]
    attribute_names = child.value[:attributes].keys
    dynamic_attributes = child.value[:dynamic_attributes]
    dynamic_attribute_hash = dynamic_attributes.old ? eval(dynamic_attributes.old) : {}
    result << { name: tag_name, attributes: attribute_names + dynamic_attribute_hash.keys }
    result.concat(extract_tags_and_attributes(child))
  end

  result
end

tags_and_attributes = extract_tags_and_attributes(parsedHaml)
is_custom_tag = ->(tag) { tag[:name].include?("-") }

puts tags_and_attributes.select(&is_custom_tag)
                        .flat_map { |tag| tag[:attributes] }
                        .uniq
# =>
# :custom-attributes1
# string-attributes1
# :custom-attributes2
# string-attributes2

Vue.js: 静的解析でVue3から非推奨なディープセレクタ`::v-deep`をエラーにするメモ📝

Vue3から以下のドキュメント記載の通りディープセレクタを利用する際に::v-deepから:deepに変更になりました。

<style scoped>
/* deep selectors */
::v-deep(.foo) {}
/* shorthand */
:deep(.foo) {}

/* targeting slot content */
::v-slotted(.foo) {}
/* shorthand */
:slotted(.foo) {}

/* one-off global rule */
::v-global(.foo) {}
/* shorthand */
:global(.foo) {}
</style>

rfcs/active-rfcs/0023-scoped-styles-changes.md at master · vuejs/rfcs · GitHub

利用するとビルドした際に以下のような警告が出るものの気づかずに利用してしまうことも多いので静的解析でエラーにできないかやってみたのでメモ📝

::v-deep usage as a combinator has been deprecated. Use ::v-deep(<inner-selector>) instead

やり方

結論から言うとstylelintのselector-disallowed-listを使って、

stylelint.io

以下のように指定してあげると::v-deep系のセレクターを静的解析でエラーにすることができた。

{
  "extends": ["stylelint-config-standard-scss"],
  "overrides": [
    {
      "files": ["**/*.vue"],
      "customSyntax": "postcss-html"
    }
  ],
  "rules": {
    "selector-disallowed-list": ["/::v-deep/", "/::v-slotted/", "/::v-global/"],

利用していると以下のようにエラーになります。

app/javascript/components/pages/EditBoardContainer.vue
 178:3  ✖  Unexpected selector "::v-deep(.main-with-sidemenu__sidemenu)"  selector-disallowed-list

Stylelint便利ですね🤵✨

`vscode-standard-ruby`でプリインストールのrubyが利用されてしまうのを直した時のメモ📝

vscode-standard-rubyでプリインストールのrubyで実行されてしまいパッケージマネージャーで関しているバージョンで実行されずLSPが落ちてしまいハマったので対応したことをメモ📝

github.com

事象

以下のようにターミナルで確認するとパッケージマネージャで管理している最新のRubyが利用されているが、

$ ruby -v
ruby 3.2.2 (2023-03-30 revision e51014f9c0) [x86_64-darwin22]

vscode-standard-rubyのLSPの起動時に以下の通り謎にプリインストールのrubyが利用されてしまっており失敗していた。

[client] stderr:
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/lib/ruby/2.6.0/rubygems.rb:283:in `find_spec_for_exe': Could not find 'bundler' (2.4.10) required by your /Users/morita.jun/Documents/repo/dogfeeds/Gemfile.lock. (Gem::GemNotFoundException)

解決方法

以下の設定が入っていたので削除し、ターミナルで利用しているもの(zsh)が利用されるようにした。

- "terminal.integrated.defaultProfile.osx": "bash"

そしてVSCodeを単純に再起動するのではなく、ターミナルからcodeコマンドでVSCodeを再起動するとパッケージマネージャで管理しているRubyが利用されLSPの起動に成功した🤔

[server] Standard Ruby v1.32.0 LSP server initialized, pid 81066

"terminal.integrated.defaultProfile.osx": "bash"の設定によりbashで最初起動してしまったので、zshのターミナルで再起動するまではパッケージマネージャーの設定が無いbashが利用されてしまいプリインストールのRubyが使われてしまっていたっぽい?(VSCodeは起動時のShellの設定を引き継ぐ?)

参考

qiita.com