Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話
Search
masanori_msl
July 20, 2019
Programming
1
170
ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話
2019/07/20開催のわんくま同盟 大阪勉強会 #76 の資料です。
masanori_msl
July 20, 2019
Tweet
Share
More Decks by masanori_msl
See All by masanori_msl
WPFで印刷しよう!
masui_masanori
1
840
Programming ASP.NETCore を推したい話
masui_masanori
0
210
C#erがTypeScriptでフロントエンドに挑戦している話
masui_masanori
0
210
やっぱりわからんTaskの話
masui_masanori
0
100
AzurePipelinesでコンティニュアスにインテグレーションしたい
masui_masanori
0
1.4k
Razorに触れてみた
masui_masanori
0
63
ASP.NET Coreに入門した話
masui_masanori
0
250
Compare Java's 'var' with C#'s 'var'.
masui_masanori
0
1.3k
BoxingとUnboxingがどこで使われているか
masui_masanori
0
110
Other Decks in Programming
See All in Programming
20年もののレガシープロダクトに 0からPHPStanを入れるまで / phpcon2024
hirobe1999
0
450
ソフトウェアの振る舞いに着目し 複雑な要件の開発に立ち向かう
rickyban
0
890
testcontainers のススメ
sgash708
1
120
PHPUnitしか使ってこなかった 一般PHPerがPestに乗り換えた実録
mashirou1234
0
130
From Translations to Multi Dimension Entities
alexanderschranz
2
130
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
170
ブラウザ単体でmp4書き出すまで - muddy-web - 2024-12
yue4u
2
460
なまけものオバケたち -PHP 8.4 に入った新機能の紹介-
tanakahisateru
1
120
これが俺の”自分戦略” プロセスを楽しんでいこう! - Developers CAREER Boost 2024
niftycorp
PRO
0
190
Webエンジニア主体のモバイルチームの 生産性を高く保つためにやったこと
igreenwood
0
330
Haze - Real time background blurring
chrisbanes
1
510
RWC 2024 DICOM & ISO/IEC 2022
m_seki
0
210
Featured
See All Featured
Practical Orchestrator
shlominoach
186
10k
RailsConf & Balkan Ruby 2019: The Past, Present, and Future of Rails at GitHub
eileencodes
132
33k
Building Better People: How to give real-time feedback that sticks.
wjessup
365
19k
Measuring & Analyzing Core Web Vitals
bluesmoon
4
170
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Product Roadmaps are Hard
iamctodd
PRO
49
11k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
44
6.9k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
2
290
Automating Front-end Workflow
addyosmani
1366
200k
VelocityConf: Rendering Performance Case Studies
addyosmani
326
24k
Typedesign – Prime Four
hannesfritz
40
2.4k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Transcript
ASP.NET CoreやTypeScriptの 力を借りて レガシー寄りの環境に 立ち向かいたかった話 2019/07/20 @わんくま同盟 大阪勉強会 #76 by
masanori_msl
About me Name:Masui Masanori Work:Unity中心でしたが最近はWeb寄り Twitter:https://twitter.com/masanori_msl
Blog:http://mslgt.hatenablog.com/
なんか社内で使うための システム作ることになりました。 あらすじ
割とレガシーな環境 別のサービスが動いていたりする(あまり新規でインストールしづらい) 開発環境へは比較的自由にインストールできる( ASP.NET Core や Node.js
など) 社内システムにアクセスするためのライブラリ(dll)がある 前提(環境)
基本的にぼっち開発。 特にフロントエンドの経験は少ない。 レガシーな環境で動かすとはいえ、できるだけモダンな言語やフレームワークを 使いたい(そして助けてほしい)。 前提(開発者)
Visual Studio Code (サーバー・クライアントサイド両方を開発する上で一番使いやすかった) PgAdmin 4 (DB Access)
Node.js、npm、tsc、etc. 開発ツール
サーバーサイド( ASP.NET Core など)でのあれこれ ↓ クライアントサイド( TypeScript など)でのあれこれ お話の流れ
サーバーサイドでのあれこれ
ASP.NET Core を使う(所属メンバー的に .NET の開発経験がある人が多いため)。 ただし社内ライブラリを使うところは ASP.NET Frameworkで。
技術選定(サーバーサイド)
技術選定(サーバーサイド) IIS Access URL rewrite ASP.NET Core ASP.NET Framework http://localhost:XXXX
開発(サーバーサイド) 実際の開発については下記から推測してください。 https://mslgt.hatenablog.com/archive/category/ASP.NET%20Core https://mslgt.hatenablog.com/archive/category/Entity%20Framework%20Core
開発(サーバーサイド) 今回は開発環境に .NET Core が インストールされていなくても 何とかする方法についてだけ。
開発(サーバーサイド) 発行時に必要なファイル( .NET Core 含む)を一緒に出力することで、 実行環境に .NET Core がインストールされてなくても実行可能に。 (Self-contained
.NET Core Applications) 必要なことは① .csproj ファイルへの RuntimeIdentifier 追加と ② publish コマンドへのオプション追加。
開発(サーバーサイド) <Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>netcoreapp2.2</TargetFramework> <AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel> <RuntimeIdentifier>win-x86</RuntimeIdentifier> </PropertyGroup> <ItemGroup> <PackageReference
Include="Microsoft.AspNetCore.App" /> <PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" /> </ItemGroup> </Project> ① .csproj ファイルへの RuntimeIdentifier 追加
開発(サーバーサイド) ② publish コマンドへのオプション追加 dotnet publish -c Release -r win-x86
開発(サーバーサイド) 参照 .NET Core application deployment – .NET Core –
Microsoft Docs https://docs.microsoft.com/en-us/dotnet/core/deploying/ How to create a self contained .Net core application? https://dotnetthoughts.net/how-to-create-a-self-contained-dotnet-core-application/
開発(サーバーサイド) 課題 プロジェクトフォルダー > bin > Release > netcoreapp2.2 >
win-x86 > publish に 発行したファイルが出力される。
開発(サーバーサイド) 課題 不要 これが欲しい
あ、Entity Framework Core は PostgreSQL が少々古くても 問題なくアクセスしてくれてました。よ。 ※ PgAdmin 4
が IE で動かないっぽいので注意 開発(サーバーサイド)
クライアントサイドでのあれこれ
HTML5 Razor TypeScript PostCSS webpack
Polyfillあれこれ 技術選定(クライアントサイド) 主に使ったもの
TypeScript 選択の理由 やっぱり(静的な)型が欲しい。 (実際には「静的な」型ではなく「強い」型) いざとなったら JavaScript に変換してしまうことだってできる。
JavaScript の Framework は? Angular 、 React 、 Vue(ABC 順)
どれも人気があるが、 下記の点が気になって今回は選択せず。 基本的に Node.js を使って動作するため、実行環境にも Node.js が必要。 半年でメジャーバージョンアップデートする Angular をはじめ(LTSはあるが)、 更新が速い。(ASP.NET Coreについては目をつぶる方針で。。。) 自分をはじめ、メンバーの中で開発経験が少ない。
PostCSS 選択の理由 Autoprefixer (CSS のベンダープレフィックスを自動でつけてくれる)が 使いたかった。 @import も便利(※)。
CSS 変数も便利(※)。 ※PostCSSの機能ではないが、コンパイル時1つのファイルにまとめてくれるため、 ブラウザ間の対応の違いなどを気にせず使えた。
webpack 選択の理由 きっかけは Pikaday(https://pikaday.com/ シンプルなデートピッカー。 IE7から対応しているらしい) を使うのに、 import /
export が必要になったため。 TypeScript -> ES3 の JavaScript に変換、というのは tsc で可能だが、 import / export は別途ツールが必要。
Razor を使う
Razorを使う DB からデータを取得する、かつ同期的にデータを更新する要素で使用。 head など各画面共通要素をひとまとめにできるの便利。 静的な HTML
ファイルと比較して、サーバーサイドの Controller で ルーティングしやすいの便利。
Razorを使う TypeScript( JavaScript )にデータが渡しづらい。 (ViewData などは Razor でしか扱えないため、 HTML
から TypeScript に データを渡す処理を別途書く必要がある) 複数人で開発する時に、クライアントサイドを分割しづらい。 課題
Razorを使う この課題については良いバランスを見つけたいところ。 (その前に Blazor が来るかもしれない)
TypeScript を使う
TypeScript を使う TypeScript tsc (コンパイラ) InversifyJS (Dependency
Injection) reflect-metadata (InversifyJS で使用) pikaday (デートピッカー) moment (日付を良い感じに扱えるようにする) jest (テストツール) 主に使ったもの
TypeScript でハマったところ
TypeScript でハマったところ 主に TypeScript が「静的に」型を持つのではない、ということと、 最終的に JavaScript に変換される、という点に起因して、 C# 脳のまま書いていると失敗した、というお話。
TypeScript でハマったところ export function doSomething(){ let numbers = [10, 5,
3, 44, 1]; for(let n of numbers.sort()){ console.log(n); } } Sort 結果は 1 -> 10 -> 3 -> 44 -> 5 となる。 これは引数無しで sort() を実行すると辞書順でソートされる、という JavaScript の 挙動がそのまま反映されるため。
TypeScript でハマったところ export function doSomething(){ let numbers = [10, 5,
3, 44, 1]; for(let n of numbers.sort((a, b) => a - b)){ console.log(n); } } 数値順でソートするには引数を指定する。
TypeScript でハマったところ 型が保持されない場合がある 特に型が入れ子構造になっている場合に、クラス間でのデータ受け渡しや JSON.parse() による変換を行うと、子の型が保持されず undefined になってしまう、 といった現象が。。。
TypeScript でハマったところ 。。。と思ったのですが、この資料を作成するときに確認したら再現しませんでした (^o^)\ ※TypeScript のバージョン違いや再現手順の間違いによるものかも。
TypeScript でハマったところ 型が保持されない問題が再現したら as Sample と明示的に子どもの型も指定した変数に格納した上で (または元のデータ取得時に型を指定して子のデータを入れ直す)使用すると、 解決していた。
TypeScript の好きなところ
TypeScript の好きなところ 強い型を持つ 少なくとも自分の書くコードでは、その変数(プロパティ)の型が何を気にしなくても、 間違っていればコンパイラが怒ってくれる。 さらに Webpack を使って import /
export が可能になったことで、 1 クラス 1 ファイルに分ける、責務ごとに分割、といったことが容易に。
TypeScript の好きなところ 持ちうるデータの制限が容易 下記の変数は 1, 2, 3 以外を入れようとするとエラーになる。 let numbers:
1 | 2 | 3; numbers = 0; // ERROR numbers = 1; // OK
TypeScript の好きなところ Non-Nullable Null になり得るかどうかが指定できる(ただし undefined にはなる)。 かつ Kotlin でいう
Smart cast のように扱われる。 (Nullable であっても Null チェック後は Non-Nullable として扱われる)
TypeScript の好きなところ Non-Nullable export class User{ public name: string =
“”; // Non-Nullable public nickname: string| null = null; // Nullable } export function doSomething(){ let newUser = new User(); newUser.name = null; // ERROR let nickname = newUser.nickname.toString(); // ERROR if(newUser.nickname !== null){ let nickname2 = newUser.nickname.toString(); // OK } }
TypeScript の好きなところ と言いつつ柔軟性もある 例えばこんな interface を受け取る関数があるとして。 export interface Option{ option1?:
string; option2?: number; } export function doSomething(option: Option){ // あれこれする. }
TypeScript の好きなところ と言いつつ柔軟性もある こんな風に引数を渡すことができる。 doSomething({ option1: “Hello” }); // option2
は undefined
参照 参照 Matering TypeScript 3 https://subscription.packtpub.com/book/application_development/9781789536706 実践 TypeScript https://book.mynavi.jp/ec/products/detail/id=104703 Interfaces
- TypeScript http://www.typescriptlang.org/docs/handbook/interfaces.html
IE 11 に立ち向かう
一番辛かったところ
エラーがでない(場合がある)
IEでエラーがでない Promise を使ったコードを IE11 で実行すると、 Promise が見つからない、といった エラーが発生する。 しかし、 Array.prototype.find()
を使うと、エラーが表示されず、 かつ処理がそこで止まってしまうため問題を発見しづらい。
解決方法 IEでエラーがでない
他のブラウザと組み合わせて頑張る IEでエラーがでない
Polyfill
Polyfill 先ほどの Promise 、 Array.prototype.find() が IE 対応の必要があるからといって 使えないのはツラい。 ということで
Polyfill 先生の力を借りることに。
Polyfill Promise: https://www.promisejs.org/ fetch: https://github.com/github/fetch Array.prototype.find() :
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/find Array.prototype.findIndex() : https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex url-search-params-polyfill: https://github.com/jerrybendy/url-search-params-polyfill fetch と ur—search-params-polyfill は npm install 、他はファイルを用意して _Layout.cshtml で読み込みました。
Polyfill 注意点として、import 漏れがあっても IE で実行しないと気付かない、 というのがあります。 定期的に IE でも確認しましょう(白目)
文字化け
日本語データの文字化け URL のパラメータに日本語を渡すと、 IE のみ文字化けする現象が。。。 encodeURIComponent(文字列) で事なきをえました。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
PostCSS を使う
PostCSS を使う PostCSS は JavaScript のプラグインによって CSS をあれこれ変換してくれるツール。 具体的にはベンダープレフィックスを追加してくれる Autoprefixer
など。 (というか Autoprefixer が使いたいがために導入した) https://postcss.org/
PostCSS を使う PostCSS postcss-cli precss autoprefixer
インストールしたもの
PostCSS を使う 設定ファイル module.exports = { plugins: [ require("autoprefixer")({ "grid":
true }), require("precss") ] } postcss.config.js というファイルを作り(多分ファイル名は何でも良さそう)、 有効にするプラグイン、 ( Autoprefixer の場合) 有効にする CSS の種類 ( CSS grid など)を指定する。
PostCSS を使う 設定ファイル { ~省略~ "browserslist": [ "last 2 version",
"> 1%", "maintained node versions", "not dead" ], ~省略~ } 対応するブラウザバージョンは、以前 postcss.config.js に書いていたが、 現在は package.json に書くよう変更されている。
PostCSS を使う 課題 正直設定ファイルの書き方よくわかりません (^o^)\ (grid の場合は postcss.config.js で true
にすると有効になるが、 flexbox は browserlist を指定する必要があるとか)
PostCSS を使う ともあれコンパイル npx postcss 変換前の PostCSSファイルパス -c postcss.config.js -d
出力先のディレクトリパス ※出力先ディレクトリパスに元のファイル名でコンパイル済みの CSS が出力される。 ※ オプションとして -w をつけると、 CSS ファイルを監視して変更のたびに自動コンパイルしてくれる。
PostCSS を使う package.json の script に追加する ~省略~ "scripts": { “css”:
“npx postcss 変換前の PostCSSファイルパス -c postcss.config.js -d 出力先のディレクトリパス -w" } } npm run css を実行するとコンパイルを実行してくれる。 webpack も同じことができるが、両方いっぺんに監視する、というのは難しそう。
PostCSS の良いところ
PostCSS の良いところ 何といっても Autoprefixer が便利! @import や CSS
変数などもコンパイル時に解決してくれるので、 IE でも心配せずに使える。 プラグインが豊富なので、Autoprefixer 以外もあれこれ試すと良さそう。
その他あれこれ その他七転八倒の様子はこの辺で。 https://mslgt.hatenablog.com/archive/category/TypeScript https://mslgt.hatenablog.com/archive/category/CSS
その他の課題
Powershell開きまくり Webpack .NET Core PostCSS Git
JavaScript Frameworkは使うべきか スキル問題は置いておくとして、結局 Framework を使わなかったとしても、 オレオレ Framework になってしまう。 であれば、ある程度スタンダードになっている Framework
の流儀に沿って 作る方がメンテもしやすい? ただし更新速度にどう追従するかの問題はある。
おわりに 手探りながらもなんとか形にできたのは、公式や MDN をはじめ、 インターネット上にたくさんの知識が共有されていたから。 (特に「新しめの機能 + IE」でググるとほぼ確実にヒットするあたり、 先人の苦労を感じる) JavaScript
Framework をはじめ、今後もあれこれ試しつつ自分も 情報共有していきたい。
License Google Noto Fonts http://www.google.com/get/noto/ Copyright(c) Google Inc SIL
Open Font License (https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL )
Thank you