かもメモ

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

TypeScript CDN の jQuery を使いたい

テンプレートエンジンで直接 script を呼ぶ古代の環境の開発をしています。

前回 TypeScript を babel + webpack でトランスパイルできるようにしたのですが、なんとこのプロジェクトでは古の jQuery が使われていました!!!! CDN から読み込まれている jQuery を使用している箇所で TypeError になってしまうので TypeScript で CDN で読み込まれている jQuery を扱えるようにしたメモ (レガシー環境過ぎて誰得なんだ…)

Webpack で bundle しないための設定

Externals

The externals configuration option provides a way of excluding dependencies from the output bundles. Instead, the created bundle relies on that dependency to be present in the consumer's (any end-user application) environment. This feature is typically most useful to library developers, however there are a variety of applications for it.
Externals | webpack

externals に設定されているライブラリは import 文があってもライブラリがバンドルされない

webpack.config.js

module.exports = {
  // …
  externals: {
    jquery: 'jQuery',
  },
}

ProvidePlugin

Automatically load modules instead of having to import or require them everywhere.
ProvidePlugin | webpack

ProvidePlugin で指定されているライブラリは import 文を書かなくても自動的にロードされるようになる。
先の externals と併用することで import 文を書かなくても CDN で読み込んだ jQuery を使えるようになる

webpack.config.js

const { ProvidePlugin } = require('webpack');

module.exports = {
  // …
  plugins: [
    new ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
    }),
  ],
}

TypeScript で global の jQuery, $ の型エラーにならないようにする

webpack でのライブラリのバンドル問題は解決しましたが、TypeScript で jQuery(function($) {}); の様な箇所で jQuery の型が解決されずエラーになってしまいます。

CDN で使用する jQuery の型を設定する

$ npm i -D @types/jquery

global 変数として設定する

@types/global.d.ts

declare global {
  interface Window {
    jQuery: JQueryStatic;
    $: JQueryStatic;
  }
}

@types 内の型ファイルを tsconfig の対象に含める

tsconfig.json

{
  // … 
-   "include": ["src/*"],
+   "include": ["src/*", "@types/**/*"],
}

これで TypeScript でも CDN で読み込んでいる jQuery が型エラーにならず使えるようになりました!
TypeScript 環境にしたとはいえ jQuery でゴリゴリ webアプリみたいなことするコード書くのつら… (jQuery の書き方もう覚えてナス)


[参考]