react-router-huge-apps-refactor icon indicating copy to clipboard operation
react-router-huge-apps-refactor copied to clipboard

how to merge chunks in one page

Open starInEcust opened this issue 9 years ago • 5 comments

how to merge AssignmentsSidebar and Assignments in one chunk?

starInEcust avatar Jun 18 '16 06:06 starInEcust

Similar question: What if I want to pre-load some of the child-routes (for a given route) rather than individually requesting each one (as they have a tiny footprint)?

IstoraMandiri avatar Jul 04 '16 11:07 IstoraMandiri

@starInEcust @hitchcott You could manually define each chunk in the webpack config instead of using a regex? Something like:

// change this to an array of files 
var chunks = [
  path.resolve(__dirname, './src/routes/Calendar.js'),
  path.resolve(__dirname, './src/routes/Grades.js'),
  path.resolve(__dirname, './src/routes/Messages.js'),
  path.resolve(__dirname, './src/routes/Profile.js'),
  path.resolve(__dirname, './src/routes/Course/Course.js')
];

module.exports = {
  // etc...
  module: {
    loaders: [
      // make sure to exclude route components here
      {
        test: /\.js$/,
        include: path.resolve(__dirname, 'src'),
        exclude: chunks,
        loader: 'babel'
      },
      // lazy load route components
      {
        test: /\.js$/,
        include: chunks,
        loaders: ['bundle?lazy', 'babel']
      }
    ]
  },
  // etc...
}

Then in app.js you'll have to remove the lazyLoadComponent() function call around any routes not defined in the webpack config.

echenley avatar Jul 04 '16 19:07 echenley

Many thanks for the response!

Although I'm still not sure how I would be able to use this to acheive the following:

/Dashboard (not lazyloaded)
/SomeModule (lazyloaded)
/Accounts/ (lazyloaded + all children)
/Accounts/Profile (pre-loaded when landing on /Accounts/*)
/Accounts/SomeOtherRoute (pre-loaded when landing on /Accounts/*)
/Accuonts/SomeOtherRoute2 (pre-loaded when landing on /Accounts/*)

Basically I want fast navigation between /Accounts/Profile and /Accounts/SomeOtherRoute without a round-trip, by bundling those sibling routes together whenever someone lands on one.

I understand with this non-regex approach I could create a specific chunks (rather than implicit folder structure), but for pre-loading the the child route components, what would the route definitions of the children look like?

IstoraMandiri avatar Jul 05 '16 00:07 IstoraMandiri

The split happens at the module level, so you could make an extra module that re-exports the others, e.g.:

// accountRoutes.js
// this module will be the split point
export Profile from './Profile';
export SomeOtherRoute from './SomeOtherRoute';

And in app.js you'll need a different function to load this type of module:

// app.js
import accountRoutes from './accountRoutes';

// load a single module containing multiple routes
function lazyLoadComponentsFromModule(lazyModule, routeNames) {
  return (location, cb) => {
    lazyModule(module => {
      cb(null, routeNames.reduce((routes, name) => {
        routes[name] = module[name];
        return routes;
      }, {}));
    });
  };
}

<Route
  path="whatever"
  getComponents={ lazyLoadComponentsFromModule(accountRoutes, ['Profile', 'SomeOtherRoute']) }
/>

And then add accountRoutes.js to your chunks array in webpack.config.js.

// webpack.config.js
var chunks = [
  path.resolve(__dirname, './src/routes/accountRoutes.js'),
  // ...etc
];

I haven't tested this code, but I think the idea would work.

echenley avatar Jul 05 '16 03:07 echenley

Thanks a lot for your idea, I'll try it; @hitchcott if you have done it, please upload your code - -!

starInEcust avatar Jul 05 '16 09:07 starInEcust