'Webpack import causing massive bundle size even with sideEffects and unusedExports set
I have a typescript project (Designer project) that I am using to bundle files with another lerna managed project of "helper functions" and type definitions (Helper project). Both projects resides in separate folders. Each package.json of every package within my Helper project is marked as sideEffect: false. The main package I have exports from other packages in its main index.ts file. I think it must be typescript related because importing interfaces works fine but objects and functions start breaking things. Any help is appreciated.
My Helper project has a few files:
// index.ts
export * from './models'; // works sorta fine
export * from './helpers'; // doesn't work for sole export
// models.ts
// importing this and other interface exports works fine
export interface LFRepoWindow {
[k: string]: any;
webAccessApi?: WebAccessApi;
}
// importing this export causes the entire package to be imported
// with all dependencies and 30+mb bundle size
export const notificationTypes = {
warning: 'warning',
error: 'error',
success: 'success',
information: 'information'
} as const;
// helpers.ts
// Importing this similarly causes all dependencies to bundle and 30+mb bundle size
export const getWebAccessInfo = function(checkFrames = false) {
const windowList = checkFrames ? Array.from(window.frames) : [window, window.parent, window.top || undefined];
const waWindow = windowList.find((w) => w?.webAccessApi !== undefined);
return { waWindow, webAccessApi: waWindow?.webAccessApi, name: waWindow?.name };
}
My webpack config file is fairly complex as it is used to dynamically bundle folders from my Designer project but should be relatively understood from this snippet
const config: webpack.Configuration = {
devtool: srcMap || env === 'DEV' ? 'inline-source-map' : undefined,
entry: name.reduce((prev, cur, i) => {
prev[cur] = path.resolve(curDir, 'src', cur + type[i], 'index');
return prev;
}, {} as { [k: string]: string }),
mode: webpackENVMap[env],
externals: {
// d3: 'd3'
jquery: 'jQuery'
},
module: {
rules: [
{
exclude: /node_modules/,
test: /\.[jt]sx?$/,
use: [
// {
// loader: 'babel-loader',
// options: { cacheDirectory: true },
// },
{
loader: 'ts-loader',
},
],
},
{
test: /\.html$/,
use: [
{
loader: 'html-loader',
options: {
minimize: true,
sources: {
urlFilter: (attribute: string, value: string, resourcePath: string) => {
if (/\/Forms\/img\//i.test(value)) {
return false
}
}
} },
},
],
},
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: env !== 'DEV' ? true : false,
},
},
'css-loader',
],
},
],
},
optimization: {
usedExports: true,
sideEffects: true,
moduleIds: 'deterministic',
runtimeChunk: !splitChunks ? false : 'single',
splitChunks: !splitChunks
? false
: {
cacheGroups: {
vendor: {
chunks: 'all',
enforce: true,
name(module: { context?: string }) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context?.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)?.[1]
|| module.context || 'vendors';
// npm package names are URL-safe, but some servers don't like @ symbols
const packageChunkName = `npm.${packageName.replace('@', '')}`;
vendorChunks.push(packageChunkName);
return packageChunkName;
},
reuseExistingChunk: true,
test: nodeModuleRegex,
},
},
},
},
output: {
filename: `[name]${splitChunks ? '.[' + hashType + ']' : ''}.js`,
path: path.resolve(curDir, 'dist'),
publicPath:
env === 'DEV'
? 'http' + '://' + forms.DEV_HOST_NAME + ':' + forms.DEV_PORT
: 'https' + '://' + forms.HOST_NAME + forms.FORMS_BUILD_LOCATION,
// ? forms.PROTOCOL + '://' + forms.DEV_HOST_NAME + ':' + forms.DEV_PORT
// : forms.PROTOCOL + '://' + forms.HOST_NAME + forms.FORMS_BUILD_LOCATION,
},
plugins: [
new webpack.WatchIgnorePlugin({ paths: [/(css)\.d\.ts$/] }),
...(shouldClean ? [new CleanWebpackPlugin()] : []),
new MiniCssExtractPlugin({
filename: env === 'PROD' ? '[name].css' : '[name].[' + hashType + '].css',
}),
...name.map(
n =>
new HtmlWebpackPlugin({
chunks: [n],
filename: `${n}.html`,
template: path.resolve(__dirname, '../assets', './index.html'),
}),
),
new webpack.ids.HashedModuleIdsPlugin(),
],
resolve: {
alias: {
// '@root': path.resolve(__dirname, '../'),
},
fallback: {
"tty": require.resolve("tty-browserify"),
"path": require.resolve("path-browserify"),
"util": require.resolve("util/"),
"stream": require.resolve("stream-browserify"),
"crypto": require.resolve("crypto-browserify"),
"zlib": require.resolve("browserify-zlib"),
"https": require.resolve("https-browserify"),
"http": require.resolve("stream-http"),
"vm": false, //require.resolve("vm-browserify"),
"fs": false,
"os": false,
"worker_threads": false,
"assert": false,
"module": false,
"console": false,
"inspector": false,
"esbuild": false,
"@swc/core": false,
"child_process": false,
"constants": false,
},
extensions: ['.tsx', '.ts', '.js'],
},
stats: withMultiple ? 'minimal' : 'verbose',
target: 'web',
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
