jasan jasan - 2 months ago 35
React JSX Question

Code splitting with Webpack

My current Route description looks as follows for one of my routes:

<Route path='auth' component = {AuthenticateContainer} onEnter = {checkAuth}/>


In order to split code for route paths I beleive the code may looks like this:

<Route path="auth" getComponent={(nextState, callback) => {
require.ensure([], function(require) {
callback(null, require('./AuthenticateContainer.js').default);
})
}}/>


But What I'm missing is the OnEnter checkAuth Function, how do I include it ?

Answer

If you have checkAuth in ./AuthenticationContainer.js then move it to routes.js or create a new js file and require it in routes.js. Basically, the function to be run on onEnter hook has to be present before requiring component using getComponent.

My routes.js looks like this-

import React from 'react';
import { Route } from 'react-router';

export default (store) => {
  function requireAuth(nextState, replace) {
    if(!store.getState().auth.isAuthenticated) {
      replace({
        pathname: '/',
        state: { nextPathname: nextState.location.pathname }
      })
    }
  }

  return { childRoutes: [{
      path: '/',
      getComponents(location, callback) {
        require.ensure(['./containers/App/App.jsx'], function (require) {
            callback(null, require('./containers/App/App.jsx').default)
        })
      },
      childRoutes: [{
        path: 'about',
        onEnter: requireAuth,
        getComponents(location, callback) {
          require.ensure(['./containers/About/About.jsx'], function (require) {
              callback(null, require('./containers/About/About.jsx').default)
          })
        }
      }]
    }]
  }
};

I am not sure if you can call checkAuth inside require.ensure and stop the component from being loaded if it isn't authenticated. By design, this is a bad approach since you are loading the component and then checking if it's authenticated. This negates the benefits of code splitting.

Edit - Adding webpack.config.js

var webpack = require('webpack');
var path = require('path');

var BUILD_DIR = path.resolve(__dirname, 'build');
var APP_DIR = path.resolve(__dirname, 'src');

var config = {
  entry: APP_DIR + '/index.jsx',

  output: {
    path: BUILD_DIR,
    filename: 'bundle.js',
    chunkFilename: '[id].chunk.js',
  },

  devtool: 'inline-source-map',

  module : {
    loaders : [
      {
        test : /\.jsx?/,
        include : APP_DIR,
        loader : 'babel'
      },
      {
        test: /\.css?$/,
        loaders: [ 'style', 'raw' ],
        include: __dirname
      }
    ]
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin('shared.js')
  ]
};

module.exports = config;

Webpack build output -

webpack -d --watch

Hash: 08b101d1e95f7633adb4
Version: webpack 1.13.2
Time: 2680ms
         Asset     Size  Chunks             Chunk Names
     bundle.js  1.05 MB    0, 3  [emitted]  main
    1.chunk.js  4.15 kB    1, 3  [emitted]  
    2.chunk.js  3.19 kB    2, 3  [emitted]  
     shared.js  3.66 kB       3  [emitted]  shared.js
 bundle.js.map  1.16 MB    0, 3  [emitted]  main
1.chunk.js.map  2.32 kB    1, 3  [emitted]  
2.chunk.js.map  1.18 kB    2, 3  [emitted]  
 shared.js.map  3.67 kB       3  [emitted]  shared.js
    + 269 hidden modules