今日JavaScript(Node.js)を書いていたときに遭遇した出来事を備忘録がてら書き残しておく。
エラーになったコード
下記のコードはエラーになる。
const fs = require('fs')
(async () => {
console.log(fs)
})()
実行結果
(async () => {
^
TypeError: require(...) is not a function
上のエラーを解決させたコード
JavaScriptは;
を書こうが書かまいがが動く、と思っていたが、1行目の末尾に ;
をつけることで、今回のコードは問題なく動くようになる。
const fs = require('fs');
(async () => {
console.log(fs)
})()
※実行結果は長くなるので省略。サンプルコードが悪かった...
"TypeError: require(...) is not a function"が出る仕組み
これはどういうことかなと思ったけど、考えてみれば単純なことだった。
JavaScriptは文末にセミコロンを付けなかった場合、その後の文が構文的に解釈可能な場合、解釈しようとする。
自分もここらへんは自信がないので、JavaScript Primer の記述も引用させていただく。
JavaScriptには、特殊なルールに基づき、セミコロンがない文も行末に自動でセミコロンが挿入されるという仕組みがあります。 しかし、この仕組みは構文を正しく解析できない場合に、セミコロンを足すという挙動を持っています。 これにより、意図しない挙動を生むことがあります。そのため、必ず文の末尾にはセミコロンを書くようにします。
引用元のページ: https://jsprimer.net/basic/statement-expression/#statement-expression-summary
つまり先ほど私が書いたコードは下記のように解釈された形となる。
// require('fs')(/* ~ */) 的な解釈となっていた
const fs = require('fs')(async () => {
console.log(fs)
})()
余談: prettierでセミコロンを付けない設定をした際の挙動
気になったので試してみた。
prettier
の設定で semi: false
にしたとき、;
はどこにつくのか?
結果は下記の通り。
const fs = require('fs')
;(async () => {
console.log(fs)
})()
あとがき
普段 ;
は付ける派なのだが、なんとなくプロトタイプのコードを書いていてつけないでいた。後から prettier
かければ済む話だとか考えていたら、思わぬエラーに引っかかった。
おかげでJavaScriptのことを少し知ることができたので結果的に良かったと思う。