0
votes

I'm trying to lazy load my routes state using below code

//router.js
//usage
$stateProvider
  .state('async', {
    url: '/async',
    templateUrl: require('!!file-loader?name=templates/[name].[ext]!./../../pages/somepage/page.html'),
    controller: 'asyncController',
    resolve: {
      deps: 
      asyncPreloading: resolverProvider.lazyload('../../pages/somepage/page.module.js')
    }
  })

the "resolverProvider.lazyload(path)" when tries to require(path) I get warning like

Critical dependencies: 30:34-55 the request of a dependency is an expression

or

Critical dependencies: 30:34-41 require function is used in a way in which dependencies cannot be statically extracted

resolverProvider code is below

//provider.js
'use strict';
export default function (app) {
  app.provider('resolver', resolverProvider);

  function resolverProvider() {
      this.$get = () => this;
      this.lazyload = lazyload;
  }

  function lazyload(module) {
    return (($q, $ocLazyLoad) => {
      "ngInject";

      const deferred = $q.defer();

      require.ensure([], function (require) {
          console.log(module);
          const asyncModule = require('../../pages/somepage/page.module.js'); // it works
          const asyncModule = require(module); // doesn't work
          $ocLazyLoad.load({
              name: asyncModule.name,
          });
          deferred.resolve(asyncModule.controller);
      });
      return deferred.promise;
    });
  }
}

Does anyone have a solution for this problem of dynamically require(expression);

2

2 Answers

0
votes

the solution is with require.context and webpack.

I have created webpackConfig.resolve.alias pointing to my appRoot.

When I'm doing the require(path) I'm passing my path as an as an regex.

//provider.js

const asyncModule = require('_appRoot/' + moduleRegExp + '.js');

checkout webpack more info.

My webpack config looks like:

// resolves modules
resolve: {
  extensions: ['', '.js'],
  modulesDirectories: ['node_modules'],
  alias: {
    _appRoot:     path.join(_path, 'src', 'app'),
    _images:      path.join(_path, 'src', 'app', 'assets', 'images'),
    _stylesheets: path.join(_path, 'src', 'app', 'assets', 'styles'),
    _scripts:     path.join(_path, 'src', 'app', 'assets', 'js')
  }
},

and my routes state are like asyncPreloading: resolverProvider.lazyload('pages\/async-page-example\/async.module')

0
votes

A simpler way to pull this off without resorting to eval is:

const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
const foo = requireFunc(moduleName);

In the bundled output, this will become

const requireFunc = true ? require : require;
const foo = requireFunc(moduleName);

For more options check here: https://github.com/webpack/webpack/issues/4175