What’s New in San CLI 4.0? Architecture, Performance, and Feature Upgrades
San CLI 4.0 introduces a re‑architected command system, decoupled configuration, Webpack 5 support, TypeScript and ESM build options, and a series of performance tweaks that together improve flexibility, reduce bundle size, and speed up both development and production builds.
Architecture Changes
San CLI’s core build capability wraps Webpack; version 4.0 restructures the architecture to make commands installable on demand, configuration decoupled, and extensions unified. The new design reduces the built‑in commands from seven to three (init, build, serve) while allowing additional commands via independent npm packages.
Commands are now separate npm packages, enabling independent installation and upgrades.
Configuration is generated by san-cli-config-webpack and can be extended via plugins; the internal webpack starter is rebuilt on an event‑driven basis for better reuse.
Three extension types are defined: san-cli-xxx (custom commands), san-cli-plugin-xxx (modify CLI configuration), and san-cli-ui-xx (UI plugins).
Command and Plugin Extension
San CLI supports three plugin mechanisms:
Custom command packages that follow the npm and yargs command conventions. Example export format is shown in the diagram.
Service plugins that modify the webpack configuration via webpack‑chain. They expose an id and an execution function, and use the new pickConfig field to isolate plugin configuration from the CLI config.
UI plugins that add visual components to the San CLI UI when they follow the naming convention.
Configuration Mechanism
In 3.0, all webpack loaders and rules were generated inside the service layer, making custom changes cumbersome. Version 4.0 moves every built‑in webpack configuration into plugins, allowing users to enable or disable each plugin via a configuration switch and to share configurations through an extends field.
The new configuration flow is: getWebpackConfig calls getWebpackChainConfig to create a chainConfig.
Inside getWebpackChainConfig, a new Config instance builds the chain.
All webpackChainFns are executed, applying plugin modifications.
Control returns to getWebpackConfig to run webpackRawConfigFns for direct config tweaks.
Finally, devServerOptions from san-cli-config-webpack are merged.
Performance Improvements
San CLI 4.0 upgrades the bundled webpack version from 4 to 5, unlocking several performance features.
New Features and Effects
Polyfill on‑demand loading reduces vendor size by 5.3% (≈19.62 KB).
Filesystem caching in development cuts first‑run time by 78.14% and incremental builds by 7.66%.
Asset modules replace url-loader and file-loader, decreasing loader count and improving large‑project build speed.
Optional optimizations that can be enabled: esbuild-loader replaces babel-loader in development (‑22.25% first‑run, ‑31.17% incremental) and uses terser in production (‑34% build time, slight bundle increase). thread-loader for multi‑process builds (recommended only for large projects).
RuntimeChunk splitting and splitChunks to reduce entry bundle size.
Deterministic moduleIds to stabilize hashes and improve caching.
Upgrade Issues Summary
Two main problem areas were encountered:
Build performance : After upgrading all loaders and plugins, some builds did not speed up. Solutions included enabling persistent filesystem caching, removing unnecessary plugins, and disabling default webpack‑5 strategies such as module.unsafeCache = true and output.pathinfo = false when appropriate.
Tool compatibility : Some webpack‑5 dependent packages (e.g., webpack-chain, webpack-dev-server) lagged behind. San CLI kept webpack-dev-server at version 3.x for stability and handled missing APIs in webpack-chain manually.
Business‑Level Build Gains
Multi‑page C‑side app (~11.7k lines): bundle size ↓ 2.7%, production build time ↑ 13.2%, development start‑up time ↓ 86%.
B‑side SPA (~70.5k lines): bundle size ↓ 0.9%, build times improved in both environments.
Feature Enhancements
TypeScript Build Support
Version 4.0 adds a project‑creation option for TypeScript. Implementation relies on @babel/preset-typescript for syntax transformation and @typescript-eslint for linting. Users can still invoke tsc or VS Code extensions as needed.
Improved Single‑File Component Workflow
After global installation, a single index.san file can be served with: san serve index.san and built with:
san build index.sanESM Build Support
For local debugging, San CLI now offers an ESM‑based build that skips Babel transpilation to ES5, leveraging modern browsers’ native support. The command: san serve --esm reduces local start‑up time by roughly 32.7% compared with the standard build.
Technical References
San: https://github.com/baidu/san
San CLI: https://github.com/ecomfe/san-cli
San DevTools: https://github.com/baidu/san-devtools
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
