Bundle Size (as of 2025-11-01):
Components:
The translation module adds significant size to the bundle:
For users who only need review functionality (comments, tracked changes, git integration), this is unnecessary overhead.
Create two build targets:
Add to vite.config.ts:
export default defineConfig({
define: {
__ENABLE_TRANSLATION__: JSON.stringify(
process.env.ENABLE_TRANSLATION !== 'false'
),
},
// ...
});
src/main.ts// Type-only imports (always available)
import type { TranslationConfig } from '@modules/translation';
// Conditional runtime import
let TranslationModule: typeof import('@modules/translation').TranslationModule | undefined;
if (__ENABLE_TRANSLATION__) {
TranslationModule = (await import('@modules/translation')).TranslationModule;
}
export class QuartoReview {
private translation?: InstanceType<typeof TranslationModule>;
constructor(config: QuartoReviewConfig = {}) {
// ...
// Initialize translation module if enabled AND available
if (this.config.enableTranslation && TranslationModule) {
this.translation = new TranslationModule({
config: translationConfig,
changes: this.changes,
markdown: this.markdown,
exporter: this.exporter,
});
}
// ...
}
}
// In UIModule constructor
if (config.translation && __ENABLE_TRANSLATION__) {
// Lazy load translation UI components
const { TranslationController } = await import(
'./translation/TranslationController'
);
this.translationController = new TranslationController({
translation: config.translation,
// ...
});
}
Ensure Vite can tree-shake unused code:
// vite.config.ts
export default defineConfig({
build: {
rollupOptions: {
output: {
manualChunks(id) {
// Separate translation into its own chunk
if (id.includes('translation') || id.includes('@xenova')) {
return 'translation';
}
},
},
},
},
});
Add to package.json:
{
"scripts": {
"build": "npm run build:full",
"build:full": "vite build",
"build:lean": "ENABLE_TRANSLATION=false vite build --mode lean",
"build:both": "npm run build:full && npm run build:lean"
}
}
Create separate extension variants:
_extensions/
├── review/ # Full version (with translation)
│ ├── _extension.yml
│ └── assets/
│ └── review.js
└── review-lean/ # Lean version (review only)
├── _extension.yml
└── assets/
└── review.js
Estimated lean bundle: ~400-500 KB (down from 2.4 MB) Estimated gzipped: ~120-150 KB (down from 533 KB)
Installing Lean Version:
quarto add username/quarto-review-lean
Installing Full Version:
quarto add username/quarto-review
Switching Versions:
# Lean version
filters:
- review-lean
# Full version (with translation)
filters:
- review
review:
enabled: true
mode: translation
Global type declaration for build flag:
// src/env.d.ts
declare const __ENABLE_TRANSLATION__: boolean;
Test both configurations:
// vitest.config.ts
export default defineConfig({
test: {
globals: true,
setupFiles: ['./tests/setup.ts'],
environment: 'jsdom',
},
define: {
__ENABLE_TRANSLATION__: true, // Test with translation enabled
},
});
Separate test run for lean build:
ENABLE_TRANSLATION=false npm test
quarto-review-v1.0.0-full.zip (with translation)quarto-review-v1.0.0-lean.zip (review only)@quarto/review and @quarto/review-leanTrack bundle sizes over time:
// scripts/check-bundle-size.js
const fs = require('fs');
const path = require('path');
const bundlePath = path.join(__dirname, '../dist/review.js');
const stats = fs.statSync(bundlePath);
const sizeMB = (stats.size / 1024 / 1024).toFixed(2);
console.log(`Bundle size: ${sizeMB} MB`);
if (sizeMB > 3.0) {
console.error('⚠️ Bundle size exceeds 3 MB limit!');
process.exit(1);
}
Add to CI/CD pipeline to alert on size regressions.
Status: 📝 Planning Phase Next Action: Implement conditional import wrapper in main.ts