webpackでbuildされるファイルがデカすぎてつらい時(分割されすぎてつらい時も後述)

:writing_hand: Code-Splitting

Note: The dynamic import() syntax is a ECMAScript (JavaScript) proposal not currently part of the language standard. It is expected to be accepted in the near future.

npx create-react-app my-app
cd my-app
# 邪魔
rm src/*.css src/App.test.js src/logo.svg src/registerServiceWorker.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";

ReactDOM.render(<App />, document.getElementById("root"));
import React, { Component } from "react";

class App extends Component {
  render() {
    return <div />;
  }
}

export default App;
yarn build
# ...
# File sizes after gzip:
#  36.22 KB  build/static/js/main.cb06ce91.js
yarn add ramda lodash underscore
import React, { Component } from "react";
import * as R from "ramda";
import * as _ from "lodash";
import * as us from "underscore";

class App extends Component {
  render() {
    return (
      <div>
        {R.always("aaaa")}
        {_.join(["a", "b", "c"], "~")}
        {us.now()}
      </div>
    );
  }
}

export default App;
yarn build
# ...
# File sizes after gzip:
#  75.55 KB (+39.52 KB)  build/static/js/main.5c0f838b.js
// before
import { add } from "./math";

console.log(add(16, 26));

// after
import("./math").then(math => {
  console.log(math.add(16, 26));
});
yarn add react-loadable
import React from "react";
import ReactDOM from "react-dom";
import Loadable from "react-loadable";

const LoadableApp = Loadable({
  loader: () => import("./App"),
  loading: () => <div>Loading...</div>
});

ReactDOM.render(<LoadableApp />, document.getElementById("root"));
yarn build
#File sizes after gzip:
# 40.29 KB              build/static/js/0.ab70241c.chunk.js
# 37.81 KB (-37.74 KB)  build/static/js/main.0a2572c6.js
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import Loadable from "react-loadable";

const Loading = () => <div>Loading...</div>;

const Home = Loadable({
  loader: () => import("./routes/Home"),
  loading: Loading
});

const About = Loadable({
  loader: () => import("./routes/About"),
  loading: Loading
});

const App = () => (
  <Router>
    <Switch>
      <Route exact path="/" component={Home} />
      <Route path="/about" component={About} />
    </Switch>
  </Router>
);
yarn eject
yarn
...
plugins: [
    ...,
    new webpack.optimize.LimitChunkCountPlugin({
      maxChunks: 1
    }),
  ]
...
yarn build
#File sizes after gzip:
# 76.97 KB (+39.16 KB)  build/static/js/main.7748b8f8.js

:moyai: 「...2MB の JS ファイルは流石にやりすぎましたわ」