kolibri icon indicating copy to clipboard operation
kolibri copied to clipboard

Reduce JS production build size by ~25%

Open rtibbles opened this issue 2 months ago • 4 comments

Summary

  • Fixes erroneous import from 'lodash' which causes the entire library to be bundled
  • Enables terser code mangling
  • Code splits vue-intl polyfill data
  • Changes corejs polyfilling strategy for kolibri-sandbox to prevent erroneous corejs imports in plugins that import it directly

Reviewer guidance

The build should still work as expected, and it will be worth testing this on Safari to ensure the polyfilling behaviour is still intact.

Manual testing of HTML5, H5P, and Bloompub resources would also be useful.

:robot: This was created by Claude Code. @rtibbles then reviewed the generated output, and did iterative rounds of updates before making it ready for review :robot:

rtibbles avatar Nov 14 '25 11:11 rtibbles

@coderabbitai full review

rtibbles avatar Nov 14 '25 11:11 rtibbles

✅ Actions performed

Full review triggered.

coderabbitai[bot] avatar Nov 14 '25 11:11 coderabbitai[bot]

Walkthrough

Changes include webpack and babel configuration updates for build optimization, refactoring Vue Intl locale data loading to be dynamic and lazy-loaded based on locale parameter, removing explicit core-js polyfill imports in favor of configuration-driven injection, and updating i18n setup to load locale data asynchronously.

Changes

Cohort / File(s) Summary
Build Configuration
packages/kolibri-build/src/webpack.config.base.js
TerserPlugin mangle option changed from false to { safari10: true } to activate it, but maintain safari10 compatibilty.
Polyfill Cleanup
packages/kolibri-sandbox/src/iframe.js, packages/kolibri-sandbox/src/xAPI/xAPIConstants.js, packages/kolibri-sandbox/src/xAPI/xAPISchema.js, packages/kolibri-sandbox/babel.config.js, packages/kolibri-sandbox/webpack.config.js
Removed explicit core-js polyfill imports (array/includes, object/assign, object/entries, object/values, promise, string/starts-with, web/url, and set). No functional code changes; polyfill handling delegated to configuration. Babel preset-env switches from useBuiltIns: false to useBuiltIns: 'usage' with corejs: '3.46' for selective polyfill injection. Webpack Babel loader exclude pattern simplified to exclude all node_modules instead of specific module filtering.
Vue Intl Locale Data Refactoring
packages/kolibri-i18n/src/intl_code_gen.js, packages/kolibri/utils/internal/vue-intl-locale-data.js
Converted locale data loading from static aggregation to dynamic, lazy-loaded switch-based cases per locale. Added uniqBy deduplication of languageInfo entries. Function signature changed to accept locale parameter and return Promise-wrapped lazy-loaded module via require.ensure.
i18n Setup Refactoring
packages/kolibri/utils/i18n.js
Updated _setUpVueIntl to load locale data asynchronously, deriving language code from current language and awaiting importVueIntlLocaleData. Control flow now uses .then(resolve, reject) to defer i18n readiness until locale data is loaded.
Import Optimization
packages/kolibri/composables/useUser.js
Updated lodash import to use subpath lodash/pick instead of default import; no runtime or API changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Vue Intl locale data lazy-loading implementation: Verify that dynamic require.ensure patterns work correctly across locales and that Promise-based loading doesn't introduce race conditions or initialization order issues.
  • i18n async setup control flow: Ensure the deferred Promise resolution properly gates i18n readiness and that all dependent code awaits locale data loading.
  • Webpack Babel loader behavioral change: Confirm that the simplified exclude pattern (all node_modules) doesn't inadvertently process or skip necessary transformations for the build output.
  • Polyfill removal verification: Validate that removing explicit core-js imports doesn't break functionality in environments where the babel preset-env configuration doesn't automatically inject required polyfills.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main objective: reducing JS production build size by ~25%, which aligns with the changeset's focus on build optimization.
Description check ✅ Passed The description clearly relates to the changeset, explaining specific optimizations made: lodash import fix, terser mangling, vue-intl code splitting, and corejs strategy changes.
✨ Finishing touches
  • [ ] 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • [ ] Create PR with unit tests
  • [ ] Post copyable unit tests in a comment
  • [ ] Commit unit tests in branch claude/analyze-webpack-build-01KdiNGodpTcF1ipRfguPxwF

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot] avatar Nov 14 '25 11:11 coderabbitai[bot]

@marcellamaki and I did some further investigation of the iOS Safari 9.3 compatibility, and it seems that this PR breaks that.

Instead we will plan to reduce this PR to just the lower risk changes, then target the rest to develop, on the assumption that our browser usage stats will show we can drop some browser support.

rtibbles avatar Dec 19 '25 00:12 rtibbles