Webpack 5 build with multiple entry points results in module is not a function

Viewed 820

I have a library built in Storybook, React. Recently migrated from webpack 4 -> webpack 5.

Everything goes well during build times, etc.

However when I import the library in my consumer project there is some error like:

animations.js?6046:2 Uncaught TypeError: __webpack_modules__[t] is not a function
    at __webpack_require__ (animations.js?6046:2)

The error shows at something like this, even though I do have react as externals:

40258: function(t) {
            "use strict";
            t.exports = __webpack_require__(/*! react */
            "./node_modules/@library/components/node_modules/react/index.js")
        }

My webpack.config.js looks like this:

const path = require('path')
const webpack = require('webpack')

const autoprefixer = require('autoprefixer')
const TerserPlugin = require('terser-webpack-plugin')
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')

const createConfig = require('./config')

const PRODUCTION = 'production'
const DEVELOPMENT = 'development'
const UMD = 'umd'
const PUBLIC_PATH = process.env.PUBLIC_URL || '/'

const appPackageJson = require('../package.json')

process.env.REACT_APP_VERSION = JSON.stringify(appPackageJson.version)
process.env.REACT_APP_BUILD_NUM = process.env.CIRCLE_BUILD_NUM

// eslint-disable-next-line func-names
module.exports = function (env = {}) {
  const productionBuild = env.build === PRODUCTION
  const umdPackage = env.package === UMD
  const environment = productionBuild ? PRODUCTION : DEVELOPMENT

  // Make sure that the proper environment variables are set
  process.env.BABEL_ENV = environment
  process.env.NODE_ENV = environment
  process.env.ENVIRONMENT = environment

  const { paths, environmentVariables } = createConfig(PUBLIC_PATH)

  return {
    mode: productionBuild ? 'production' : 'development',
    bail: productionBuild,
    devtool: productionBuild ? 'source-map' : 'cheap-eval-source-map',
    entry: {
      components: paths.entryJSFile,
      animations: paths.animationsJsFile,
      datepicker: paths.datepickerJsFile,
    },
    output: {
      path: paths.buildFolder,
      publicPath: paths.publicPath,
      // Pass window object to webworker files
      globalObject: 'this',
      // Packaging specific settings
      library: {
        name: umdPackage ? ['DigitalLib', '[name]'] : undefined,
        type: umdPackage ? 'umd' : 'commonjs2',
      },
      filename: umdPackage ? '[name].umd.js' : '[name].js',
      libraryTarget: umdPackage ? 'umd' : 'commonjs2',
      umdNamedDefine: umdPackage ? true : undefined,
    },
    resolve: {
      symlinks: false,
      extensions: ['.ts', '.tsx', '.mjs', '.js', '.jsx', '.json', '.css']
    },
    externals: {
      // Don't bundle react or react-dom
      react: {
        commonjs: 'react',
        commonjs2: 'react',
        amd: 'React',
        root: 'React',
      },
      'react-dom': {
        commonjs: 'react-dom',
        commonjs2: 'react-dom',
        amd: 'ReactDOM',
        root: 'ReactDOM',
      },
      'prop-types': {
        commonjs: 'prop-types',
        commonjs2: 'prop-types',
        amd: 'PropTypes',
        root: 'PropTypes',
      },
      'styled-components': {
        commonjs: 'styled-components',
        commonjs2: 'styled-components',
        amd: 'styled',
        root: 'styled',
      }
    },
    module: {
      strictExportPresence: true,
      rules: [
        // Load web workers using the worker-loader
        {
          test: /\.webworker\.js$/,
          loader: 'worker-loader',
        },
        {
          oneOf: [
            // Process javascript through babel 7
            {
              test: /\.(ts|js)x?$/,
              loader: 'babel-loader',
              exclude: /node_modules/,
            },
            // Webpack 4 doesn't handle GraphQL mjs dependency correctly, use this to circumvent it
            // https://github.com/graphql/graphql-js/issues/1272
            {
              test: /\.mjs$/,
              include: /node_modules/,
              type: 'javascript/auto',
            },
            {
              test: /\.css$/,
              use: [
                'style-loader',
                {
                  loader: 'css-loader',
                  options: {
                    importLoaders: 1,
                  },
                },
                {
                  loader: 'postcss-loader',
                  options: {
                    ident: 'postcss',
                    plugins: () => [require('postcss-flexbugs-fixes'), autoprefixer({ flexbox: 'no-2009' })],
                  },
                },
              ],
            },
            // Use file loader for the rest of the files. Define any new loaders before this
            {
              type: 'asset/resource',
              exclude: [/\.(ts|js)x?$/, /\.html$/, /\.json$/, /\.md$/],
              generator: {
                filename: 'assets/[name].[contenthash].[ext]',
              },
            },
          ],
        },
      ],
    },
    plugins: [
      new webpack.DefinePlugin(environmentVariables.stringified),
      // Ignore moment.js locale files
      new webpack.IgnorePlugin({ 
        resourceRegExp: /^\.\/locale$/,
        contextRegExp: /moment$/ 
      }),
    ].concat(
      productionBuild
        ? [
            new BundleAnalyzerPlugin({
              analyzerMode: 'static',
              reportFilename: '../bundle-statistics.html',
              openAnalyzer: false,
            }),
          ]
        : [new webpack.HotModuleReplacementPlugin()]
    ),
    optimization: productionBuild
      ? {
          minimize: true,
          minimizer: [
            new TerserPlugin({
              terserOptions: {
                compress: { warnings: true, comparisons: false },
                mangle: { safari10: true },
                output: { ascii_only: true },
                safari10: true,
              },
              parallel: true,
            }),
            new CssMinimizerPlugin(),
          ],
        }
      : {},
    performance: {
      hints: productionBuild ? 'warning' : false,
    },
    devServer: productionBuild
      ? undefined
      : {
          contentBase: paths.src,
          watchContentBase: true,
          hot: true,
          quiet: true,
          clientLogLevel: 'error',
          compress: true,
          historyApiFallback: {
            disableDotRule: true,
          },
        },
    watchOptions: {
      ignored: ['node_modules'],
    },
  }
}

Basically there are 3 entry points, because I want to split them a bit. With webpack 4 bundling it was working and I could do something like:

import { SuccessAnimation } from '@library/components/build/animations'. (this is from animations.js entry)

as well as

import { Button } from '@library/components' (this is from components.js entry)

What am I doing wrong? Is Webpack resolving the modules somehow differently and if yes how can I fix this?

0 Answers
Related