使用 react-router jsx 的 Webpack 代码拆分

Webpack code splitting utilizing react-router jsx

我的路线是用 jsx 映射的。我使用 webpack 来捆绑东西,我想根据路由将输出的 js 文件分成块。

我试过 require.ensure 但 webpack 没有分割任何东西。最后它只生成一个包文件。我不确定我在这里做错了什么。我不想维护路线所在的 2 个地方。理想情况下,webpack 使用我已经定义的路由。

export const renderRoutes = () => (
  <Provider store={store}>
    <Router history={history}>
      <Route path='en' component={AppContainer}>
      <Route path='cart' getComponent={(location, cb) => {
        require.ensure([], (require) => {
          cb(null, require('./Cart/CartContainer'));
         });
       }}/>
        <Route path='checkout'>
          <Route path='shipping_address' component={ShippingAddressFormContainer} />
          <Route path='delivery_options' component={DeliveryOptionFormContainer} />
          <Route path='payment' component={PaymentContainer} />
          <Route path='review_order' component={ReviewOrderContainer} />
          <Route path='confirmation' component={ConfirmationContainer} />
        </Route>
      </Route>
    </Router>
  </Provider>
);

render(
  renderRoutes(),
  document.getElementById('react-root')
);

grunt 文件配置:

dev: {
        entry: [
          './<%= paths.src %>/javascripts/react/containers/Root'
        ],
        output: {
          path: path.join(__dirname, '<%= paths.dist %>/javascripts'),
          filename: 'bundle.js',
          chunkFilename: '[id].chunk.js',
          publicPath: '/en/'
        },
        devtool: 'cheap-module-source-map',
        plugins: [
          new webpack.optimize.CommonsChunkPlugin('bundle.js'),
          new webpack.optimize.OccurrenceOrderPlugin(), // Chunk ids by occurrence count. Ids that are used often get lower (shorter) ids.
          new webpack.DefinePlugin({
            'process.env': {
              'NODE_ENV': JSON.stringify('development')
            }
          })
        ],
        module: {
          preLoaders: [
            {
              test: /\.json$/,
              loader: 'json'
            },
          ],
          loaders: [
            {
              test: /\.js$/,
              loaders: ['babel'],
              exclude: /node_modules/,
              include: __dirname
            }
          ]
        }
      },

开发任务输出

        Asset     Size   Chunks             Chunk Names
    bundle.js  2.76 MB  0, 1, 0  [emitted]  bundle.js, main
bundle.js.map  3.17 MB  0, 1, 0  [emitted]  bundle.js, main

我看了一些教程,但这种情况似乎并不常见。

I talked to OP in chat, he showed me his entire code and I figured it out!

在你的代码中,你有类似的东西:

// ... Some imports here
import CartContainer from './Cart/CartContainer';
// ... More imports here

export const renderRoutes = () => (
    <Provider store={store}>
        <Router history={history}>
            // Some other routes here
            <Route path='cart' getComponent={(location, cb) => {
                require.ensure([], (require) => {
                    cb(null, require('./Cart/Container').default);
                });
            }} />
        </Router>
    </Provider>
);

现在你可能会看到它,但你是 "tricking" webpack,因为当你 import CartContainer(在第一行)时,你说的是 "ok, this chunk (the main) has CartContainer, please, add it to the bundle"。然后,当你使用 require.ensure 时,webpack 已经知道这个依赖被加载了(它去了主块)并且它不需要将它拆分成不同的块。

你只需要删除第一个导入,这样 webpack 就会知道你想要 CartContainer 在一个单独的块中!请注意,由于您使用的是 babel,因此在需要此额外块时需要添加 .default

希望对您有所帮助!