• ..

CircleCI

    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で囲むことにします。