Configuring sideEffects for CSS and Asset Imports
Safely configure package.json sideEffects glob patterns to preserve CSS, font, and polyfill imports while enabling aggressive dead code elimination for JavaScript modules.
Why Global sideEffects: false Drops Stylesheets
Bundler AST traversal treats non-JS imports as pure unless explicitly flagged. CSS injection relies on runtime side effects (DOM insertion via style tags). A global boolean false overrides implicit asset dependencies in compiled output, causing silent failures during static analysis. This manifests as:
ModuleParseError: CSS import silently dropped; sideEffects: false
This configuration breaks dual ESM/CJS outputs by stripping required stylesheets before runtime execution. Proper scoping is foundational to Tree-Shaking & Bundle Optimization.
Precision Glob Patterns for Style & Media Files
Replace the global boolean with an explicit array to preserve asset bundling while maintaining JS tree-shaking. Use relative path scoping to avoid over-inclusion of unrelated modules. Separate style extensions from script extensions in the sideEffects array, and exclude declaration files and config artifacts from the list.
"sideEffects": [
"./dist/styles/*.css",
"./dist/styles/*.scss",
"./dist/assets/**/*.{png,svg,woff}"
]
This pattern ensures only compiled output directories are evaluated. For implementation strategies when transitioning from global booleans to array-based overrides, see Implementing the sideEffects Flag Correctly.
Resolving TypeScript Module Resolution Conflicts
The TypeScript compiler ignores sideEffects, but bundlers parse them for dependency graphs. Explicitly scope sideEffects to compiled output directories, not src/. Avoid **/* patterns that capture .d.ts or .map files. Misconfiguration triggers:
TS2307/TS5055: Module resolution fails when sideEffects array captures declaration files
Scoping to dist/, lib/, or esm/ isolates runtime assets from compile-time definitions, preventing false-positive side-effect detection.
Bundler-Specific Asset Pipeline Overrides
Apply targeted configuration flags to bypass default asset stripping:
- Rollup: Requires explicit
sideEffectsmapping to prevent asset chunk elimination during graph optimization. - Webpack 5:
module.rules.type: 'asset'interacts directly withsideEffectsevaluation. Ensure asset modules are not marked side-effect-free in loader chains. - Vite: Set
build.lib.cssCodeSplit: falseto prevent orphaned style chunks in library mode. Pipeline misalignment produces:rollup: output.assetFileNames mismatch; webpack: sideEffects: true in module.rules
Step-by-Step Resolution
- Audit current
package.jsonsideEffectsconfiguration
grep -n "sideEffects" package.json && cat package.json | jq '.sideEffects'
- Replace boolean
falsewith scoped asset glob array
"sideEffects": ["./dist/styles/*.css", "./dist/assets/**/*.{png,svg,woff2}"]
- Validate bundler output with asset preservation flags
npx webpack --config webpack.lib.config.js --stats-children --env analyze=true
- Verify dual ESM/CJS packaging integrity
npm pack --dry-run && tar -tf library-1.0.0.tgz | grep -E '\.(css|png|svg)$'