requireEntrypoint returns undefined value
See original GitHub issueHello,
I am running into troubles with SSR + multiple entry points. None of the issues already solved seem to have the same problem.
My issue is that on the server-side, when doing:
const nodeExtractor = new ChunkExtractor({
statsFile: './public/build/js/node/loadable-stats.json',
entrypoints: ['MyPage'],
});
const { default: App } = nodeExtractor.requireEntrypoint('MyPage');
App
comes as undefined
, even though loadable-stats.json
does contain the name of the entrypoint as a key with the right file as a value. Even if I do not give an argument to requireEntrypoint
, it comes as undefined - same if I don’t give entrypoints
to instantiate ChunkExtractor
and keep the argument.
If I replace the last line with:
const App = nodeExtractor.requireEntrypoint('MyPage');
App
does not come as a string, a class or a function but an object. React.createElement
therefore fails.
My webpack configuration is as follow:
// ...
// ... define some variables that we'll use in the configuration below
// ...
// The object that'll hold webpack configuration
const getConfig = (target) => ({
entry: {
MyPage: ['MyPage'],
MyOtherPage: ['MyOtherPage'],
},
mode,
name: target,
target,
module: {
rules: [{
test: /\.jsx?$/,
exclude: /(node_modules)/,
use: {
loader: 'babel-loader',
options: {
caller: { target },
},
},
}],
noParse: [/aws-sdk/],
},
resolve: {
extensions: ['.js', '.jsx'],
},
externals: target === 'node' ? ['@loadable/component', nodeExternals()] : undefined,
output: {
filename,
chunkFilename,
path: path.resolve(__dirname, 'public', 'build', 'js', target),
publicPath: `/build/js/${target}`,
libraryTarget: target === 'node' ? 'commonjs2' : undefined,
},
plugins: [
// Define global constants to be used in the JS files
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'local'),
},
}),
new webpack.NamedChunksPlugin((chunk) => {
if (chunk.name) {
return chunk.name;
}
const n = [];
chunk.forEachModule((m) => n.push(path.relative(m.context, m.request)));
return n.join('_');
}),
// Name all modules because adding a new page will bust all cache
new NameAllModulesPlugin(),
// Add versioning to files with a manifest files as basis
new Versioning({
manifestPath: path.join(__dirname, './public/build/rev-manifest.json'),
basePath: `js/${target}/`,
cleanup: false,
}),
new LoadablePlugin(),
],
devtool,
optimization: {
namedModules: true,
providedExports: true,
usedExports: true,
concatenateModules: true,
noEmitOnErrors,
minimizer,
splitChunks: {
cacheGroups: {
chunks: CHUNKS,
// No vendor chunk on the server-side
...target !== 'node' && {
vendors: {
test: (module) => !skip(module) && isExternal(module),
name: 'vendor',
filename: filenameVendor,
chunks: 'all',
minChunks: 3,
},
},
commons: {
test: (module) => !skip(module) && !isExternal(module),
name: 'common',
filename: filenameCommon,
chunks: 'initial',
minChunks: 3,
},
},
},
},
performance: {
hints: false,
},
...target !== 'node' && {
resolveLoader: {
modules: ['node_modules'],
},
},
// Bail out on the first error
bail: true,
watchOptions: {
aggregateTimeout: 100,
poll: 1000,
ignored: /node_modules/,
},
});
I can give more details if necessary, but I find myself completely stuck here. I followed the example we can find here.
I am running:
- webpack 4.23.1
- loadable 5.2.2
Issue Analytics
- State:
- Created 5 years ago
- Comments:7 (1 by maintainers)
Top GitHub Comments
I got it working, mixing both the official documentation and the server-side rendering code example. Maybe the documentation should be updated? The solution was to do as follow:
And return something like:
So the node extractor is used for the server-side rendering, and the web extractor is used to get the browser-side compiled files.
Fixed it. I used only the
webExtractor
and ditched thenodeExtractor
to get it working. Thanks!