ProvidePlugin を使って import を書く回数を減らす

例えば React を JSX で書いているプロジェクトであれば JSX を使っているファイルでは必ずimport React from 'react';のような書かなければいけません。( JSX 部分は変換されてReact.createElementを使うようになる為)

設定する

ProvidePluginwebpackモジュールに付属しているので新たにインストールする必要はありません。これをpluginsセクションの中に置きます。

{
  // ...略
  plugins: [
    new webpack.ProvidePlugin({
      React: 'react'
    })
  ]
}

ProvidePluginはオブジェクトを引数に取ります。その中にReact: 'react'と置いた場合、「reactモジュールをReactという名前でどこでも使えるようにするよ」という意味になります。JavaScript の場合設定はこれだけでどこでもReactが使えるようになっているはずです。

ちなみに、どこでもはwebpackのビルド対象ファイルだけで、window.Reactという形にはならないので安全です。
対象のファイルをラップする親スコープがあり、そこにreact-WEBPACK-IMPORTED-MODULE-1-defaultのような名前の関数が生えています。この関数は実行後にReactモジュールを返し、これをReactという名前で置く親スコープ内に置くことで使えるようになっているのだと思います。

ESLint を使っている場合はreact/react-in-jsx-scopeが引っかかるようになるかもしれません。これは"react/react-in-jsx-scope": 0と ESLint のファイルに追記して無効化できます。

TypeScript 対応

TypeScript でどこでもReactを使おうとすると、そのままではany型になってしまいます。コード上ではいきなり現れた謎変数な為です。これにはアンビエント宣言(Ambient Declarations)を定義したファイルを作る必要があります。その中身は「どこでも出てくるReactとは何ぞや」です。

アンビエント宣言はd.tsという拡張子で作ります。「どこでも出てくる」は、つまりglobalということなのでd.tsの置き場所はtsconfigincludeパターンに含まれるか、filesの中に置かれていればどこでも大丈夫です。

Reactだけならこれだけです。

import React from 'react';

// global 空間を拡張
declare global {
    const React: typeof React;
}

これでどこでも型付きReactが使えるようになったはずです。

ちなみにこっちは良くわからないですが駄目です。

import * as React from 'react';

declare var React: typeof React;

使った時にこのように警告されます。

'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.

「〜 import instead」この内容だと振り出しに戻るので却下です。なんだか難しいですが、モジュールのグローバル定義はdeclare globalで囲むことにします。