Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Code Splitting #19

Closed
codepunkt opened this issue Dec 20, 2016 · 4 comments
Closed

Code Splitting #19

codepunkt opened this issue Dec 20, 2016 · 4 comments

Comments

@codepunkt
Copy link

Is there a way to use route-based code splitting with ui-router/react?

@elboman
Copy link
Member

elboman commented Dec 22, 2016

Sure! UI-Router Core 1.0 introduced future states and lets you lazy load them when needed.
All you need to do is declare the future state:

{
  name: 'lazy',
  url: '/this-is-lazy',
  lazyLoad: () => System.import('./lazyLoadState')
}

The lazyLoadState file must declare the state that will replace with the future-state (that acts as a placeholder) and export a default object with a states attribute.

import MyComponent from './MyComponent';
const state = {
  name: 'lazy',
  url: '/this-is-lazy',
  component: MyComponent
};
export default { states: [state] }

Note that the syntax for lazy loading a JS module depends on the bundler you use. Since the lazyLoad function in your state declaration requires you to return a promise, verbosity may change drastically based on your module bundler: Webpack 2 supports System.import() as well as import(), while webpack 1.x supports the verbose require.ensure() syntax which isn't promise-based.

This doesn't prevent you from writing a small helper function to reduce this verbosity:

const lazyLoadModule = (moduleName) => new Promise((resolve, reject) => {
  require.ensure([], () => { resolve(require(moduleName).default) });
});

const state = {
  name: 'lazy',
  url: '/this-is-lazy',
  lazyLoad: () => lazyLoadModule('./lazyLoadState')
}

In any case I wrote a small working example, hope it helps: http://www.webpackbin.com/Ekiu1rHNz

Also, you can take a look at the core documentation regarding future states here: https://ui-router.github.io/docs/latest/interfaces/state.statedeclaration.html#lazyload

Let me know if you have any doubt

@elboman elboman closed this as completed Jan 25, 2017
@MichaelBuen
Copy link

MichaelBuen commented Jun 17, 2017

http://www.webpackbin.com/Ekiu1rHNz link is no longer working

image

I tried the code-splitting with @uirouter/react. The chunk is loading in network tab, however for some reason the component is not rendering in the page. @uirouter/react works if there's no code-splitting. if I put the component directly on state's component property. Is there any plugins that I missed or something?

@MichaelBuen
Copy link

MichaelBuen commented Jun 17, 2017

I'm thinking the code-splitting's problem is caused by using module: commonjs in tsconfig.json. However if I set it to umd, TypeScript complains:

image

Here's my router states, app component is loaded via _import:

const states = [{
    name    : 'home.**',
    url     : '/home',
     // component: App
    lazyLoad: () => _import('../components/App')
}];

Here's the components/App:

window.alert('yay');

const state = {
    name: 'home',
    url: '/home',
    component: App
};

export default { states: [state] };

The chunk loads, window.alert('yay') run. The window.alert in App's constructor didn't though. It seems that the component property of future state is not being swapped to original state.

Is there a plunker or webpackbin example with code-splitting usage, and also with otherwise?

I have good experience with ui-router in Angular 1.x and lazy-loading with it using ocLazyLoad. I'm thinking if I can use @uirouter/react with lazy-loading despite being 0.5.0 version.

@brendanmckeown
Copy link

@MichaelBuen and for anyone else who stumbles upon this issue, I fixed this by exporting a states array from the lazy-loaded module, instead of exporting the default.

const state = {
    name: 'home',
    url: '/home',
    component: App
};

export const states = [state];

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants