• ..

TypeScript

    commonjs で esnext なパッケージを一緒に使う

    対象

    cjs で書かれている。つまり以下のように書かれてるもの。例えば、sindresorhus/ky

    module.exports = /* ... */

    esnext なobject-rest-spread-propertiesなどが使われてる。

    // 例: ky/index.js
    returnValue = {...returnValue, [key]: value};

    問題

    • 対象のファイルを Babel で変換しないとエラー
    • 依存のnext-babel-loaderの中でnextが読み込む.babelrcの設定がmodules:falseなので変換できても cjs が解決できない
    • next.config.js上で Babel の設定を上書きできない
    • .babelrcでは処理的に 1 つの設定しか持てない
    • 自分のソースコードは cjs にしたくない
      webpack(config, {isServer}) {
        if (isServer) {
          return config;
        }
    
        config.module.rules.map(rule => {
          if (
            rule.test.test('.js') &&
            Object.prototype.hasOwnProperty.call(rule, 'exclude') &&
            rule.exclude.test('node_modules')
          ) {
            rule.exclude = /node_modules\/(?!ky)/;
            // Module build failed: Error: Duplicate plugin/preset detected.
            rule.options = {
              presets: ['next/babel', {
                'preset-env': {
                  modules: 'commonjs'
                },
              }]
            }
          }
          return rule;
        });
    
        return config;
      },

    解決

    やっぱりこれだけにルール追加するぐらいしかなかった。(読み込んでるプラグインなどはデフォルトの設定と同じもの)

      webpack(config, {isServer}) {
        if (isServer) {
          return config;
        }
    
        config.module.rules.unshift({
          test: /\.jsx?$/,
          include: /node_modules\/ky/,
          use: {
            loader: 'babel-loader',
            options: {
              presets: ['@babel/preset-env'],
              plugins: [
                '@babel/plugin-proposal-class-properties',
                '@babel/plugin-proposal-object-rest-spread',
                '@babel/plugin-transform-runtime',
              ],
            },
          },
        });
    
        return config;
      },