babelでES5形式に変換されない件(書き途中)


この記事は自分用の備忘録です。
「今動けばよい」という思想のもとに書いています。

babelはES2015形式以降のものをES5に変換してくれるもの。と解釈していたのですが
「一般的なブラウザで動作する内容に変換する」というものであるようです。
なので、一般的なブラウザでサポート済みのものは変換されないようです。

npm install --save babel-cli

src/index.js
const myMap = new Map();
myMap.set("key", "value");
const mySet = new Set();
mySet.add("hoge");

console.log(myMap, mySet);

みたいのがあったとして、

package.json
"scripts": {
    "babel": "babel src -d out"
  }

を実行した結果を見ると

out/index.js
var myMap = new Map();
myMap.set("key", "value");
var mySet = new Set();
mySet.add("hoge");
console.log(myMap, mySet);

となった。
でも、ES2015非対応のブラウザでも動かしたいので、頑張ってみる。

create-react-appで試してみる。

create-react-app test
cd ./test
copy nul > .babelrc

babel-transform-runtimeは、create-react-app した時に一緒に入っているようなので、.babelrcを以下のように変更する。

.babelrc
{
  "plugins": ["transform-runtime"],
}

react-scriptがこのあたりのトランスパイルの処理をやってくれている。
webpackのコンフィグの設定はよく理解できていないけれど、
react-scriptsのwebpack.config.prod.jsにbabelrcを使うか使わないかを示すような定義があったので書き換える。

./node_modules/react-scripts/config/webpack.config.prod.js
           loader: require.resolve('babel-loader'),
            options: {
              // @remove-on-eject-begin
              babelrc: true, この行をfalseからtrueに変える
              presets: [require.resolve('babel-preset-react-app')],
              // @remove-on-eject-end
              compact: true,
            },
~中略~
結果を確認するのに邪魔なのでminifyなどしてる処理をコメントアウトしておく
// new webpack.optimize.UglifyJsPlugin({
    //   compress: {
    //     warnings: false,
    //     // Disabled because of an issue with Uglify breaking seemingly valid code:
    //     // https://github.com/facebookincubator/create-react-app/issues/2376
    //     // Pending further investigation:
    //     // https://github.com/mishoo/UglifyJS2/issues/2011
    //     comparisons: false,
    //   },
    //   mangle: {
    //     safari10: true,
    //   },
    //   output: {
    //     comments: false,
    //     // Turned on because emoji and regex is not minified properly using default
    //     // https://github.com/facebookincubator/create-react-app/issues/2488
    //     ascii_only: true,
    //   },
    //   sourceMap: shouldUseSourceMap,
    // }),

以上の変更を行った後

npm run build
をおこなうと

main_xxxxxxx.js
var myMap = new __WEBPACK_IMPORTED_MODULE_1_babel_runtime_core_js_map___default.a();
myMap.set("key", "value");
var mySet = new __WEBPACK_IMPORTED_MODULE_0_babel_runtime_core_js_set___default.a();
mySet.add("hoge");
console.log(myMap, mySet);

なんとなくそれっぽく変換されました。

しかし、自前で定義(今回の例だと./sec.index.js)したところは変換されていますが
react.development.js / react-dom.production.min.jsからrequireで変換されたところは変わらずにそのままSetなどが使われたままでした。

仕方ないので、自分でreact.development.js / react-dom.production.min.jsをES5形式に変換してみることにする。

mkdir trans_test
cd ./trans_test
npm init
mkdir src
npm install --save-dev webpack
npm isntall --save-dev webpack-cli
npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime
npm isntall --save fbjs
npm install --save react
copy nul webpack.config.js
copy nul .babelrc

./node_modules/react/cjs/react.development.jsを./src/にコピー

package.json
{
  "name": "trans_test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "webpack": "webpack"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.4",
    "babel-preset-env": "^1.6.1",
    "babel-runtime": "^6.26.0",
    "npm": "^5.7.1",
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.12"
  },
  "devDependencies": {
    "babel-plugin-transform-runtime": "^6.23.0",
  }
}

webpack.config.js
const path = require('path');

module.exports = {

  mode: 'development',
  entry: './src/cjs/react.development.js',
  output: {
    filename: './src/bundle.js',
    path: path.join(__dirname, 'public/js')
  },
  module: {
    rules: [{
      test: /\.js$/,
      exclude: /node_modules/,
      use: [{
        loader: 'babel-loader',
        options: {
          presets: ['env']
        }
      }],
    }],
  }
};

.babelrc
{
  "plugins": [
    ["transform-runtime", {
      "helpers": true,
      "polyfill": true,
      "regenerator": true,
      "moduleName": "babel-runtime"
    }]
  ]
}

npm run webpack

を実行するとreact.development.jsがES5形式に変換された。
変換してできたやつ(bundle.js)を
./node_modules/react/cjs/react.development.jsにリネームしてコピーしておく。

次、
./node_modules/react-dom/cjsの中身を./srcにコピー
webpack.config.jsのEntryの変更。
js:webpack.config.js
entry: './src/cjs/react-dom.production.min.js',

npm run webpack

これで変換したやつをtestプロジェクトnode_modules/react-dom/cjs/react-dom.production.min.js
にリネームして差し替えればいい感じに動くのではないだろうか?

こんなに何を頑張っているんだろう。という気になっていますが、
とりあえず今だけ動けばよいの思想でもう少し頑張ります。