11

I'm using require.ensure to create split points at react-router paths. However, my build directory still only has app.js in addition to the vendor.js. I was expecting a separate js file for each path I used require.ensure.

I used require.ensure at each path like this:

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

my web pack config output for build looks like this:

output: {
  path: PATHS.build,
  filename: '/[name].[chunkhash].js',
  chunkFilename: '/[chunkhash].js'
}

Here are the gists of my route file and my webpack config file in their entirety.

UPDATE: I figured out what I was doing wrong. My project structure for containers is like so:

-app
 -containers
   -containerA.
     -containerA.js
   -containerB
     -containerB.js
   -containerC
     -containerC.js
   -index.js

The issue: I was still exporting the containers I was requiring in routes file like so: export containerB from './containerB/containerB' Removing the export in the index.js and requiring straight from the containerB.js did the trick.

jasan
  • 11,475
  • 22
  • 57
  • 97

3 Answers3

1

Ensure takes an argument array of modules you want to require. You need to supply the array with the module names you wish to dynamically load. In your case, provide 'containers/Authenticate/AuthenticateContainer.js' to ensure like this:

require.ensure(['containers/Authenticate/AuthenticateContainer.js'], (require) => {
      callback(null, require('containers/Authenticate/AuthenticateContainer.js').default)
    }, 'auth');
cgatian
  • 22,047
  • 9
  • 56
  • 76
  • adding that makes no difference to the build directory. – jasan Sep 29 '16 at 02:32
  • is there something in the webpack config i need to include for it to work. – jasan Sep 29 '16 at 02:44
  • If you copied verbatim I missed a single quote at the end. No there shouldnt be anything else you need to configure. – cgatian Sep 29 '16 at 13:31
  • @jasan please let us know what happened – Dimitris Karagiannis Oct 05 '16 at 10:52
  • @MitchKarajohn I have not yet solved this problem. One option I do have is to upgrade to webpack 2.0 and use the new system.imports but that would also require me to make lot of other changes in my config. Thus i'm holding off on that. – jasan Oct 05 '16 at 11:23
  • Ill spin up a sandbox today to see whats up. If you have the time commit your code to github and I can take a look. – cgatian Oct 05 '16 at 12:26
  • @cgatian I have already linked the config and routes files. Are they not enough? – jasan Oct 07 '16 at 09:55
0

I had the same problem on one of my project : we used Systemjs and decided to switch to Webpack, so it broke our System.import. We fix it by replacing :

System.import(modulePath)
  .then(module => {
    // Do things
  })

With :

new Promise((resolve, reject) => {
    resolve(require(modulePath));
}).then((module) => { 
  // Do things 
});

Hope this helps

Richard Casetta
  • 346
  • 1
  • 7
0

i am using webpack 1.13.1 and here is my config

output: {
        path: PATHS.build,
        filename: '[name].[hash].js',
        publicPath:"/"
    },

here is the code for get component

const lazyLoadSomeComponent = () => {
  return {
      getComponent: (location, callback)=> {
        require.ensure([], require => {
          callback(null, require("./componentpath")["default"]);
        }, 'componentName');
      }
    }
};

Then in route

<Route path="somepath" {...lazyLoadSomeComponent()} />

But Whats going here ?

  • First we create a function that will return the get component Method for us.
  • Second we call that function in route and execute it so we get the get component Method there , this will make routes easy to read
  • Last in webpack specify the public path so "/" here resolves from root of your server, you can also specify your domain here

For Further Enhancement we can load multiple component at once using below method

const LazyComponents = (pageName) => {
  return {
      getComponent: (location, callback)=> {
        require.ensure([], require => {
          switch(pageName){
            case 'Component1':
            callback(null, require("./components/component1")["default"]);
            break;
            case 'Component2' :
                callback(null, require( "./components/component2" )["default"]);
                    break ;

        }, "CombinedComponents");
      }
    }
};

Then in Routes

<Route path="somepath" {...LazyComponents('Component1')} />
abhirathore2006
  • 3,317
  • 1
  • 25
  • 29