Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話

ASP.NET CoreやTypeScriptの力を借りてレガシー寄りの環境に立ち向かいたかった話

2019/07/20開催のわんくま同盟 大阪勉強会 #76 の資料です。

masanori_msl

July 20, 2019
Tweet

More Decks by masanori_msl

Other Decks in Programming

Transcript

  1. ASP.NET CoreやTypeScriptの 力を借りて レガシー寄りの環境に 立ち向かいたかった話 2019/07/20 @わんくま同盟 大阪勉強会 #76 by

    masanori_msl
  2. About me  Name:Masui Masanori  Work:Unity中心でしたが最近はWeb寄り  Twitter:https://twitter.com/masanori_msl 

    Blog:http://mslgt.hatenablog.com/
  3. なんか社内で使うための システム作ることになりました。 あらすじ

  4.  割とレガシーな環境  別のサービスが動いていたりする(あまり新規でインストールしづらい)  開発環境へは比較的自由にインストールできる( ASP.NET Core や Node.js

    など)  社内システムにアクセスするためのライブラリ(dll)がある 前提(環境)
  5.  基本的にぼっち開発。  特にフロントエンドの経験は少ない。  レガシーな環境で動かすとはいえ、できるだけモダンな言語やフレームワークを 使いたい(そして助けてほしい)。 前提(開発者)

  6.  Visual Studio Code (サーバー・クライアントサイド両方を開発する上で一番使いやすかった)  PgAdmin 4 (DB Access)

     Node.js、npm、tsc、etc. 開発ツール
  7. サーバーサイド( ASP.NET Core など)でのあれこれ ↓ クライアントサイド( TypeScript など)でのあれこれ お話の流れ

  8. サーバーサイドでのあれこれ

  9.  ASP.NET Core を使う(所属メンバー的に .NET の開発経験がある人が多いため)。  ただし社内ライブラリを使うところは ASP.NET Frameworkで。

    技術選定(サーバーサイド)
  10. 技術選定(サーバーサイド) IIS Access URL rewrite ASP.NET Core ASP.NET Framework http://localhost:XXXX

  11. 開発(サーバーサイド) 実際の開発については下記から推測してください。 https://mslgt.hatenablog.com/archive/category/ASP.NET%20Core https://mslgt.hatenablog.com/archive/category/Entity%20Framework%20Core

  12. 開発(サーバーサイド) 今回は開発環境に .NET Core が インストールされていなくても 何とかする方法についてだけ。

  13. 開発(サーバーサイド) 発行時に必要なファイル( .NET Core 含む)を一緒に出力することで、 実行環境に .NET Core がインストールされてなくても実行可能に。 (Self-contained

    .NET Core Applications) 必要なことは① .csproj ファイルへの RuntimeIdentifier 追加と ② publish コマンドへのオプション追加。
  14. 開発(サーバーサイド) <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 追加
  15. 開発(サーバーサイド) ② publish コマンドへのオプション追加 dotnet publish -c Release -r win-x86

  16. 開発(サーバーサイド) 参照 .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/
  17. 開発(サーバーサイド) 課題 プロジェクトフォルダー > bin > Release > netcoreapp2.2 >

    win-x86 > publish に 発行したファイルが出力される。
  18. 開発(サーバーサイド) 課題 不要 これが欲しい

  19. あ、Entity Framework Core は PostgreSQL が少々古くても 問題なくアクセスしてくれてました。よ。 ※ PgAdmin 4

    が IE で動かないっぽいので注意 開発(サーバーサイド)
  20. クライアントサイドでのあれこれ

  21.  HTML5  Razor  TypeScript  PostCSS  webpack

     Polyfillあれこれ 技術選定(クライアントサイド) 主に使ったもの
  22. TypeScript 選択の理由  やっぱり(静的な)型が欲しい。 (実際には「静的な」型ではなく「強い」型)  いざとなったら JavaScript に変換してしまうことだってできる。

  23. JavaScript の Framework は? Angular 、 React 、 Vue(ABC 順)

    どれも人気があるが、 下記の点が気になって今回は選択せず。  基本的に Node.js を使って動作するため、実行環境にも Node.js が必要。  半年でメジャーバージョンアップデートする Angular をはじめ(LTSはあるが)、 更新が速い。(ASP.NET Coreについては目をつぶる方針で。。。)  自分をはじめ、メンバーの中で開発経験が少ない。
  24. PostCSS 選択の理由  Autoprefixer (CSS のベンダープレフィックスを自動でつけてくれる)が 使いたかった。  @import も便利(※)。

     CSS 変数も便利(※)。 ※PostCSSの機能ではないが、コンパイル時1つのファイルにまとめてくれるため、 ブラウザ間の対応の違いなどを気にせず使えた。
  25. webpack 選択の理由  きっかけは Pikaday(https://pikaday.com/ シンプルなデートピッカー。 IE7から対応しているらしい) を使うのに、 import /

    export が必要になったため。  TypeScript -> ES3 の JavaScript に変換、というのは tsc で可能だが、 import / export は別途ツールが必要。
  26. Razor を使う

  27. Razorを使う  DB からデータを取得する、かつ同期的にデータを更新する要素で使用。  head など各画面共通要素をひとまとめにできるの便利。  静的な HTML

    ファイルと比較して、サーバーサイドの Controller で ルーティングしやすいの便利。
  28. Razorを使う  TypeScript( JavaScript )にデータが渡しづらい。 (ViewData などは Razor でしか扱えないため、 HTML

    から TypeScript に データを渡す処理を別途書く必要がある)  複数人で開発する時に、クライアントサイドを分割しづらい。 課題
  29. Razorを使う この課題については良いバランスを見つけたいところ。 (その前に Blazor が来るかもしれない)

  30. TypeScript を使う

  31. TypeScript を使う  TypeScript  tsc (コンパイラ)  InversifyJS (Dependency

    Injection)  reflect-metadata (InversifyJS で使用)  pikaday (デートピッカー)  moment (日付を良い感じに扱えるようにする)  jest (テストツール) 主に使ったもの
  32. TypeScript でハマったところ

  33. TypeScript でハマったところ 主に TypeScript が「静的に」型を持つのではない、ということと、 最終的に JavaScript に変換される、という点に起因して、 C# 脳のまま書いていると失敗した、というお話。

  34. 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 の 挙動がそのまま反映されるため。
  35. TypeScript でハマったところ export function doSomething(){ let numbers = [10, 5,

    3, 44, 1]; for(let n of numbers.sort((a, b) => a - b)){ console.log(n); } } 数値順でソートするには引数を指定する。
  36. TypeScript でハマったところ 型が保持されない場合がある 特に型が入れ子構造になっている場合に、クラス間でのデータ受け渡しや JSON.parse() による変換を行うと、子の型が保持されず undefined になってしまう、 といった現象が。。。

  37. TypeScript でハマったところ 。。。と思ったのですが、この資料を作成するときに確認したら再現しませんでした (^o^)\ ※TypeScript のバージョン違いや再現手順の間違いによるものかも。

  38. TypeScript でハマったところ 型が保持されない問題が再現したら as Sample と明示的に子どもの型も指定した変数に格納した上で (または元のデータ取得時に型を指定して子のデータを入れ直す)使用すると、 解決していた。

  39. TypeScript の好きなところ

  40. TypeScript の好きなところ 強い型を持つ 少なくとも自分の書くコードでは、その変数(プロパティ)の型が何を気にしなくても、 間違っていればコンパイラが怒ってくれる。 さらに Webpack を使って import /

    export が可能になったことで、 1 クラス 1 ファイルに分ける、責務ごとに分割、といったことが容易に。
  41. TypeScript の好きなところ 持ちうるデータの制限が容易 下記の変数は 1, 2, 3 以外を入れようとするとエラーになる。 let numbers:

    1 | 2 | 3; numbers = 0; // ERROR numbers = 1; // OK
  42. TypeScript の好きなところ Non-Nullable Null になり得るかどうかが指定できる(ただし undefined にはなる)。 かつ Kotlin でいう

    Smart cast のように扱われる。 (Nullable であっても Null チェック後は Non-Nullable として扱われる)
  43. 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 } }
  44. TypeScript の好きなところ と言いつつ柔軟性もある 例えばこんな interface を受け取る関数があるとして。 export interface Option{ option1?:

    string; option2?: number; } export function doSomething(option: Option){ // あれこれする. }
  45. TypeScript の好きなところ と言いつつ柔軟性もある こんな風に引数を渡すことができる。 doSomething({ option1: “Hello” }); // option2

    は undefined
  46. 参照 参照 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
  47. IE 11 に立ち向かう

  48. 一番辛かったところ

  49. エラーがでない(場合がある)

  50. IEでエラーがでない Promise を使ったコードを IE11 で実行すると、 Promise が見つからない、といった エラーが発生する。 しかし、 Array.prototype.find()

    を使うと、エラーが表示されず、 かつ処理がそこで止まってしまうため問題を発見しづらい。
  51. 解決方法 IEでエラーがでない

  52. 他のブラウザと組み合わせて頑張る IEでエラーがでない

  53. Polyfill

  54. Polyfill 先ほどの Promise 、 Array.prototype.find() が IE 対応の必要があるからといって 使えないのはツラい。 ということで

    Polyfill 先生の力を借りることに。
  55. 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 で読み込みました。
  56. Polyfill 注意点として、import 漏れがあっても IE で実行しないと気付かない、 というのがあります。 定期的に IE でも確認しましょう(白目)

  57. 文字化け

  58. 日本語データの文字化け URL のパラメータに日本語を渡すと、 IE のみ文字化けする現象が。。。 encodeURIComponent(文字列) で事なきをえました。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent

  59. PostCSS を使う

  60. PostCSS を使う PostCSS は JavaScript のプラグインによって CSS をあれこれ変換してくれるツール。 具体的にはベンダープレフィックスを追加してくれる Autoprefixer

    など。 (というか Autoprefixer が使いたいがために導入した) https://postcss.org/
  61. PostCSS を使う  PostCSS  postcss-cli  precss  autoprefixer

    インストールしたもの
  62. PostCSS を使う 設定ファイル module.exports = { plugins: [ require("autoprefixer")({ "grid":

    true }), require("precss") ] } postcss.config.js というファイルを作り(多分ファイル名は何でも良さそう)、 有効にするプラグイン、 ( Autoprefixer の場合) 有効にする CSS の種類 ( CSS grid など)を指定する。
  63. PostCSS を使う 設定ファイル { ~省略~ "browserslist": [ "last 2 version",

    "> 1%", "maintained node versions", "not dead" ], ~省略~ } 対応するブラウザバージョンは、以前 postcss.config.js に書いていたが、 現在は package.json に書くよう変更されている。
  64. PostCSS を使う 課題 正直設定ファイルの書き方よくわかりません (^o^)\ (grid の場合は postcss.config.js で true

    にすると有効になるが、 flexbox は browserlist を指定する必要があるとか)
  65. PostCSS を使う ともあれコンパイル npx postcss 変換前の PostCSSファイルパス -c postcss.config.js -d

    出力先のディレクトリパス ※出力先ディレクトリパスに元のファイル名でコンパイル済みの CSS が出力される。 ※ オプションとして -w をつけると、 CSS ファイルを監視して変更のたびに自動コンパイルしてくれる。
  66. PostCSS を使う package.json の script に追加する ~省略~ "scripts": { “css”:

    “npx postcss 変換前の PostCSSファイルパス -c postcss.config.js -d 出力先のディレクトリパス -w" } } npm run css を実行するとコンパイルを実行してくれる。 webpack も同じことができるが、両方いっぺんに監視する、というのは難しそう。
  67. PostCSS の良いところ

  68. PostCSS の良いところ  何といっても Autoprefixer が便利!  @import や CSS

    変数などもコンパイル時に解決してくれるので、 IE でも心配せずに使える。  プラグインが豊富なので、Autoprefixer 以外もあれこれ試すと良さそう。
  69. その他あれこれ その他七転八倒の様子はこの辺で。 https://mslgt.hatenablog.com/archive/category/TypeScript https://mslgt.hatenablog.com/archive/category/CSS

  70. その他の課題

  71. Powershell開きまくり Webpack .NET Core PostCSS Git

  72. JavaScript Frameworkは使うべきか スキル問題は置いておくとして、結局 Framework を使わなかったとしても、 オレオレ Framework になってしまう。 であれば、ある程度スタンダードになっている Framework

    の流儀に沿って 作る方がメンテもしやすい? ただし更新速度にどう追従するかの問題はある。
  73. おわりに 手探りながらもなんとか形にできたのは、公式や MDN をはじめ、 インターネット上にたくさんの知識が共有されていたから。 (特に「新しめの機能 + IE」でググるとほぼ確実にヒットするあたり、 先人の苦労を感じる) JavaScript

    Framework をはじめ、今後もあれこれ試しつつ自分も 情報共有していきたい。
  74. 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 )
  75. Thank you