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
820
Programming ASP.NETCore を推したい話
masui_masanori
0
200
C#erがTypeScriptでフロントエンドに挑戦している話
masui_masanori
0
210
やっぱりわからんTaskの話
masui_masanori
0
100
AzurePipelinesでコンティニュアスにインテグレーションしたい
masui_masanori
0
1.4k
Razorに触れてみた
masui_masanori
0
61
ASP.NET Coreに入門した話
masui_masanori
0
240
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
Functional Event Sourcing using Sekiban
tomohisa
0
110
Jakarta EE meets AI
ivargrimstad
0
690
どうして僕の作ったクラスが手続き型と言われなきゃいけないんですか
akikogoto
1
120
CSC509 Lecture 13
javiergs
PRO
0
110
エンジニアとして関わる要件と仕様(公開用)
murabayashi
0
310
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
250
Remix on Hono on Cloudflare Workers
yusukebe
1
310
デザインパターンで理解するLLMエージェントの作り方 / How to develop an LLM agent using agentic design patterns
rkaga
8
620
ふかぼれ!CSSセレクターモジュール / Fukabore! CSS Selectors Module
petamoriken
0
150
Modular Monolith Monorepo ~シンプルさを保ちながらmonorepoのメリットを最大化する~
yuisakamoto
6
570
React CompilerとFine Grained Reactivityと宣言的UIのこれから / The next chapter of declarative UI
ssssota
2
120
WebフロントエンドにおけるGraphQL(あるいはバックエンドのAPI)との向き合い方 / #241106_plk_frontend
izumin5210
4
1.4k
Featured
See All Featured
For a Future-Friendly Web
brad_frost
175
9.4k
Site-Speed That Sticks
csswizardry
0
36
The World Runs on Bad Software
bkeepers
PRO
65
11k
Intergalactic Javascript Robots from Outer Space
tanoku
269
27k
ReactJS: Keep Simple. Everything can be a component!
pedronauck
665
120k
YesSQL, Process and Tooling at Scale
rocio
169
14k
Designing for Performance
lara
604
68k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
42
9.2k
Agile that works and the tools we love
rasmusluckow
327
21k
A Modern Web Designer's Workflow
chriscoyier
693
190k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
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