I am trying to set up the following architecture: a core React application that gets built with some basic functionality, and the ability to load additional React components at runtime. These additional React components can be loaded on-demand, and they are not available at build time for the core application (so they cannot be included in the bundles for the core application, and must be built separately). After researching for some time, I came across Webpack Externals, which seemed like a good fit. I am now building my modules separately using the following webpack.config.js:
const path = require('path');
const fs = require('fs');
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
module.exports = {
entry: './src/MyModule.jsx',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'MyModule.js',
library: 'MyModule',
libraryTarget: 'umd'
},
externals: {
"react": "react",
"semantic-ui-react": "semantic-ui-react"
},
module: {
rules: [
{
test: /\.(js|jsx|mjs)$/,
include: resolveApp('src'),
loader: require.resolve('babel-loader'),
options: {
compact: true,
},
}
]
},
resolve: {
extensions: ['.wasm', '.mjs', '.js', '.json', '.jsx']
}
};
Took a look at the generated MyModule.js file, and it looks correct to me.
Now, in my core app, I am importing the module as follows:
let myComponent = React.lazy(() => import(componentName + '.js'));
where componentName
is the variable that matches the name of my module, in this case, "MyModule" The name is not known at build time, and the file is not present in the src folder at build time. To avoid errors from webpack when building this code with an unknown import, I have added the following to my webpack.config.js for the core project:
module.exports = {
externals: function (context, request, callback/*(err, result)*/) {
if (request === './MyModule.js') {
callback(null, "umd " + request);
} else {
callback();
}
}
}
I have confirmed that the function in externals gets called during the build, and the if condition is matched for this module. The build succeeds, and I am able to run my core application.
Then, to test dynamic loading, I drop MyModule.js
into the static/js folder where the bundles for my core app live, then I navigate to the page in my core app that requests MyModule via let myComponent = React.lazy(() => import(componentName + '.js'));
I see a runtime error in the console on the import line,
TypeError: undefined is not a function
at Array.map (<anonymous>)
at webpackAsyncContext
My guess is it's failing to find the module. I don't understand where it is looking for the module, or how to get more information to debug.
I have a chart that shows the time in and time out for the employees on a daily basis. I've fetched the data from the database and all was working well. But now the columns show the data incorrectly ...
I have a chart that shows the time in and time out for the employees on a daily basis. I've fetched the data from the database and all was working well. But now the columns show the data incorrectly ...
I've got a tree like: { "nodes": [ { "id":1, "children":[ { "id":3, "children":[ {"id":4, "children":[]}, {"id":5, "children":[{"...
I've got a tree like: { "nodes": [ { "id":1, "children":[ { "id":3, "children":[ {"id":4, "children":[]}, {"id":5, "children":[{"...
Please see this minimum example https://codepen.io/rockmandash/pen/Rzwowd The code is this: <div class="cool"> <input type="checkbox" value="checkbox1"> <input type="checkbox" ...
Please see this minimum example https://codepen.io/rockmandash/pen/Rzwowd The code is this: <div class="cool"> <input type="checkbox" value="checkbox1"> <input type="checkbox" ...
I'm working on a form to add members to a project. Only members whose profiles are recorded in the system can be added. There are a name input field and a position select box. The position select box ...
I'm working on a form to add members to a project. Only members whose profiles are recorded in the system can be added. There are a name input field and a position select box. The position select box ...