- 投稿日:2022-02-28T23:11:41+09:00
TestCafe触ってみる
はじめに E2EテストツールのTestCafeのハンズオンです。 ほぼ、公式のGetting Startedをなぞってます。 ハンズオンのゴール ゴールはテスト対象のデモサイトで、簡単なテストを実行してみるところまでです。 TestCafeのインストール npmを利用していくので、インストールされていないマシンをお使いの場合は事前にインストールをお願いします。 今回はTestCafeをローカルインストールするので、作業用のフォルダを用意してください。 $ mkdir testcafe-sample $ cd testcafe-sample npmをinitしてフォルダ内にインストールできるようにします。 $ npm init --y testcafeをローカルインストールします。テストなので一応devDependencies指定しておきます。 $ npm install --save-dev testcafe TestCafeがインストールできたかを確認します。 $ npx testcafe -v 1.18.4 npxコマンドによりローカルでインストールしたパッケージのコマンドが使えるようになります。 テストを作る TestCafeが用意してくれているデモページをテスト対象としてテストを作ってみます。 デモページにアクセス 入力欄#developer-nameにJohn Smithと入力 ボタン#submit-buttonをクリック 期待値Thank you, John Smith!と表示されていることを確認 とりあえず、動くことを確認したいのでTestCafeのサイトのコードをそのまま拝借してきます。test.jsファイルを作って貼り付けます。 test.js import { Selector } from 'testcafe'; fixture`Getting Started` .page`https://devexpress.github.io/testcafe/example`; test('My first test', async t => { await t .typeText('#developer-name', 'John Smith') .click('#submit-button') .expect(Selector('#article-header').innerText).eql('Thank you, John Smith!'); }); 詳しい内容の解説は省きます。 ちなみに、セレクタの指定方法などはこの記事にまとめています。 テストを実行する テストを実行してみます。 $ npx testcafe chrome ./test.js するとブラウザが起動して、テストが実行されます。 利用できるブラウザは—list-browsersオプションで確認できます。 $ npx testcafe --list-browsers firefox chrome edge safari 参考
- 投稿日:2022-02-28T21:14:10+09:00
javaScript_Array.filter
MDNの中にfilter()メソッドについて、このように説明しています。 filter() メソッドは、与えられた関数によって実装されたテストに合格したすべての配列からなる新しい配列を生成します。 例: const numArr = [1,2,3,4,5]; // 奇数のみを抽出する const NewNumArr = numArr.filter((num)=>{return num%2 === 1;}); console.log(NewNumArr); // 値を順番に取り出す for(value of NewNumArr){ console.log(value); } 文字列を連結するには、従来は+を使いますが、ES6の書き方で${}を使います。 例: const nameArr = ["田中","中田","藤井","蒼井"]; for(let i=0; i<nameArr.length; i++){ console.log(`${i + 1}番目は${nameArr[i]}です`); } ここで簡単に紹介しますが、ES6の中にmap()メソッドを使うと、従来でfor文で書く冗長なコードを簡略化することができます。 ぜひmap()メソッドに慣れてください。 例: const nameArr = ["田中","中田","藤井","蒼井"]; nameArr.map((name,index) => console.log(`${index + 1}番目は${name}です`)); if文を使用し、配列になる一部の値のみを変更する例: const nameArr = ["田中","中田","藤井","蒼井"]; const NewNameArr = nameArr.map((name)=>{ if(name === "田中"){ return name; }else{ return `${name}さん`; } }) console.log(NewNameArr); for(value of NewNameArr){ console.log(value); }
- 投稿日:2022-02-28T18:50:52+09:00
QuillJS を利用している場合にホワイトスペースが圧縮されてしまう問題の対処
問題 quilljs のversion 1.3.7 (記事執筆時点でGithubで表記されている latest リリース) での話。 Quill Editor で編集した値を一度 DB に保存する。 この場合、DB の中身はこのようになる。 # 入力 テストです。 ← 全角スペースが4個配置されています。 # DBに保存される値 <p>テストです。 ← 全角スペースが4個配置されています。</p> この値を再編集するために、<div> 要素に以下の通りに出力して Quill インスタンスを生成する。 <div id="quill-editor"> <p>テストです。 ← 全角スペースが4個配置されています。</p> </div> ... <script type="text/javascript"> var quill = new Quill('#quill-editor'); </script> しかし、これで初期化するとスペースが圧縮された状態でエディタに表示されてしまう。 これをスペース圧縮を行わないで展開するにはどうすれば良いのかを調べたが、結構大変だったのでメモ。 解決作 この問題については例えば以下の Issue で語られているが、これはコピー&ペーストの時の場合であって、初回の展開時の話ではない。 しかし、この Issue 内で、この置換を行っているところが matchText 関数内であることが示されている。 実際のソースコードを見ると、 function matchText(node, delta) { let text = node.data; // Word represents empty line with <o:p> </o:p> if (node.parentNode.tagName === 'O:P') { return delta.insert(text.trim()); } if (text.trim().length === 0 && node.parentNode.classList.contains('ql-clipboard')) { return delta; } if (!computeStyle(node.parentNode).whiteSpace.startsWith('pre')) { // eslint-disable-next-line func-style let replacer = function(collapse, match) { ... となっていて、node.parentNode に whiteSpace スタイルが直接指定されているかどうかを見て置換を行っていることが分かる。 この node.parentNode の実体を見てみると、これは <div id="quill-editor"> 内の子要素であることが分かった。 そのため、Quill インスタンスを生成する前に、例えば以下のような方法で各要素に style="white-space: pre;" を直接付与してやれば良い。 jQueryを利用する場合のコード $('#quill-editor').children().each(function(idx, v) { $(v).css('white-space', 'pre'); }); この後に Quill インスタンスを生成するとスペースを圧縮せずにエディタ上に文字を展開することができる。
- 投稿日:2022-02-28T16:43:47+09:00
【Vue】v-forで配列を指定回数だけループさせて出力させる
環境 Vue2 はじめに 今回はVue.jsの記事になります。案件の中で要素を最初の2件だけ表示させてほしいというご要望をいただきました。メソッドを使い配列フィルタリングしたりといろいろな方法を試したので書き留めておこうと思います。 v-forについて v-forディレクティブの使い方 v-forはいわゆるfor分の役割を持ちます。 HTMLタグの属性にv-for="要素(命名は自由) in 定義した配列"を定義 index.vue <div id="app"> <ul> <li v-for="item in items">{{ item }}</li> </ul> </div> v-forは2つ目の引数にindexを取れる 以下の様に第2引数を指定することによって、indexを取ることができます。indexの名前は自由につけてOK index.vue <div id="app"> <ul> <li v-for="(item, index) in items">{{ item }}</li> </ul> </div> :keyを設定する :key=””で各要素を一意に識別するためのkey属性を設定する。 ここでkey属性を設定しないとエラーが吐き出されます。 Elements in iteration expect to have 'v-bind:key' directives index.vue <div id="app"> <ul> <li v-for="(item, index) in items" :key="item">{{ item }}</li> </ul> </div> 今回のコード index.vue <template> <div id="app"> <ul> <li v-for="member in memberis" :key="member.id"> {{ member.id}}-{{ member.name }} <p> 保有スキル:<span v-for="skile in member.skiles" :key="skile.id">{{ skile.label }}</span> </p> </li> </ul> </div> </template> <script> export default { name: "App", data() { return { memberis: [ { id: 1, name: "鈴木", skiles: [ { id: 1, label: "PHP" }, { id: 2, label: "Ruby" }, { id: 3, label: "Vue" }, { id: 4, label: "JavaScript" } ] }, { id: 2, name: "田中", skiles: [ { id: 1, label: "Java"}, { id: 2, label: "AWS"}, { id: 3, label: "JavaScript"}, { id: 4, label: "GCP" }, { id: 5, label: "PHP" } ] }, { id: 3, name: "佐藤", skiles: [ { id: 1, label: "React"}, { id: 2, label: "Ruby"}, {id: 3, label: "Laravel"} ] }, ] }; }, }; </script> <style> ul { list-style : none; } li { margin: 10px; padding: 10px; border: 1px solid #000; } span { margin: 5px; } </style> さっそく修正していきます 修正内容は、保有スキルの表示を2つにして欲しいというものです。 いろいろと調べてみた結果 配列をフィルタリングした後にv-forでループさせれる v-forとv-ifを組み合わせる 上記2点の記事が多くでてきました。 今回は前者の配列をフィルタリングする方法を使って修正していきます。 実装 今回は配列が入れ子構造になっているので、親をv-forで回しつつスキルのv-forでフィルタリングをさせる実装になります。 コード index.vue <template> <div id="app"> <ul> <li v-for="member in memberis" :key="member.id"> {{ member.id}}-{{ member.name }} <!-- フィルタリングメソッドを追加 --> <p> 保有スキル:<span v-for="skile in limitCount(member.skiles)" :key="skile.id">{{ skile.label }}</span> </p> </li> </ul> </div> </template> <script> export default { name: "App", data() { return { memberis: [ { id: 1, name: "鈴木", skiles: [ { id: 1, label: "PHP" }, { id: 2, label: "Ruby" }, { id: 3, label: "Vue" }, { id: 4, label: "JavaScript" } ] }, { id: 2, name: "田中", skiles: [ { id: 1, label: "Java"}, { id: 2, label: "AWS"}, { id: 3, label: "JavaScript"}, { id: 4, label: "GCP" }, { id: 5, label: "PHP" } ] }, { id: 3, name: "佐藤", skiles: [ { id: 1, label: "React"}, { id: 2, label: "Ruby"}, {id: 3, label: "Laravel"} ] }, ] }; }, // フィルタリングするメソッドを追加 methods: { limitCount (lists) { return lists.slice(0, 2) } } }; </script> <style> ul { list-style : none; } li { margin: 10px; padding: 10px; border: 1px solid #000; } span { margin: 5px; } </style> 実装内容 文字列や配列などからデータの一部分だけ取り出せるメソッsliceを使ってメソッドを定義します。 第一引数に開始位置、第二引数に終了位置を指定します。今回は表示させたい値は最初の2つなので開始位置0、終了位置2を指定しています。 こうすることで表示させたい数の変更も簡単にできます。 後は、フィルタリングしたい配列を指定してメソッドを呼び出せば完了です。 今回は以上となります。
- 投稿日:2022-02-28T16:39:41+09:00
【JavaScript】Mochaについて
JavaScriptのテストでmochaを使ったのではじめの基本的なところをメモしておく。 mochaとは mochaとは、柔軟性のあるJavaScriptのテストフレームワーク。 mocha自体には、アサーションなどの機能を持っていないため自由にライブラリを選択できる。また、Node.jsだけでなくブラウザでも実行することができるという特徴がある。 mochaは、npmを使って以下のようにインストールできる。 npm install --save-dev mocha chaiとは chaiとは、アサーションライブラリのこと。chaiは、mochaと同様にNode.jsだけでなくブラウザでも実行できる。上記のようにmocha自体はアサーションの機能がないため、今回はchaiを使用した。 chaiのインストールもnpmを使って以下のようにできる。 npm install --save-dev chai package.jsonを編集 npm testでmochaを実行できるように、package.jsonのscriptsに以下を追加する。 package.json "scripts":{ "test": "mocha" } サンプル mochaとchaiを使った簡単なサンプルを書いておく。 今回は、足し算の結果を返すsum(x,y)をテストするサンプルを書いてみた。 テストコード const assert = require("chai").assert; const calculator = require("../src/calculator"); describe("sum()のテスト", () => { it("sum(2,5) = 7", () => { assert.deepEqual(calculator.sum(2, 5), 7); }); }); このテストを実行すると以下となる。 sum()のテスト ✔ sum(2,5) = 7 1 passing (6ms)
- 投稿日:2022-02-28T15:37:28+09:00
シークライズ
「Sequelize」の読み方を、私は「シークライズ」と表記、記述、呼称しています。 Sequelizeとは、データベースへ簡単にアクセスするためのNode.jsのライブラリです。 TypeScriptやJavaScriptで使用しています。
- 投稿日:2022-02-28T15:26:48+09:00
IEサポートも終わるので、npmパッケージのDependabot Alertsを解消しつつアプリの動きに支障なくアップデートさせる
フロントエンド開発を長年悩ましてきたInternet Explorer 11(以下IE11)のサポートが2022年6月15日ついに終了となります。 これを受けて、サポートを続けていた既存のWebアプリもサポートを切る流れが現在進行系で加速していることでしょう。 ソース管理にGitHubを使用している場合、Dependabot Alertsが何十件、下手したら何百件と溜まっているかもしれません。npmパッケージをアップデートしてくれというメッセージを添えて。 npmパッケージは数年経つとバージョンが大きく上がるケースは多いです。規模の大きいパッケージになっていくと、いわゆるbreaking change(破壊的変更)が複数回含まれることも少なくありません。 この点を踏まえて、何も考えずアップデートしてDependabot Alertsをすべて解消したらアプリがビルドすら出来ずに動かなくなりました!一般にも公開するのにどうしましょう!な展開を避けるためにはどう対処すれば良いのでしょうか?今回は私自身の経験も踏まえてまとめていきます1。 本記事で紹介する手順はパッケージ管理がyarn(1.x系)であることを前提としています。npmなど別のパッケージ管理ツールを使用している場合は、都度コマンドを置き換えていただければと思います。またnpmに関して、パッケージ管理ツールとコマンドの意味を区別するため、後者を表す場合はnpmと記載しています。 GitHubのDependabot Alertsとは? GitHub上で運用しているリポジトリの設定がOn(デフォルトもOn)になっていると、リポジトリページに表示される警告です。 アプリにインストールされている依存パッケージの脆弱性を自動で検知・警告&場合によってはPRを自動で生成してくれる便利機能です。ここで言う依存パッケージはpackage.jsonに明記されているパッケージだけでなく、package.lock.json/yarn.lockといったlockファイルにしか記載されていないパッケージも対象となります。 詳しく知りたい方は以下のページを読んでみてください。 npm audit fixを使ってアップデートし、Dependabot Alertsを解消する 解消するためにターミナルで叩くコマンドは以下のとおりです。 $ yarn audit $ npm i --package-lock-only $ npm audit fix --force $ rm yarn.lock $ yarn import $ rm package-lock.json $ rm -rf node_modules $ yarn # yarn install でも可能 何をしているのか、順を追って説明します。 Dependabot Alertsの一覧を確認 $ yarn audit これはDependabot Alertsの一覧にターミナル上で吐き出してくれるコマンドです。--level [info|low|moderate|high|critical]フラグをつけると指定した警告度のものだけ表示されます。アップデートする度にalerts数の確認のためにこまめに叩いておきましょう。 npm audit fixで実際にパッケージのアップデートを行う $ npm i --package-lock-only $ npm audit fix --force $ rm yarn.lock $ yarn import $ rm package-lock.json npm audit fixコマンドはpackage.jsonに明記されているパッケージの子パッケージのalerts解消も考慮した状態までアップデートしてくれるコマンドです。 ただし、npm audit fixコマンドに該当するコマンドがyarnにはないため、npm i --package-lock-onlyでまずpackage.jsonの内容を基にpackage-lock.jsonを生成します。 そしてnpm audit fix --forceでパッケージのアップデートを行います。この際、package-lock.jsonの内容も書き換わります。 ここで--forceフラグの有無の違いについて質問が飛んできそうなので、説明します。正直npmのドキュメント読んでも分かりづらいため、ここは説明が難しいところですが、私はこんな風に解釈しています。 --forceフラグなし: package.jsonに明記されているパッケージに限り、パッケージそのものにalertsが出ていれば、修正したバージョンへアップデートを行う。 --forceフラグあり: package.jsonに明記されているパッケージの依存パッケージでalertsが出ている→package.jsonに明記されているパッケージについて、その依存パッケージがalertsの出ないバージョンへ修正された状態のバージョンへアップデートを行う。 --forceフラグありの意味が自分で書いておいてよくわからなくなっていますが、要はpackage.jsonに明記されているパッケージの子パッケージのalerts解消も考慮した状態までアップデートしてくれるよ、の意味で取っていただければと思います。 package-lock.jsonの内容をyarn.lockに反映させたいので、一旦既存のものを削除しyarn importで再度生成します。 アップデート後、ビルド出来るかなどを確認 $ rm -rf node_modules $ yarn # yarn install でも可能 node_modulesにはまだアップデート前の情報が残ったままなので一旦消して、再度生成しましょう。 終わったら、ビルドしてみたりアプリ起動したりして、正常に既存アプリが動作するかを確認しましょう。yarn auditでの確認も忘れずに。またLinter/Formatter/テストコードが入っている場合はこちらも合わせて確認しておきましょう。 流れとしては以上です。コマンドの説明を終えたので、ここから具体的な対処方法の解説をしていきます。 依存パッケージ数別アップデート手順 package.jsonにいるパッケージ数の規模によってアップデート手順が少し違ってくるので分けて説明します。 ※パッケージ数はあくまで私の経験則による目安です。パッケージが大きいものばかりという可能性もあるので、目安はケースバイケースで変更してください。 パッケージ数が小規模(<=15くらい) まだ数が少ないので、こちらの節で解説した方法のみで問題ありません。時間もかからない&万が一何か合った場合に原因の特定が難しくないからです。 パッケージ数が中〜大規模(>15くらい) 規模が大きくなるので、一辺にアップデートしてしまうと万が一何か合った場合の原因特定/原因となったライブラリの切り分けが難しくなっていきます。ですので私の経験上、以下の方法をオススメします。 基本的に前述のアップデートコマンドを叩いて、npm audit fix --forceではなく、npm audit fixで叩く ビルドエラー等出ないか確認 前述のアップデートコマンドそのまま叩く 再度ビルドエラー等出ないか確認 こんなときどうすればいいの?集 npm audit fixの方法だけですんなり上手くいけばいいのですが、やはり上手くいかない場合も多々あります。私の経験で実際に対処したケースをここにまとめておきます。 npm audit fixでアップデートしたのにDependabot Alertsが解消されない このケースは残念ながら度々発生します。この場合、alertsが出ているパッケージはpackage.jsonに明記されているパッケージから更に枝分かれ形式で依存しているものであるケースがほとんどです。 この場合、yarnのresolutions機能を使ってalertsが出ているパッケージを指定する方法で対処する方法があります。 まずyarn auditなどでalerts一覧を確認し、そこでpatched versionに書かれたバージョンをpackage.jsonのresolutions欄に追記しましょう。 コード例では以下のことを行っています(パッケージ名はあくまで例です)。 hogehogeというパッケージのバージョンが2.1.3で固定されてインストールされる fugaというパッケージのバージョンが1.1.5 < 2.0.0の間でインストールされる package.json { "devDependencies": { ... }, + "resolutions": { + "hogehoge": "2.1.3" + "fuga": "^1.1.5" + } } これで再度yarnもしくはyarn installコマンドでパッケージをインストールし、yarn auditするとresolutionsしたパッケージのalertsが消えます。 resolutions機能をもう少し詳しく知りたい方は以下のページを参考にしてみてください。 ※npmを使用している場合、version8.3以降限定ですが、overrides機能で代用可能なようです。 ESLintとPrettierが喧嘩する ESLintとPrettierはモダンフロント開発におけるLinter/Formatterのデファクトスタンダードです。 そんなESLintとPrettierですが、アップデートを行うと、ESLint的にはOKだが、PrettierとしてはNGとなる現象も多々発生します(私は遭遇したことないですが、逆のケースも勿論存在すると思います)。この場合、vscodeなどで出るエラー解消ボタンを押してコードを修正しても今度はESLintとしてNGになってしまいます。なぜこんなことが起こるようになってしまったのでしょうか? Prettierはversion 2.x系以降において末尾カンマの有無などデフォルト設定が大きく変更されました。詳しい変更点の内容は以下の記事を参考にしてもらえばと思います。 Prettier側の設定で上記変更点を一部offにすることは可能なのですが、残念ながらPrettier側から変更出来る設定は少なく全部の競合の制御は不可能な仕様となっています。ですので、ESLint側の方を上手く制御してあげる必要があります。 Prettier側としては、eslint-config-prettierというPrettier側のルールと競合しうるESLintルールをoffしてくれるライブラリを使って競合を避けることが推奨されています2。もしこのeslint-config-prettierが入っていても、競合が発生するのであればpluginも含めたESLint関連のパッケージのバージョン指定を一度見直しましょう。 Node.jsのバージョンが指定されているため、パッケージのバージョンを上げたくても上げられない プロジェクトによっては、使用するNode.jsのバージョンが指定されている場合があります。この場合、パッケージによってはアップデート出来ないケースがあり得ます。 私が出会ったパッケージではnode-sassがこれに該当します。README見てもらえばわかると思いますが、Node.jsのバージョンによってインストールするバージョンが指定されています。 (引用:node-sassのREADMEより) もう非推奨なんだし、さっさとdart-sassに乗り換えればいいのにの声が聞こえてきそうですが、現実はそんなわけにはいきません。以下のページを見てもらえばと思いますが、@importから@useへの変更を筆頭に文法が一部変更されています。 アプリの規模が大きい場合、既存の大量のsass/scssファイルの精査/書き換え作業が必要になります。もはやこのレベルならアップデート作業が完了した後に、別タスクとしてやるかnode-sassのままにしておくべきでしょう(正直dart-sassへの移行は、E2E Test環境やVisual Regression Testing環境が完備されているとかでもない限り、山積みの手動テストが必要になるのでかなり難しい)。 そんなわけでalertsを消すだけなら、前述のyarnのresolutions機能を活用しましょう。(もしalertsを全て消してくれという要求がされているのであれば、今回はNode.jsのバージョンの影響で解消出来なかったです、Node.jsのバージョン云々は今後相談させてくださいみたいな話をマネジメント層を通してきちんと相談しましょう。) まとめ 今回は私の経験則を基にnpmパッケージのアップデート対応方法をまとめてみました。alertsを一掃するだけならそんなに難しくないのですが、アプリを動かすまでのパッケージバージョンの指定/設定の追記修正がなかなか難しいです。 また対処集もいくつか載せてみましたが、こんなケースもあった、もっとこうすれば楽に進められるなどのご意見があればコメントいただけると非常に嬉しいです。ではIEに苦しめられない良いフロント開発ライフを願って! 参考ページ あなたはどんな開発してきたの?って聞かれそうなので回答ですが、一般の人も使うとあるWebアプリのVue開発を担当しています。 ↩ ここに書かれている通り、version 7.x以降はESLintのversion7.x以降のインストールが必須とされているため、ご注意ください。 ↩
- 投稿日:2022-02-28T14:22:41+09:00
グレーアウトなよる
背景 フロント実装にてクリック契機等で既存画面をグレーアウトして新たな要素を出す仕組みを書いたのでその備忘録も兼ねて。 単純にモーダル機能としてだけであればBootstrapで事足りるのですがそれだと少し痒いところに手が届かないよって方向けに。。 実装例 ボタンクリックで背景グレーアウト→画像表示 Grayout.vue <template> <b-button @click="display" variant="primary" class="btn">表示</b-button> <div id="grayout" v-show="showFlag"> <div id="contents"> <!-- コンテンツを記載 --> <img id="image" :src="imgUrl"/> </div> </div> </template> <script> export default { data () { return { imgUrl: '', showFlag: false } }, methods: { display () { let random = 0 + Math.floor( Math.random() * 3 ); if (random == 0) { // 大吉 this.imgUrl = 'https://3.bp.blogspot.com/-vQSPQf-ytsc/T3K7QM3qaQI/AAAAAAAAE-s/6SB2q7ltxwg/s1600/omikuji_daikichi.png' } else if (random == 1) { // 吉 this.imgUrl = 'https://2.bp.blogspot.com/-27IG0CNV-ZE/VKYfn_1-ycI/AAAAAAAAqXw/fr6Y72lOP9s/s800/omikuji_kichi.png' } else { // 凶 this.imgUrl = 'https://4.bp.blogspot.com/-qCfF4H7YOvE/T3K7R5ZjQVI/AAAAAAAAE-4/Hd1u2tzMG3Q/s1600/omikuji_kyou.png' } this.showFlag = true } } } </script> Grayout.css <style> #grayout{ z-index:1000; position:fixed; top:0; left:0; width:100%; height:100%; background-color:rgba(0,0,0,0.5); display: flex; align-items: center; justify-content: center; } #contents{ z-index:1001; } z-indexでコンテンツの出す層を設定できます。(数が大きい方が前面に表示) 様々な要素が重なり合う場合の厳密な制御が可能になりますが、1,2,3...で刻むよりは1,10,100,1000...とする方が後々改修する時に楽だったり単純にパッと見でわかりやすいのでおすすめ。
- 投稿日:2022-02-28T12:55:19+09:00
jQueryのAJAX通信でリクエストヘッダ送る際の備忘録
タイトル通り、jQueryのAJAX通信でAPIに対してリクエストヘッダに値を設定して送る時の備忘録です。 基本的にはheadersに値を設定して送る事になると思います。 記述例としては以下のような感じ。 var _data = JSON.stringify({}); $.ajax({ url: '[APIのURL]', headers: { '[送信したい値のkey名]' : '[送信したい値]', }, type: 'POST', contentType:'application/json; charset=utf-8', data: _data, dataType: 'json', crossDomain: true, cache: false, xhrFields: { withCredentials: true } }); 注意点としては、送るのがリクエストヘッダだけで送るデータがなかったとしても 空のデータをJSON化してdataに指定して送っておかないと400エラーが出ます。 ※PHPのエラーには「Required request body is missing: public java.lang.String」といった感じのものが出る。
- 投稿日:2022-02-28T06:47:47+09:00
JavaScriptをTypeScriptにする一文字命名規則とは何か
この命名規則は策定中です。 はじめに 本記事ではプログラミングの生産性を上げるシンプルな命名規則を提案します。 一文字命名規則とは何か 一文字命名規則とはアルファベット一文字とアンダースコアを変数名や関数名の頭に付ける命名規則です。 そうすることにより変数名や関数名を大文字小文字あわせて最大52種類のグループに分け、それぞれのグループに型などの意味を持たせられます。 具体的にはフラグ変数の名前がvisibleならアルファベット一文字bとアンダースコア_を頭につけてb_visibleにして変数名にBoolean型の意味を持たせられます。 一文字命名規則の補足説明 一文字命名規則を詳しく説明します。 プログラマーはそれぞれのグループの意味を自由に定義できます。 変数名や関数名の一文字を見てグループの意味が分かるようにします。 シンプルな命名規則にするために一文字縛りがあります。 一文字が重複したときは大文字や、52種類のなかの未使用文字を使うことを検討します。たとえばJavaScriptなら数値型をn_に、Node型をN_にするのが良いでしょう。 一文字が重複して複数の意味を持っても構いません。その場合は文脈から判断されます。 グループの定義をどこかに書いておくことは良い考えです。 すべての変数名や関数名に一文字を付ける必要はありません。プログラマーの負担がない範囲で一文字命名規則を使います。 一文字命名規則がどのようにしてJavaScriptをTypeScriptにするか? 一文字命名規則を使うことによりプログラマーが変数名b_visibleを見たときBoolean型だと分かるようになります。 変数名を見て型情報が分かることがJavaScriptをTypeScriptに近づけるということです。 一文字命名規則の使用例 一文字命名規則がJavaScriptのプログラミングの生産性を爆上げすることが一発で分かる使用例を示します。 JavaScript var e_target = document.querySelector('#target'); // 要素(Element) var s_target = e_target.textContent; // 文字列(String) var n_target = Number(e_target.textContent); // 数値(Number) お分かりいただけただろうか? 1つの名称targetを使いまわすことにより、DOMの操作をするJavaScriptのプログラマーが変数名で悩まなくてよくなります。一文字命名規則により、それぞれの変数の意味が変数名から分かるようになっています。 一文字命名規則の一例 JavaScriptの場合の一例を示します。 変数名の場合 一文字 意味 a Array型。配列。 b Boolean型。論理型。真偽値。BigInt型。 c Constant。定数。constで宣言された変数。Class型。クラス。 d Date型。日付。 e Element型。 f Flag型。フラグ。Function型。関数。 g Global。グローバル変数。 h i j JSON型。 k l letで宣言された変数。List型。リスト。 m n Node型。Number型。数値。 o Object型。オブジェクト。 p q Queue型。キュー。 r RegExp型。正規表現。 s String型。文字列。Symbol型。シンボル値。 t Text型。テキスト。Temporary型。一時的な変数。Time型。時間。 u v Value。任意の値。varで宣言された変数。 w x y z 関数名の場合 一文字 意味 a Arrow。アロー関数。Async関数。 b Bind。thisや関数の引数がバインドされた関数。 c Callback。コールバック関数。 d e EventListenerの関数。 f Function。functionで宣言された関数。 g Generator関数。function*で宣言された関数。 h Higher-order function。高階関数。 i j jQueryの関数。 k l m n Nested function。関数内関数。 o p Pure function。純粋関数。 q Query。何かを問い合わせる関数。 r Recursive function。再帰関数。 s Side Effect。副作用のある関数。Sub関数。副関数。 t Temporary。一時的な関数。 u v w Wrapper。ラッパー関数。 x y z 一文字命名規則に関連した記法 調べたところハンガリアン記法という記法があることが分かりました。 ハンガリアン記法とは変数名やクラス名などに接頭文字ないし接尾文字をつける命名法です。 ハンガリアン記法との違いは、一文字命名規則には一文字縛りがあること、アンダースコアがあること、一文字が重複した場合の扱いがあることなどです。 ハンガリアン記法への批判への批判 調べたところハンガリアン記法が批判されてきたことが分かりました。ハンガリアン記法への批判への批判を試みます。 修正の際にデータ型を変更すると変数名も変えなきゃいけなくなるので面倒。保守の障害になる。 変数や関数に名前を付けるときによく使われる省略形 - Qiita C++やC#のような言語ではそういうこともあるかもしれませんが、JavaScriptの小さな開発ならデータ型を変更することはほとんどありません。 C++やC#のような言語では型付けが存在するためにシステムハンガリアンを使用することによる利点はない。 ハンガリアン記法 - Wikipedia JavaScriptにはC++やC#のような型付けが存在しません。型付けが存在する言語においても変数名や関数名に型以外の意味を持たせることがプログラミングの役に立つと思います。 さいごに ハンガリアン記法は Excel や Word の開発で成功を収めました1が、批判があったためか世間で推奨されなったようです。 本当に非推奨でしょうか?少なくともJavaScriptの小さな開発において役に立つと思います。 ぜひ一文字命名規則を使ってください。ハンガリアン記法よりもシンプルな一文字命名規則でプログラミングの生産性を爆上げしましょう。 ハンガリアン記法 - Wikipedia ↩
- 投稿日:2022-02-28T01:31:31+09:00
「マイクロサービスパターン」の復習 5章
概要 Java読書会でせっかく勉強したのにつぎつぎと忘れていくので、印象に残ったところを記録していく 5章 マイクロサービスアーキテクチャにおけるビジネスロジックの設計 ビジネスロジックを設計上、どのように構築していくか Transaction scriptパターン もっともシンプルな形態 ビジネスロジックはサービスクラスに持たせて、エンティティクラスはデータだけ エンンティティの方はORマッパーでマッピングする 利点 設計が簡単 エンティティ側がデータだけなので、責務について悩むこともない ロジックとデータが分離されている ビジネスロジックとデータ(データベースのスキーマ)の変更頻度・ライフサイクルは違うので別れている方が良いという考え方もある 欠点 ビジネスロジックの重複 ビジネスロジック間の共通ロジックについて、共通化がきれいにできない ロジックは全部サービス側の責務になってしまっているので、共通化したとしても結構汚くなるでしょう。例えば、AbstractServiceみたいな親クラスを作って、共通ロジックを親クラス持ちにするのもよくあるけど、数あるサブクラスのうち2つの共通化にしかなってないとそれは親クラスの責務なのか?となるでしょう。 Transaction Scriptについては、利点も協力だけど、この本のスタンスとしては、より柔軟で強力なDomain Modelパターン(とその系譜)の方が複雑なロジックを実現するには適しているとしている。 Domain Modelパターン 柔軟かつ強力な形態 外部からの要求の受け口となるサービスクラスは入口となるメソッドはもつが、ほとんどのビジネスロジックはモデルクラスが持ち、サービスクラスはモデルのメソッドを呼ぶだけ 利点 (オブジェクト指向的な意味で)設計が分かりやすい モデルクラスがデータとそれに関連するビジネスロジックを持つので、オブくジェクト指向的な役割分担がなされる 結果的に共通化が促進される(共通ロジックもどのクラスの責務なのかが明確になり各モデルクラスに分散されていく) テストがしやすい これが真実かどうかは作り方によるが、この本に出てくるモデルクラスはそれなりにテストしやすくなっている オブジェクト指向の本来持っている柔軟性が活かしやすい GOFのデザインパターンなどが活かしやすい 欠点 設計難易度が高い ORマッパーとの使い方に気を使う Transaction Scriptならテーブルとのマッピング用なので、クラスからスキーマを作るので、スキーマからクラスを作るのでもどちらでも良かったけど、Domainモデルでは単純にはいかない。 個人的にはDomain Modelパターンは、うまく行けば綺麗だけど、設計が崩れないよう、細心の注意を払わなければいけないので、かならずしも好きではないです Aggregateパターン AggregateはもともとDDDの言葉。 モデリング後の各エンティティを、従属関係、ライフサイクル、意味論などの観点からグルーピンングし、各グループをAggregateと呼ぶ 例 Orderアグリゲートとは、Order、PaymentInfo、DeliveryInfo、OrderLineItemの集合となる。アグリゲートの中で特に中核となるものをアグリゲートルートとよぶ 通常のドメインモデルであっても実際に作ったことのある人ならOrderLineItemはOrderの一部分であり、Orderが削除されるときにはOrderLineItemも削除されるのは感覚的に分かるはず 一方で、Orderテーブルの外部キーとして、Restaurantへの参照があったとしも、RestaurantはOrderとは別のライフサイクルを持つことも感覚的に分かるはず Aggregateパターンでは、これらを明確にする Aggregateパターンでは、Aggregateが整合性の単位となる。 例 OrderLineItemを個別に作成・削除するのではなく、Orderに対する更新処理として表現する 実装上はTransactionが使えるなら、一つのTransactionに収まるようにする アグリゲートとマイクロサービス 概ねマイクロサービスとアグリゲートを1対1にすると、それらしい設計になる 場合によっては1対多でもいいのかもしれない。 単純なDomain Modelだと、Domain Modelのどの部分がどのサービスに担当になるのか不明瞭 アグリゲートというモデル上の境界を導入することで、サービスへの対応がしやすくなる この章の本題であるビジネスロジックは、各アグリゲートが持つようにする Domain Modelを強化したようなもの 例:OrderサービスとOrderアグリゲート、KitchenサービスとKitchenアグリゲート アグリゲートをまたがる参照は、主キーの参照を持つようにする サーガによって、サービスを渡り歩く処理をする場合は、1つのアグリゲートごとに1つのトランザクションを作る Domain Eventパターン アグリゲートが生成、更新されたときはイベントを発行するということ 単位がアグリゲートなのが大事 イベントの用途1:ユーザーへの通知 例えばOrderの配送開始をユーザーにメールで通知するなど Orderの更新処理の一部として、メール通知のロジックも含めることでも実現可能である イベント経由にしておいたほうが、関心事が分離されて、拡張性もある。 通知手段はいくつでも増やせるなど イベントの用途2:別のマイクロサービスへの通知 7章のCQRSパターンのように、更新とクエリーが別サービスになっている場合は、クエリー側のサービスは更新側サービスからイベントを拾って、クエリーのためのDBを更新する マイクロサービスでは、各サービスごとにDBをもつので、結果的に何らかミラーリングが必要になることも多くなる。そのためにはイベントは欠かせなくなる 感想 アグリゲートは、マイクロサービスの構成を考える上で、根幹をなす考え方だと思われる イベントというのは組み込みでは当たり前のものだけど、ついにWebの世界でもイベントが必要な時代になったかと感じる