0

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 ?

jasan
  • 11,475
  • 22
  • 57
  • 97

1 Answers1

1

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
Arjun Hariharan
  • 320
  • 2
  • 9
  • Arjun , wouldn't this mean that anytime the user visits the 'about' path the codesplitting for About.jsx wouldn't benefit much since the requireAuth still resides in the main chunk JS file and is required everytime. – jasan Sep 28 '16 at 19:22
  • Also, do i need to modify my webpack config? because event after adding require.ensure the webpack -p did not create any extra js files – jasan Sep 28 '16 at 20:47
  • @jasan - You can keep your login/signup form and related functions in AuthenticationContainer.js and checkAuth in the main chunk since you will always run checkAuth to see if the user is logged in before moving to a new route. I see checkAuth as a helper utility which is required by the entire app and not just one or 2 containers. Note - You are still splitting your code. AuthenticationContainer will run only when the user isn't logged in. If the user needs to login to the app always, then it makes no sense to split AuthenticationContainer into a chunk since it's always needed. – Arjun Hariharan Sep 29 '16 at 03:10
  • thanks , that makes sense. However for some reason Even with these defined split points, webpack only generates one single bundled file. – jasan Sep 29 '16 at 03:14