これはメモです

それ以上でもそれ以下でもないのです

フロントエンドツールの公式サイトリンク集

公式を見ながらひとつひとつ設定していくのが最も理解が深まると思うのでメモ。

Vite

ja.vitejs.dev

ESLint

eslint.org

React フック用プラグイン

https://ja.reactjs.org/docs/hooks-rules.html#eslint-plugin

'React' must be in scope when using JSX エラーの対処法

React v17 create-react-app で作ったアプリで ESLint に怒られまくった - かもメモ https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/react-in-jsx-scope.md

ESlint module.exports が no-undef エラー

ESlint module.exports が no-undef なエラーになるとき - かもメモ

stylelint

stylelint.io

プロパティ順序整列用

https://github.com/cahamilton/stylelint-config-property-sort-order-smacss

Prettier

prettier.io

aria-expandedの紐付けについて

最近ハンバーガーメニューを実装する時などにaria-*属性を使用することがあり、下記のように記述していた。

<div class="hamburger">
  <button type="button" aria-expanded="false" aria-controls="js_menu">ボタン</button>
  <div id="js_menu" aria-hidden="true">
    <!-- ここにメニューが入る -->
  </div>
</div>

気を付ける部分として、

  1. aria-expanded属性は開閉を制御する要素(つまりbutton)につける
  2. aria-contorls属性で制御する要素とされる要素の紐付けを行う

このように考えていたのだが、1.に関してはそうとも限らないらしい。

上記コードのような、ボタンとメニューが共通の祖先要素を持つなら、その要素にaria-expandedを付与することもできる。

<div class="hamburger" aria-expanded="false">
  <button type="button" aria-controls="js_menu">ボタン</button>
  <div id="js_menu" aria-hidden="true">
    <!-- ここにメニューが入る -->
  </div>
</div>

新しい発見があって奥深いという気持ち。

参考

tabindexの初期値について

divなどの通常フォーカスできない要素にJavaScriptでフォーカスを持たせる場合、tabindex="-1"を指定することがある。 ふと気になってtabindexのデフォルト値が何なのか調べてみた。

console.log(document.createElement('div').tabIndex); // -1
console.log(document.createElement('a').tabIndex); // 0
console.log(document.createElement('button').tabIndex); // 0

abuttonといったフォーカス可能な要素は0, それ以外は-1になるよう。 初期値が-1であれば指定不要では…?

と思ってtabindexを指定せずにフォーカスを当ててみようとしたが失敗。

仕様がどうなっているか確認。HTML Living Standardによると、

The tabIndex IDL attribute must reflect the value of the tabindex content attribute. The default value is 0 if the element is an a, area, button, frame, iframe, input, object, select, textarea, or SVG a element, or is a summary element that is a summary for its parent details. The default value is −1 otherwise. HTML Standard 6.6.3 The tabindex attribute

訳すと以下のような意味になる。

  • tabIndexのIDL属性は、 content属性の値を反映する必要がある。
  • 以下の要素のIDL属性は初期値が0。それ以外は-1
    • a
    • area
    • button
    • frame
    • iframe
    • input
    • object
    • select
    • textarea
    • SVGa
    • detailsの子要素であるsummary

聞き慣れないIDL属性、content属性と言う言葉が出てきた。 ざっくり言うと下記のような意味らしい。

  • IDL属性 … JavaScriptのプロパティ。
  • content属性 … HTMLで設定した属性。

つまり、JSのtabIndexプロパティの初期値は0-1で、HTMLに設定したtabindexの値はJSのプロパティに反映されるということらしい。 そのため、最初に調べたのはtabIndexプロパティであって、tabindex属性とは別。 ではHTMLにtabindexを設定しない場合、属性値は何になるのか。

console.log(document.createElement('div').getAttribute('tabindex')); // null
console.log(document.createElement('div').tabIndex); // -1

nullになった。HTMLに設定されたtabindexはJS側にも反映されるが、未指定の状態では相違が生じるということになる。

まとめると

  • HTML属性値とJSプロパティは同一のものに見えるが、実際はそうではない。
  • フォーカス可能要素以外にフォーカスを持たせる場合は、やはりHTML側でtabindex属性を明示的に指定する必要がある。

余談

また別の話だと思うが、ahrefもHTML属性とJSプロパティとで返す値が異なる。 仕様上、HTMLAnchorElementhref属性は絶対URIをを表すと決められている。

<a href="#hoge"></a>
// 表示ページのURLをhttps://example.comとする
document.querySelector('a').href; // https://example.com#hoge
document.querySelector('a').getAttribute('href'); // #hoge

以上。

参考

PHPで連想配列の値が空か判定する

ちょっと詰まったのでメモ。

$arrayとかisset()で判定できるのかなと思いきや出来なかった。

<?php
$array = [
    'elm1' => '',
    'elm2' => [],
];
var_dump(!$array); // false
var_dump(!isset($array)); // false

調べたところ、array_filter()の第二引数(コールバック関数)を省略することでフィルタリングができるとのこと。

コールバック関数が与えられなかった場合、 array のエントリの中で空のものはすべて削除されます。 この場合の「空」の定義については、empty() 関数を参照して下さい。PHP: array_filter - Manual

<?php
$array = [
    'elm1' => '',
    'elm2' => [],
];

$filtered = array_filter($array);

var_dump($filtered); // []
var_dump(!$filtered); // true

参考

MAMPのMySQLでrootパスワードを再設定する

rootを「パスワード設定なし」にしたらエラーでMySQLに接続できなくなり再設定したのでメモ。

