やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

JavaScript開発しているときにハマったこと

 最近やっててハマった代表的なものをメモる。

前回

 上記を書いててハマったことをまとめる。

開発段階ごとにある困難

 JSはさまざまな動作環境がある。すでにそれだけで混乱する。加えて、それぞれの環境において別の問題がある。

環境 問題
ブラウザのみ ES Module、fetch APIなどが動作しない(CORSエラー)
ローカルサーバ(python3 -m http.server 8000) ES Moduleなどは未実装のため古いブラウザで動作しない
webpack + babel 開発環境を整えるのが超大変
(上記いずれか1つ)+デプロイ GitHubPagesによる謎エラー(ローカルでは動いてたのに動かなくなる)

 はじめは環境構築が面倒なのでブラウザだけで進める。しかし動作しないAPIなどがあって仕方なくローカル鯖を使う。遊ぶだけならここまでで十分。しかし、今後とも使えるライブラリを開発したいとか、それをCDNにしたいとなると以降の困難にむきあわねばならない。

CORSエラー

 JS書いていると頻出するエラー。セキュリティのために用意されたエラーである。他のドメインのファイルを使わないようにするって感じだったと思う。詳しくは知らん。

 ローカル鯖を立てることで解決する。開発中は本番用サーバーにアップできない。仕方なくローカルサーバを立ち上げて確認する。よく以下のようなコマンドが使われる。

python3 -m http.server 8000
npx webpack serve

ES Module

 JSを外部ファイル化し、importで依存関係を解決するしくみ。従来はHTMLに<script src="">を依存関係の順に正しく網羅せねばならなかった。ES Moduleを使えばJS内に依存コードを書ける。<script src="./main.js" type="model">ひとつだけHTMLに書けば良い。

 CORSエラーになる。ローカルで実行するとCORSエラーになる。なのでローカル鯖を立ち上げて確認せねばならない。面倒。

 ES Module対応ブラウザが少ない。なので従来のコードを書くか、webpackを使って1ファイル化することで解決する。

 場合によってはローカルサーバ不要。webpackを使い、かつfetch APIなどサーバ通信が必要なAPIが使われていなければ、ローカルサーバを立ち上げる必要がなくなる。この場合分けを考えるのがきわめて困難。なので結局、従来コードを書くか、webpack+ローカル鯖という二極化になってしまう。どちらもそれぞれに困難がある。

fetch API

 今回、<code src="">にて外部ファイルを参照するようにした。このとき外部ファイルにアクセスするため fetch API を使った。こいつはローカルサーバを立ち上げていないとエラーになってしまう。結局、ローカルサーバを立ち上げるという面倒をせねば動作確認すらできない。

webpack + babel

 ビルドが大変。babelのプラグインをインストールし、設定ファイルに指定する必要がある。さもなくばエラーになる。ローカルではそんなことせずとも動くのに、webpackでビルドするためにはそれらが必要になる。これはwebpack + babelが最新コードを古いブラウザでも動作するよう旧式コードに変換するためである。必要だとはわかっているけど面倒くさい。

npm init -y
npm i -D webpack webpack-cli webpack-dev-server babel-loader @babel/core @babel/preset-env @babel/plugin-proposal-private-methods @babel/plugin-proposal-class-properties
npx webpack
npx webpack serve
module.exports = {
  mode: "production",
  entry: "./src/CodeTag.js",
  output: {
    library: 'CodeTag',
    libraryExport: 'default',
    libraryTarget: 'var',
    filename: 'CodeTag.js',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: [
          {
            loader: "babel-loader",
            options: {
              presets: [
                // ES2020 を ES5 に変換
                "@babel/preset-env",
              ],
              plugins: [
                // private # を使えるようにする
                "@babel/plugin-proposal-private-methods",
                "@babel/plugin-proposal-class-properties",
              ],
            },
          },
        ],
      },
    ],
  },
  // ES5(IE11等)向け
  target: ["web", "es5"],
};

デプロイで謎エラー

 リポジトリを作ったらGitHubPagesをつくる。settingdocs/にしてsaveボタンを押す。すると以下のようなエラーが出た。

balanced-match の README にある {{1}} の{ が正しく閉じられていません

 わけがわからん。ただ、node_moduleをまるごとアップしてしまったのがダメっぽい。こいつらはビルドするときに必要なのであって、ビルド後は不要。なので余計なファイルを削除することで解決した。

URL切れになった

 Highligh.jsのCSSを参照しようとしたら、なぜかできなかった。

./docs/node_modules/highlight.js/styles/default.css

 以下のようにすると参照できた。謎。

./styles/default.css