Webpack both static and dynamic import leads to no chunk

Viewed 226

I've been struggling with something (react, but doesn't matter). Imagine the following setup:

// modules/A/index.ts
export { actions } from '/actions'
export { default as RootComponent } from './component' // imagine this to be big, I tried adding 250kb of data to it.
export { default as reducer } from './reducer'
export { default as saga } from './saga'

Now.. In the app, there is the following:

// index.js
import {actions} from './modules/A';

const LazyComponent = React.lazy(() => import('./modules/A').then(res => {
  // doing something with the reducer/saga
  return {default: res.RootComponent}
}));

// LazyComponent as a route, using an action from actions to trigger something (if present)

All this works fine, except, the moment when I statically import the actions from the module, no chunk will be generated anymore and everything ends up in the main js. If I would import the actions from the actions file itself from the module, it will generate a chunk for the dynamic import, like desired.

If there anything that can be done to get my desired effect: statically import something from the module, but load the rest only on demand (because of the size)?

The idea is, that the module might be extracted as a dependency later on (es module), and then the pkg.module will be some index, so how to support code splitting like that?

Simplified Webpack config (copy from a different project, didn't really go through it yet) (v4.43):

const config = {
    target: 'web',
    entry: {
        app: './src/index.tsx',
    },

    output: {
        filename: '[name].[chunkhash].bundle.js',
        path: path.join(__dirname, 'dist'),
        publicPath: '/',
    },

    resolve: {
        extensions: ['.tsx', '.ts'],
        modules: [path.resolve(__dirname, 'src'), 'node_modules'],
    },

    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: [
                    {
                        loader: 'thread-loader',
                        options: {
                            poolTimeout: isProduction ? 500 : Infinity,
                        },
                    },
                    {
                        loader: 'ts-loader',
                        options: {happyPackMode: true},
                    },
                ],
            },
            {
                test: /\.css$/i,
                use: ['style-loader', 'css-loader'],
            },
            {
                test: /\.(ttf|eot|svg|jpg|gif|png|woff(2)?)(\?[a-z0-9]+)?$/,
                loader: 'file-loader',
            },
        ],
    },

    plugins: [
        ...(isProduction ? new CleanWebpackPlugin() : []),
        new webpack.DefinePlugin({
            PRODUCTION: isProduction,
        }),
        new htmlWebpackPlugin({template: './src/index.html'}),
        new CopyWebpackPlugin({
            patterns: [
                {
                    context: './public',
                    from: '**/*',
                },
            ]
        }),
        new CircularDependencyPlugin({
            exclude: /node_modules/,
            failOnError: true,
        }),
    ],

    devServer: { /* blabla*/ },
    optimization: {
        noEmitOnErrors: true,
    },
    stats: {
        warningsFilter: /export .* was not found in/,
    },
}
0 Answers
Related