かもメモ

自分の落ちた落とし穴に何度も落ちる人のメモ帳

JavaScript, Node.js 先に作っておいた変数を named export したい

default exports は好きな名前で import できてしまうから極力 named exports / import にしたほうが良いと教えてもらったので、先に変数が作られてる場合どうするんだろう?と思い調べて見たメモ。

ESModules の named exports

exports

// foo.ts
export const foo = 'Foo!';

import

import { foo } from './foo'

ESModules の default exports

exports

// app.ts
import express = require('express');
const app: express.Express = express();

export default app;

import

import app from './app'

default exports は好きな名前で import できる

import myapp from './app'
myapp; // => express.Express

先に作っている変数を named exports したい

// app.ts
import express = require('express');
const app: express.Express = express();
app.use(...); 
// … 色々処理

export app;
// => Error: Declaration or statement expected.

これはDeclaration or statement expected. エラーになる。

export { } で named exports することができる

// app.ts
import express = require('express');
const app: express.Express = express();
app.use(...); 
// … 色々処理

export { app };

import

import { app } from './app';

₍ ᐢ. ̫ .ᐢ ₎👌

as を使えば名前を変えてnamed exports することもできる

// app.ts
import express = require('express');
const app: express.Express = express();

export { app as myapp };

import

import { app } from './app';
// => Error: Module '"./app"' declares 'app' locally, but it is exported as 'myapp'.

TypeScriptでは myapp で exports されているけど?というエラーを表示してくれる。
₍ ᐢ. ̫ .ᐢ ₎👌

default exports は default という特別な名前を付けた named export だった。

export default app;

これは下記と同じ意味

export { app as default };

e.g.

// app.ts
import express = require('express');
const app: express.Express = express();

export { app as default };

import

import { app } from './app';
// => Error: Module '"./app"' has no exported member 'app'. Did you mean to use 'import app from "./app"' instead?

TypeScriptでは import app from "./app" では?というエラーを表示してくれる。
₍ ᐢ. ̫ .ᐢ ₎👌

import

import app from './app';
// 👌

₍ᐢ •̥ ̫ •̥ ᐢ₎‪ 完全に理解した!

感想

import / exports 周り完全に雰囲気で使っているのでチョクチョクあれ?どうやるんだっけ???になってます。
ESModules と CommonJS の import / export, require / module.exports いつかちゃんと調べようと思いつつ数百年が立ってしまった… そして未だに雰囲気でしか理解してない。。。

TypeScript まだよわよわなんで頑張っていきたい。
チョットづつエラーも読めるようになってきた。


[参考]

ハンズオンNode.js

ハンズオンNode.js

  • 作者:今村 謙士
  • 発売日: 2020/11/17
  • メディア: 単行本(ソフトカバー)

Node.jsデザインパターン 第2版

Node.jsデザインパターン 第2版

Firebase Cloud Firestore で複数の OrderBy で 9 FAILED_PRECONDITION: The query requires an index なエラーになった

Cloud Firestore からデータを取ってこようとしたら次のようなエラーが返ってきた。

{
  error: {
    code: 9,
    details: "The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/<projectName>/firestore/indexes?...",
    message: "9 FAILED_PRECONDITION: The query requires an index. You can create it here: https://console.firebase.google.com/v1/r/project/<projectName>/firestore/indexes?...",
    metadata: …
  }
}

9 FAILED_PRECONDITION なエラーになるコード

const db = admin.firestore();

const snapshot = await db
  .collection(COLLECTION)
  .orderBy('score', 'asc')
  .orderBy('createAt', 'asc')
  .get();

どうやら orderBy() が複数個あるとエラーになってしまうようでした。

Cloud Firestore にインデックスが作成されてないとエラーになる

エラーを見ていると The query requires an index. You can create it here: https://console.firebase.google.com/... と書かれていました。
エラーに続く URL にアクセスすると Firebase コンソールから Cloud Firestore にインデックスを作成するか聴かれるモーダルが表示されます。そのまま作成ボタンを押すとインデックスが作成されます。

firebase Cloud Firestore console

インデックスのビルドに少し時間がかかりますが、ステータスが 有効 になればインデックスが有効になり先の 9 FAILED_PRECONDITION になっていたクエリが実行できるようになりました。

インデックスが必要だと分かっている場合は、コンソールから前もってから作成しておくのが良さそうです。
インデックスが全く作成されていないプロジェクトなら Cloud Firestore のインデックス タブを選択して インデックスを作成ボタン から作成することができます。

firebase Cloud Firestore console

所管

複数のフィールドで並べ替えを行うこともできます。たとえば、州で並べ替え、各州の中で人口の降順で並べ替える場合は、次のようにします。

citiesRef.orderBy("state").orderBy("population", "desc");
cf. Order and limit data with Cloud Firestore  |  Firebase

公式ドキュメントに orderBy() を複数使う例が載っていて、そこにインデックスが必要なことが書かれていなかったので、そもそも Firestore に接続できてないのか?なども疑ってハマってしまいました。
Firebase のドキュメント総じて分かりにくい気がしてるのは僕だけ?
そして作成されたインデックスの削除の方法が分からない…


[参考]

ナイン (講談社文庫)

ナイン (講談社文庫)

VSCode 保存時に Prettier の自動フォーマットが効かなくなった件

コードのフォーマット揃ってないとʕ•ﻌ•ʔムキッってなっちゃうけど、手作業でフォーマットするのは面倒くさいダメ人間です。
./vscode/settings.json"editor.formatOnSave": true を指定していたのだけど、保存時に Prettier が効かなくなってたので動くようにしたのメモ。

環境

editor.defaultFormatter に esbenp.prettier-vscode を指定すればOK

.vscode/settings.json

{
  "editor.defaultFormatter": "esbenp.prettier-vscode", // この行を追加する
  "editor.formatOnSave": true,
  …
}

₍ ᐢ. ̫ .ᐢ ₎ AWESOME

特定の言語のときだけ Prettier を ON / OFF にできる

editor.defaultFormatternull にすると Prettier を OFF にできる。
例えば JavaScript のときだけ有効にするなら次のように設定すればOK

.vscode/settings.json

{
  "editor.defaultFormatter": null,
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "editor.formatOnSave": true,
  … 
}

これで VSCode で何故か Prettier が動かなくなっていた問題解決しました!
設定にもチョットだけ詳しくなれたのでハマってよかったです。
面倒だからナントカシタイってモチベーションが学びの元〜!!!


[参考]

この本ほしい〜 (積本になるから我慢…)