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?