接続できません。設定が無効です。

mysqli::real_connect(): (HY000/1045): Access denied for user 'root'@'localhost' (using password: YES)

MySQL サーバに接続しようとしましたが拒否されました。config.inc.php のホスト、ユーザ名、パスワードが MySQL サーバの管理者から与えられた情報と一致するか確認してください。

config.inc.phpとの不一致からエラーが出るよう。

1. パスワードなしでmysqlにログインできるようにする

/Applications/MAMP/conf内にmy.cnfファイルを作成し、下記記述を追加して保存。

[mysqld]
skip-grant-tables

2. 'mysql'データベースのuserテーブル内のrootパスワードをSQLで再設定する

初期パスワードはrootなので、rootにしておくと3.の工程は不要。

UPDATE user SET authentication_string=password('新規パスワード') WHERE user='root';

3. config.inc.phpに記載のパスワードを2. で設定したパスワードに変更する

エラーメッセージにはディレクトリの記載がないので分かりづらい。

/Applications/MAMP/bin/phpMyAdmin5にあるconfig.inc.php内のパスワードを変更する。

- $cfg['Servers'][$i]['password']  = 'root';
+ $cfg['Servers'][$i]['password']  = '新規パスワード';

4. MAMPを再起動

これで直るはず。

参考

create-react-app/TypeScriptの環境構築

create-react-appの環境構築を効率化するため、備忘としてメモ。 大岡由佳 著 りあクト!【I.言語・環境編】【II.React基礎編】第3.1版を参考に行った。 こちらの書籍ではパッケージマネージャーにyarnを使用しているが、普段npmを使用しているためnpmで作業を行う。

環境・バージョン

  • MacBook Air M1 Monterey 12.1
  • Node.js v16.13.0
  • npm 8.1.0

1. create-react-appのインストール

create-react-appのインストールを行う。アプリケーション名はcra-ts-templateとした。 TypeScriptを使用するため、オプションとして--template typescriptを指定する。

npx create-react-app cra-ts-template --template typescript

インストール完了後、ターミナルの最後には下記メッセージが表示される。

We suggest that you begin by typing:

  cd cra-ts-template
  npm start

Happy hacking!

上記コマンドをターミナルに入力し、アプリケーションが立ち上がれば無事インストールできている。

これ以降、カレントディレクトリはcra-ts-templateとして話を進める。

2. TypeScriptのバージョン確認

create-react-appによってインストールされたTyepScriptのバージョンを確認する。 tsc -vで確認できる。tstypescriptではない点に注意。 今回は4.4.4だった。

tsc -v

補足:インストール済みのcreate-react-appを使用する場合

TypeScript及び関連パッケージを最新版に更新しておく必要がある。

TypeScriptのバージョンアップ

下記コマンドで行う。

npm update typescript@latest

関連パッケージのバージョンアップ

まず、npm outdatedで新しいバージョンがリリースされていないか確認する。create-react-appインストール後に行ってみた結果は以下の通り。

npm outdated

Package       Current    Wanted  Latest  Location                  Depended by
@types/node  16.11.19  16.11.19  17.0.8  node_modules/@types/node  cra-ts-template

node.jsのバージョンが16.13.0に対しバージョンが古いように見える。そのため、いったんアンインストールし@types/node@16.13.0のインストールを試みた。(更新が必要なパッケージが多数ある場合、npm-check-updatesを使うと良いよう。1

npm un @types/node
npm i -D @types/node@16.13.0

すると下記のエラー。

npm ERR! notarget No matching version found for @types/node@16.13.0.
npm ERR! notarget In most cases you or one of your dependencies are requesting
npm ERR! notarget a package version that doesn't exist.

@types/node@16.13.0は存在しないらしい。npmで確認しても16.11.19までしかないようなので再インストール。

npm i -D @types/node@16.11.19

これでとりあえずcreate-react-app及びTypeScriptの環境構築は完了。 次回以降、開発を行う上で便利なツール群の導入(ESLintなど)を行っていく。

参考

オリジンについて

<link rel="dns-prefetch">について調べる際、オリジンという言葉が出てきたためメモ。

概要

  • オリジンとは、URLのスキーム(プロトコル)・ホスト(ドメイン)・ポートをあわせたもの。
  • スキーム、ホスト、ポートが一致していれば同一オリジンと言える。
  • 関連する仕組みとして、同一オリジンポリシーCORSがある。

  • オリジン: http://example.com
  • スキーム: http
  • ホスト: example.com
  • ポート: 明示されていない場合、スキームがhttpの場合は80,httpsの場合は443

スキーム、ホスト、ポートが一致していれば同一オリジンと言える。

http://example.comhttp://www.example.comでは、ホストが異なるため同一オリジンとはみなされない。

関連する仕組み

  • 同一オリジンポリシー

あるリソースから他のオリジンのリソースにアクセスできないように制限するもの。セキュリティの面で重要な仕組み。

  • CORS(Cross-Origin Resource Sharing, オリジン間リソース共有)

オリジンを跨いだアクセスを許可するもの。(同一オリジンポリシーの緩和)

その他

プロトコル以外のスキームもある。例えばmailtojavascriptなど。

例)http://www.example.com

  • ホスト: ネットワークに接続された機器を指す。この場合ホスト名はwwwで、Webサーバを示している。
  • ドメイン: インターネット通信時の接続先を示す。この場合ドメイン名はexample.comとなる。
  • FQDN(Fully Qualified Domain Name, 完全修飾ドメイン名): ホスト名+ドメイン名を示す。

参考