ASP.NET Core で小さく Sass と ES6 を使う

「小さく」と書いた理由には、その対比として Webpack のような Node のエコシステムを使った手法を置いている。つまり、そちらを「大掛かり」としている。

フロントエンドエンジニア不在の現場でフロントと向き合う

ASP.NET Core 関連のブログ等を読んでいたり、ASP.NET Core の SPA サポートをみていても、おそらく大きな流れとしては Node を素直に利用して、フロントはフロントの文化の中で開発しようというものに見える。

一方で、React / Vue などを使ったフロントエンド開発は、ASP.NET (MVC or WebForm) + jQuery の開発を主とする組織においてはハードルが非常に高い。

「勉強すれば」という声も聞こえてきそうだが、現実としてそういう組織は開発リソースも潤沢ではないため、学習しながら開発というのは難しく(しかも全く別分野のものを!)、当然フロントエンドエンジニアを採用するということも難しい。

ほとんど言い訳ではあるが、こういう背景があるという前提がある。

それでも JS / CSS の開発をアップデートしたい

SPA とまでいかなくとも、UI / UX に関する事業としての要望は上がっていくので、jQuery や普通の JavaScript を使うにしても、少しでも開発生産性を上げるようにしたい。

というところで、今回は最低限として以下を目指す。

  • JS/CSS のライブラリ管理できる(npm は使わない)
  • ES6 が使える(それ以上は望まない。でもアロー関数や class ぐらいは使いたい。)
  • Sass/Scss が使える

ライブラリ管理 Libman

Client-side library acquisition in ASP.NET Core with LibMan | Microsoft Docs

今回の要望を満たすのにちょうどいい。

dotnet tool も提供されている。

> dotnet tool install microsoft.web.librarymanager.cli

以下のようなコマンドでインストールができる。wwwroot 内のどこに配置するかも決められる。

> dotnet libman install jquery

インストールされたものは libman.json に記録されるため、それがある状態であれば以下で復元ができる。

> dotnet libman restore

ES6 / Sass の導入

Compilation of LESS, Scss, Stylus, JSX, ES6 and (Iced)CoffeeScript files

README の上記を見てもらって分かる通り、いくつかの形式をサポートしている。ただ、nuget の最終更新日 (2019 年で止まっている)を見てもらっても分かる通り、あまり活発ではなく、ES6 以上の対応は望めない。よって、さらにモダンな JS を使いたい場合は Webpack を使うしか無い。(TypeScript 等も当然そちらになる)

WebCompiler には以下のように dotnet tools も存在している。

GitHub - excubo-ag/WebCompiler

ただ、今回は極力開発体験として、IDE から実行ボタンを押せば済むだけにしたかったので MSBuild と連携して実行してくれる BuildWebCompiler の方を選択した。

以下が設定ファイルであるが、単に対応関係を書けばいいだけである。dotnet tools の方はフォルダ指定もできるので、この辺の設定を省略できるので、現場によっては dotnet tools を選んでもいいだろう。

[
  {
    "outputFile": "wwwroot/css/site.css",
    "inputFile": "wwwroot/css/site.scss"
  },
  {
    "outputFile": "wwwroot/js/site.js",
    "inputFile": "wwwroot/js/site.es6"
  }
]

上記を見て分かる通り、ES6 の場合は .es6 拡張子にしておく。(ここは例えば .es6.js とかにしてもいいが、IDE 側でうまくツリー表示してくれなかったので、素直に es6 にした)

bundler の導入

JS / CSS を bundle (及び minify )したいので、そちらも導入する。(WebCompiler でも minify はできるが、こちらでまとめて行うのであえてしていない)

こちらは Microsoft Docs に紹介があるので、詳細はそちらに譲るが、bundleconfig.json にまとめるファイルと出力ファイルを定義するだけなので迷う部分はない。

こちらも、MSBuild と連携してビルド時に実行してくれるため、開発体験としては、SCSS や ES6 を修正すると、ビルド時に CSS / JS への変換と、ファイルの bundle, minify をしてくれる感じになる。

当然、開発中は bundle と minify はいらないので、その辺は Release ビルド時だけ実行するように最適化できるとなお良さそうではある。

(テンプレートを使っている場合) bootstrap sass を使う

Sass を利用するようになったので、せっかくなので bootstrap sass を利用する。以下のように bootstrap.scss を用意し、lib 配下の bootstrap には sass フォルダもあるので、そこから必要なものだけインポートする。MVC テンプレートを使った場合の最低限だと以下のようになると思う。

@import '../lib/bootstrap/dist/scss/functions';
@import '../lib/bootstrap/dist/scss/mixins';
@import '../lib/bootstrap/dist/scss/variables';
@import '../lib/bootstrap/dist/scss/root';
@import '../lib/bootstrap/dist/scss/reboot';
@import '../lib/bootstrap/dist/scss/grid';
@import '../lib/bootstrap/dist/scss/navbar';
@import '../lib/bootstrap/dist/scss/utilities';
@import '../lib/bootstrap/dist/scss/type';

これを利用すれば、bootstrap.min.css を利用するよりサイズを削減できる。

_Layout.cshtml で分離させる

    <environment names="Development,Docker">
        <link rel="stylesheet" href="~/css/bootstrap.css" />
        <link rel="stylesheet" href="~/css/site.css" />
    </environment>
    <environment names="Staging,Production">
        <link rel="stylesheet" href="~/css/bootstrap.min.css" asp-append-version="true" />
        <link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
    </environment>

Microsoft Docs にも書いてあるが、同じようにする。(Sass で最低限だけ入れているので CDN からは読んでいない)

IDE 上でどう見えているか

f:id:dany1468:20210110003922p:plain

Rider での表示であるが、minify されたファイルも含めてツリー表示される。

最後に

今回の構成だと、JS のテストを書いたりというところまではいけていないし、おそらくは既存 jQuery / CSS での開発をちょっと便利にするぐらいにはなると思う。

なんとか Webpack を導入しつつも、既存の Web Form の開発者がそれを意識せずに開発できるようにというところを目指したかったが、おそらく綻びもでてしまうし、そこで開発体験が悪くなっても仕方がないので、フロントエンドの知見や人員が少しでも増えたところでという折り合いをつけようとしている感じ。

コード

GitHub - dany1468/aspnetcore_es6_sass

参考

他に検討したもの

以下はもう少し検討しても良かったのですが、Microsoft Docs で BuildBundlerMinifier が紹介されており、導入に関して説明がしやすいだろうというのがあったためというのが大きいです。