Sandeep
Sandeep

Reputation: 2121

react lazy load external amd modules

My react app has external resources outside src/ so i have ejected react-scripts and disabled ModuleScopePlugin. Referenced the external library in resolve.alias and used across the application.

resolve.alias: {
  'genlib': path.resolve(fs.realpathSync(process.cwd()), 'lib/genlib/js/src'),
  'config': path.resolve(fs.realpathSync(process.cwd()), 'config/dev'),
  'messages': path.resolve(fs.realpathSync(process.cwd()), 'config/messages')
}

genlib is the external library im trying to reference.

The external library is AMD using requirejs.

One of the file in the library lazy loads a class using require.

define('class1', ['require', ...], function(require, ...) {
  //
  require([variable], function()...)
});

The above require is throwing Cannot find module 'xxx' at runtime from webpackEmptyContext.

When require from above code is consoled then below is logged instead of require function. Confused why webpackEmptyContext is consoled out instead of webpackContext function

ƒ webpackEmptyContext(req) {
    var e = new Error("Cannot find module '" + req + "'");
    e.code = 'MODULE_NOT_FOUND';
    throw e;
}

I have not changed any of the webpack.config.js except adding alias and disabling ModuleScopePlugin.

What else needs to be added or changed in config to lazy load amd modules.

webpack v4.19.1
react-dev-utils v7.0.1

Upvotes: 2

Views: 1439

Answers (2)

Sandeep
Sandeep

Reputation: 2121

I have solved by using ContextReplacementPlugin.

Added below code to webpack config plugins.

new webpack.ContextReplacementPlugin(/genlib[\\/]services/, /.*$/),

Now a map is created with all the files in the services directory and webpackContext loads the files when required.

Upvotes: 1

amarmishra
amarmishra

Reputation: 613

You will see babel-loader in return object of webpack.config.js file. module -> rules array First code is to run the linter

    {
      test: /\.(js|mjs|jsx)$/,
      enforce: 'pre',
      use: [
        {
          options: {
            formatter: require.resolve('react-dev-utils/eslintFormatter'),
            eslintPath: require.resolve('eslint'),

          },
          loader: require.resolve('eslint-loader'),
        },
      ],
      include: [
          paths.appSrc,
          'paht/to/external-library/using/requirejs' <---- Add your external file path for loader to parse the AMD files
      ],
    }

Similarly include file path to test entry of JS files test: /\.(js|mjs|jsx|ts|tsx)$/,

Can you try this and check?

Upvotes: 0

Related Questions