When bundling my web-application, I have realised that re-exports of (some) modules do not work as expected. I have tried multiple optimization settings but so far with no success.
So basically I have the following setup
config/
webpack.config.ts
package.json
frontend/
apps/
app1/
src/
index.tsx
App.tsx
...
packages/
test/
index.ts
testFunc.ts
test1Func.ts
Test.tsx
Test1.tsx
So I run webpack from config
with the entry point frontend/apps/app1/index.tsx
which imports App.tsx
(standard React application).
This all works fine but I have realised that when produce a production build from app1, unused exports in my App.tsx
appear in the bundle. To clarify
import { testFunc } from 'packages/test' // <- `packages` is an alias
const App: React:FC = () => {
const t = testFunc();
return <>Hello World!</>;
}
will include Test.tsx
, Test1.tsx
and 'test1Func.ts' in the bundle. My index.ts
in test/
looks like
export { testFunc } from './testFunc';
export { test1Func } from './test1Func';
export { Test } from './Test';
export { Test1 } from './Test1';
I should mention that testFunc1.ts
contains a useEffect
hook because I found that as soon as I have react related code, there is no tree shaking for the source anymore. So
// test1Func.ts
export const test1Func = () => {
useEffect(() => {
// do nothing
}, []);
return "Test 1";
}
However, if I import my files directly, eg. import { testFunc } from 'packages/test/testFunc'
, everything works as expected and only test
appears in the bundle. This also applies to the other test components:
testFunc
index.ts
& use in App.tsx
=> bundles all files inside test/
❌import { testFunc } from 'packages/test/testFunc'
& use in App.tsx
=> only testFunc.ts
is included in the bundle ✅import { testFunc } from 'packages/test/testFunc'
& don't use in App.tsx
=> nothing gets included in the bundle ✅testFunc1
| Test
| Test1
<- they all behave the same
index.ts
& use in App.tsx
=> bundles all but testFunc
❌import { test1Func } from 'packages/test/test1Func'
& use in App.tsx
=> only test1Func.ts
is included in the bundle ✅import { test1Func } from 'packages/test/testFunc'
& don't use in App.tsx
=> nothing gets included in the bundle ✅I guess this is just a configuration error, although I have already tried multiple different optimisation settings. The closest probably is the sideEffects
option but so far, this also did not have any effect.
Any ideas?
Thank you very much!
I found the solution! 🙌
As guessed, I had Webpack's optimization.sideEffects
property misconfigured. sideEffects
is necessary for proper tree shaking.
However, in order to get this work properly there are 2 destinations where you have to set the sideEffects property:
package.json
(in my case in every package I use in my monorepo)webpack.config.ts
The admittedly very confusing thing is that you will have to set
sideEffects: false
in the package.json
sideEffects: true
in the optimization
section in your webpack.config.ts
Here's a bit more if you are interested.