Our projects utilize create-react-app
and Typescript, resulting in the emergence of a collection of commonly used React components. To enhance maintenance and reusability, we decided to extract these components into their own NPM package named PackageA
. Surprisingly, this transition caused the overall size of our test application, referred to as TestApp
, to increase compared to when the components were integrated within the app itself. TestApp
is a simplistic app that primarily demonstrates some, but not all, aspects of the components in PackageA
, previously housed within the project but now imported from the privately published PackageA
.
Initial sizes of JS chunks before extracting PackageA
out from TestApp
("main" indicating code from the project itself, while the other chunk holds dependencies):
- Gzipped: "main" chunk ~ 31 kB, chunk with external dependencies ~ 193 kB (post build output)
- Unzipped: "main" chunk ~ 93 kB, chunk with external dependencies ~ 653 kB (browser size)
Sizes after separating PackageA
from TestApp
:
- Gzipped: main chunk ~ 22 kB, chunk with external dependencies ~ 215 kB (post build output)
- Unzipped: main chunk ~ 57 kB, chunk with external dependencies ~ 745 kB (browser size)
This results in an increase of 13 kB gzipped and 56 kB unzipped, corresponding to approximately 6% gzipped and 8% unzipped size increment. Though not drastic, the difference is notable considering the expectations.
Additional Details
- The content of
PackageA
is published as ES6 modules to enable efficient tree-shaking, ensuring that unused parts ofPackageA
do not affectTestApp
. PackageA
undergoes minification by UglifyJS before being published, utilizing both--compress
and--mangle
options.- Source maps are excluded from the source files of
PackageA
, only available separately. - Dependencies listed under
dependencies
inPackageA
'spackage.json
are exclusive toPackageA
and are removed fromTestApp
'spackage.json
, with identical versions used. All other dependencies ofPackageA
are listed underpeerDependencies
. - Size validation was conducted after clearing the
node_modules
folder and reinstalling dependencies. - The content of
PackageA
mirrors the deleted folder from
file that exports the other files' contents, less than 3 kB unzipped.TestApp</code, with the addition of an <code>index.ts
The potential sources of this size increase and the starting points for investigation are crucial. It's possible that the increase stems from how the code is transpiled in the package, with create-react-app
transpiling in a more efficient manner for in-project code compared to imported code. Answering this query is challenging given the numerous possibilities and complexities involved.
Below is the tsconfig.json
file used in the extracted PackageA
:
{
"compilerOptions": {
"target": "es6",
"lib": ["es6", "dom"],
"jsx": "react-jsx",
"module": "es6",
"rootDir": "./src",
"moduleResolution": "node",
"declaration": true,
"sourceMap": true,
"outDir": "./build/esm",
"inlineSources": true,
"allowSyntheticDefaultImports": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
},
"include": ["./src"],
"exclude": ["**/*.test.tsx", "**/*.test.ts", "**/*.stories.tsx"]
}