Modularization Overview
Definition and Core Goals of Modularization
Definition of Modularization:
Modularization is a software development approach that breaks down complex systems into independent, manageable units. In front-end development, modularization refers to organizing JavaScript code, styles, templates, and other resources into independent functional units.
Core Goals:
- Code Reuse: Encapsulate reusable functionality to avoid code duplication.
- Dependency Management: Clearly define inter-module dependencies to prevent global namespace pollution.
- Scope Isolation: Each module has its own independent scope to avoid variable conflicts.
- Maintainability: Modular structures make code easier to understand and maintain.
- Team Collaboration: Enables parallel development of different modules by multiple developers.
Evolution of Modularization
History of Front-End Modularization:
- Pre-Modular Era:
- All code resided in the global scope.
- Loaded sequentially via
<script>tags. - Heavy reliance on global variables, leading to naming conflicts.
- IIFE (Immediately Invoked Function Expression) Era:
(function() {
// Module code
var privateVar = 'private variable';
window.moduleAPI = function() { /* ... */ };
})();- Achieved scope isolation via closures.
- Dependencies managed manually.
- CommonJS Era:
- Module system adopted by Node.js.
- Synchronous module loading.
- Uses
require()for imports andmodule.exportsfor exports.
- AMD (Asynchronous Module Definition) Era:
- Asynchronous module system designed for browsers.
- Uses
define()andrequire()to define and load modules. - Representative implementation: RequireJS.
- ES Modules (ES6 Modules) Era:
- Standardized ECMAScript module system.
- Supports static analysis and tree-shaking.
- Uses
import/exportsyntax.
Advantages of Modularization
Key Advantages:
- Maintainability:
- Modular structures make code organization clearer.
- Modifying one module does not affect others.
- Easier to locate and fix issues.
- Extensibility:
- Easy to add new feature modules.
- Loose coupling ensures extensions don’t impact existing functionality.
- Supports progressive enhancement.
- Team Collaboration:
- Different developers can work on separate modules in parallel.
- Clear interface definitions reduce communication overhead.
- Minimizes code conflicts.
- Performance Optimization:
- Supports on-demand loading to reduce initial load times.
- Facilitates code splitting and lazy loading.
- Enables tree-shaking to remove unused code.
Modularization vs. Componentization
| Feature | Modularization | Componentization |
|---|---|---|
| Focus | Code organization and reuse | UI functionality and interaction reuse |
| Granularity | Typically smaller, focused on functionality | Typically larger, includes UI and interaction logic |
| Reuse Method | Via import/export mechanisms | Via component tags or API calls |
| Typical Use | Utility functions, data models, services | UI controls, page sections, composite components |
| Dependencies | Primarily code dependencies | May include styles, templates, and logic dependencies |
| Implementation | ES Modules, CommonJS, etc. | Web Components, framework component systems |
Relationship: Componentization is typically built on top of modularization, with a single component often composed of multiple modules.
Application Scenarios of Modularization
Front-End Applications:
- Single Page Applications (SPAs): Split different functional pages into independent modules.
- Component Library Development: Encapsulate UI components as independent modules.
- Utility Function Libraries: Package reusable functionality into modules.
- State Management: Modularize state management logic (e.g., Redux).
Node.js Server-Side Applications:
- API Routing: Split different route-handling logic into modules.
- Database Access: Modularize data models and access logic.
- Middleware: Encapsulate request-handling middleware as independent modules.
- Service Layer: Package business logic into reusable service modules.
Modularization Standards
IIFE (Immediately Invoked Function Expression) Modularization
Basic Syntax:
(function() {
// Private variables and functions
var privateVar = 'private variable';
function privateFunction() {
console.log(privateVar);
}
// Expose public interface
window.myModule = {
publicMethod: function() {
privateFunction();
}
};
})();Features:
- Achieves scope isolation via closures.
- Dependencies managed manually.
- Simple and easy to use without requiring special tools.
- Lacks support for static dependency analysis.
Improved Version (Dependency Injection):
(function(window, $) {
// Use injected dependencies
var module = {
init: function() {
$('body').css('background', 'white');
}
};
window.myModule = module;
})(window, jQuery);CommonJS Standard (Node.js Module System)
Basic Syntax:
// Export module
const privateVar = 'private variable';
function privateFunction() {
console.log(privateVar);
}
function publicFunction() {
privateFunction();
}
module.exports = {
publicFunction: publicFunction
};
// Or
exports.publicFunction = publicFunction;// Import module
const myModule = require('./myModule');
myModule.publicFunction();Features:
- Synchronous module loading.
require()is a synchronous operation.module.exportsdefines exported content.- Suitable for server-side (fast file system access).
- Cannot be used directly in browsers (requires bundling tools).
AMD (Asynchronous Module Definition) Standard
Basic Syntax:
// Define module
define(['dependency1', 'dependency2'], function(dep1, dep2) {
// Module code
var privateVar = 'private variable';
function privateFunction() {
console.log(privateVar);
}
// Return public interface
return {
publicMethod: function() {
privateFunction();
}
};
});// Load module
require(['myModule'], function(myModule) {
myModule.publicMethod();
});Features:
- Asynchronous module loading.
- Designed for browsers.
- Requires support from libraries like RequireJS.
- Dependencies declared upfront.
- Suitable for browser environments but challenging for static analysis.
ES Modules (ECMAScript Standard Modularization)
Basic Syntax:
// Export
const privateVar = 'private variable';
function privateFunction() {
console.log(privateVar);
}
export function publicFunction() {
privateFunction();
}
// Or
export { publicFunction as renamedFunction };// Import
import { publicFunction } from './myModule.js';
publicFunction();
// Or
import * as myModule from './myModule.js';
myModule.publicFunction();Features:
- ECMAScript standard.
- Supports static analysis (tree-shaking).
- Supported by both browsers and Node.js (with module type considerations).
- Supports dynamic imports (
import()). - Clear and concise syntax.
Browser Usage Example:
<script type="module">
import { publicFunction } from './myModule.js';
publicFunction();
</script>UMD (Universal Module Definition) Standard
Basic Syntax:
(function (global, factory) {
if (typeof define === 'function' && define.amd) {
// AMD environment
define(['dependency'], factory);
} else if (typeof exports !== 'undefined') {
// CommonJS environment
const dependency = require('dependency');
module.exports = factory(dependency);
} else {
// Browser global environment
global.myModule = factory(global.dependency);
}
}(typeof self !== 'undefined' ? self : this, function (dependency) {
// Module code
return {
publicMethod: function() {
// ...
}
};
}));Features:
- Compatible with multiple module systems.
- Usable in both browsers and Node.js.
- Typically generated by bundling tools.
- Complex code, generally not written manually.
Development Environment Setup
Node.js Environment and npm/yarn Package Managers
Node.js Installation:
- Download the installer from Node.js official website.
- Alternatively, use version management tools (e.g., nvm, n).
Verify Installation:
node -v # Check Node.js version
npm -v # Check npm versionnpm Basics:
# Initialize project
npm init
# Install package
npm install lodash # Local installation
npm install -g typescript # Global installation
# Install specific version
npm install lodash@4.17.21
# Install development dependency
npm install eslint --save-dev
# Update packages
npm update
# Uninstall package
npm uninstall lodashyarn Basics:
# Initialize project
yarn init
# Install package
yarn add lodash # Local installation
yarn global add typescript # Global installation
# Install specific version
yarn add lodash@4.17.21
# Install development dependency
yarn add eslint --dev
# Update packages
yarn upgrade
# Uninstall package
yarn remove lodashBrowser Support (Using ES Modules in Browsers)
Browser Support for ES Modules:
- Chrome 61+
- Firefox 60+
- Safari 10.1+
- Edge 16+
- Opera 48+
Basic Usage:
<!-- Direct module import -->
<script type="module">
import { func } from './module.js';
func();
</script>
<!-- Import external module -->
<script type="module">
import { func } from 'https://example.com/module.js';
func();
</script>Notes:
- Module scripts are deferred by default (equivalent to
defer). - External modules require full URLs (including protocol).
- CORS issues may arise (servers must set correct headers).
- Bare module specifiers (e.g.,
import 'lodash') are not supported.
Solving CORS Issues:
- Use a local server during development (e.g.,
http-server,webpack-dev-server). - Ensure production servers set proper
Access-Control-Allow-Originheaders.
Build Tools (Webpack, Rollup, Parcel)
Webpack Configuration Example:
// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
},
mode: 'development'
};Rollup Configuration Example:
// rollup.config.js
import babel from 'rollup-plugin-babel';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'esm'
},
plugins: [
babel({
exclude: 'node_modules/**'
})
]
};Parcel Configuration Example:
// Usually no configuration needed; Parcel auto-detects
// If needed, create .parcelrc
{
"extends": "@parcel/config-default",
"transformers": {
"*.{js,jsx}": ["@parcel/transformer-babel"]
}
}Build Tool Comparison:
| Feature | Webpack | Rollup | Parcel |
|---|---|---|---|
| Main Use | Complex app bundling | Library bundling | Rapid prototyping |
| Config Complexity | High | Medium | Low |
| Plugin Ecosystem | Very rich | Moderately rich | Moderate |
| Tree-Shaking | Supported | Excellent support | Supported |
| Code Splitting | Strong support | Basic support | Basic support |
| Dev Server | Built-in | Requires plugins | Built-in |
Debugging Tools for Modularization (Chrome DevTools)
Debugging Modular Code:
- Sources Panel:
- View loaded modules.
- Set breakpoints to debug module code.
- Use “Go to line” to quickly locate code.
- Network Panel:
- View module loading requests.
- Check module load times and order.
- Filter
.jsortype=modulerequests.
- Console Panel:
- Execute code within module scope.
- Inspect exported module variables.
Debugging Tips:
- Use
debuggerstatements to set breakpoints in code. - Test dynamic imports using
import()in the Console. - Use “Blackboxing” to ignore third-party library code.
- Use “Workspace” to map local file systems for source mapping.
Example Code and Demo Execution
IIFE Module Example:
<!DOCTYPE html>
<script>
// Define module
(function() {
var privateVar = 'IIFE private variable';
function privateFunction() {
console.log(privateVar);
}
window.iifeModule = {
publicMethod: function() {
privateFunction();
}
};
})();
</script>
<script>
// Use module
iifeModule.publicMethod(); // Output: "IIFE private variable"
</script>CommonJS Example (Node.js Environment):
// math.js
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
module.exports = {
add,
subtract
};// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 5
console.log(math.subtract(5, 2)); // 3Run:
node app.jsES Modules Example (Browser Environment):
<!DOCTYPE html>
<script type="module">
import { add, subtract } from './math.js';
console.log(add(2, 3)); // 5
console.log(subtract(5, 2)); // 3
</script>// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}Run (Requires Local Server):
# Use Python simple server
python -m http.server 8000
# Then visit http://localhost:8000Webpack Bundling Example:
- Create Project Structure:
my-webpack-project/
├── src/
│ ├── index.js
│ └── math.js
├── package.json
└── webpack.config.js- File Contents:
// src/math.js
export function add(a, b) {
return a + b;
}// src/index.js
import { add } from './math.js';
console.log(add(2, 3));// webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
mode: 'development'
};- Install Dependencies and Build:
npm init -y
npm install webpack webpack-cli --save-dev
npx webpackCommonJS Modularization
Module Definition and Export (module.exports, exports)
Basic Export Methods:
// Method 1: Directly assign to module.exports
module.exports = {
add: function(a, b) { return a + b; },
subtract: function(a, b) { return a - b; }
};
// Method 2: Add properties to exports object
exports.multiply = function(a, b) { return a * b; };
exports.divide = function(a, b) { return a / b; };Key Differences:
module.exportsis the actual exported object in the module system.exportsis merely a reference tomodule.exports.- Directly assigning to
exportsbreaks this reference.
Correct vs. Incorrect Examples:
// Correct - Add property
exports.func1 = function() {};
// Correct - Directly assign to module.exports
module.exports = function() {};
// Incorrect - Directly assign to exports (won’t work)
exports = function() {}; // This function won’t be exportedNode.js Module Loading Example:
// math.js
module.exports = {
add: (a, b) => a + b,
subtract: (a, b) => a - b
};
// app.js
const math = require('./math');
console.log(math.add(2, 3)); // 5Module Import (require)
Basic Import Syntax:
const module = require('./module.js');
const { specificExport } = require('./module.js'); // ES6 destructuringFeatures of require:
- Synchronous Loading: Blocks execution until the module is loaded.
- Caching Mechanism: Multiple
requirecalls for the same module return the same instance. - File Extension Handling:
.jsextension can be omitted. - Directory as Module: Can
requirea directory (viapackage.json’smainfield orindex.js).
Path Resolution Rules:
- Exact File Paths:
/absolute/path.jsor./relative/path.js. - Extension Completion: Tries
.js,.json,.node. - Directory as Module: Looks for
package.json’smainfield orindex.js. - node_modules Lookup: Recursively searches parent directories.
Practical Example:
// Import JSON file
const config = require('./config.json');
// Import Node.js built-in module
const fs = require('fs');
// Import third-party module
const lodash = require('lodash');
// Import local module (omit extension)
const utils = require('./utils');Module Caching Mechanism
Node.js Module Caching Principle:
- Modules are cached on first
require. - Subsequent
requirecalls return the cached instance. - Caching is based on the module’s fully resolved path.
Cache Verification Example:
// module.js
let counter = 0;
module.exports = {
increment: () => ++counter,
getCounter: () => counter
};
// app.js
const mod1 = require('./module');
const mod2 = require('./module');
mod1.increment();
console.log(mod2.getCounter()); // 1 - Proves it’s the same instanceClearing Cache (Special Cases):
// Note: Not recommended unless necessary
delete require.cache[require.resolve('./module')];
const freshModule = require('./module'); // ReloadCaching Use Cases:
- Singleton pattern implementation.
- Load configuration files once.
- Performance optimization (avoid repeated loading).
Circular Dependency Issues and Solutions
Circular Dependency Example:
// a.js
const b = require('./b');
exports.a = 'a';
console.log('a.js:', b.b);
// b.js
const a = require('./a');
exports.b = 'b';
console.log('b.js:', a.a);Execution Result Analysis:
- Load
a.js. a.jspauses atrequire('./b')and starts loadingb.js.- Load
b.js. b.jspauses atrequire('./a')sincea.jsis already loading.- Return partially exported object from
a.js(at this point,a.ais undefined). b.jscontinues, printingb.js: undefined.b.jscompletes, exporting{b: 'b'}.a.jscontinues, printinga.js: b.
Solutions:
- Refactor Code: Eliminate circular dependencies (best practice).
- Delayed Reference: Use
requireinside functions.
// a.js
exports.a = 'a';
exports.getB = function() { return require('./b').b; };
// b.js
exports.b = 'b';
exports.getA = function() { return require('./a').a; };- Dependency Injection: Pass dependencies via parameters.
Dynamic Loading Features of CommonJS
Dynamic require Example:
// Dynamically load module based on condition
function getPlugin(pluginName) {
try {
return require(`./plugins/${pluginName}`);
} catch (err) {
console.error(`Plugin ${pluginName} not found`);
return null;
}
}
// Load module at runtime
const plugin = getPlugin(process.env.PLUGIN_NAME);Dynamic Loading Use Cases:
- Plugin systems.
- On-demand loading of feature modules.
- Environment-specific implementations.
Notes:
- Dynamic
requirepaths must be string literals or statically analyzable expressions. - Dynamic loading may affect bundler analysis (e.g., Webpack requires special configuration).
- Can lead to unpredictable module caching behavior.
ES Modules Modularization
Module Definition and Export (export, export default)
Named Exports:
// Method 1: Named exports
export const pi = 3.14159;
export function square(x) { return x * x; }
// Method 2: Define then export
const e = 2.71828;
function cube(x) { return x * x * x; }
export { e, cube };Default Export:
// Method 1: Direct default export
export default function() { return 'default'; }
// Method 2: Define then export default
function main() { return 'main function'; }
export default main;Mixed Exports:
export const version = '1.0';
export function helper() { /* ... */ }
export default class MainClass { /* ... */ }Re-export (Module Aggregation):
// utils/index.js
export { foo } from './foo';
export { bar } from './bar';
export { default as baz } from './baz';Module Import (import, import() Dynamic Import)
Named Imports:
// Import specific exports
import { pi, square } from './math';
// Rename on import
import { pi as PI, square as sq } from './math';
// Import all named exports as an object
import * as math from './math';
console.log(math.pi);Default Import:
// Import default export
import mainFunction from './main';
// Mix default and named imports
import mainFunction, { helper } from './main';Dynamic Import (import()):
// Basic usage
import('./module')
.then(module => {
module.someFunction();
})
.catch(err => {
console.error('Module loading failed', err);
});
// Using async/await
async function loadModule() {
try {
const module = await import('./module');
module.someFunction();
} catch (err) {
console.error('Module loading failed', err);
}
}Dynamic Import Use Cases:
- Code splitting and lazy loading.
- On-demand loading of polyfills.
- Conditional loading of different implementations.
Static Analysis Features of ES Modules
Advantages of Static Analysis:
- Tree Shaking: Bundlers can remove unused exports.
- Faster Loading: Browsers can pre-parse dependencies.
- Better Optimization: Compilers can perform deeper optimizations.
Static vs. Dynamic Imports:
// Static import - analyzable
import { func1 } from './module';
// Dynamic import - not statically analyzable
const moduleName = './module-' + condition;
import(moduleName).then(...);Static Import Restrictions:
- Must be at top-level scope (cannot be nested in conditionals).
- Paths must be string literals (not variables).
- Cannot dynamically construct paths.
Workarounds for Static Restrictions:
- Use dynamic
import(). - Refactor code to eliminate dynamic requirements.
- Use bundler-specific features (e.g., Webpack’s magic comments).
Circular Dependency Handling in ES Modules
Circular Dependency Example:
// a.mjs
import { b } from './b.mjs';
export const a = 'a';
console.log('a.mjs:', b);
// b.mjs
import { a } from './a.mjs';
export const b = 'b';
console.log('b.mjs:', a);Execution Result Analysis:
- Load
a.mjs. - Encounter
import { b } from './b.mjs', start loadingb.mjs. - Load
b.mjs. - Encounter
import { a } from './a.mjs', buta.mjsis already loading. - Return
a.mjs’s partially initialized export object (whereais undefined). b.mjscontinues, printingb.mjs: undefined.b.mjscompletes, exporting{ b: 'b' }.a.mjscontinues, printinga.mjs: b.
Key Differences:
- CommonJS: Exports a module instance (may include partially initialized values).
- ES Modules: Exports a namespace object (some exports may be undefined before full initialization).
Solutions:
- Refactor Code: Eliminate circular dependencies (best practice).
- Delayed Reference: Access imported values inside functions.
// a.mjs
import { b } from './b.mjs';
export const a = 'a';
export function getB() { return b; } // Access inside function- Dependency Injection: Pass dependencies via parameters.
Interoperability Between ES Modules and CommonJS
Using ES Modules in Node.js:
- Use
.mjsfile extension. - Or set
"type": "module"inpackage.json.
Interoperability Rules:
- ESM Importing CJS:
- Possible to import.
- CJS’s
module.exportsbecomes ESM’s default export. - CJS named exports may be accessible as ESM named exports (with limitations).
// Import CJS module
import cjsModule from './cjs-module.cjs';
import { namedExport } from './cjs-module.cjs'; // May have limitations- CJS Importing ESM:
- Cannot directly use
require()to import ESM. - Must use dynamic
import().
// Import ESM in CJS
async function loadESM() {
const esmModule = await import('./esm-module.mjs');
esmModule.default();
}Common Issues:
- CJS
thisbinding: In ESM-imported CJS modules,thisisundefined. - CJS
__dirnameand__filename: Unavailable in ESM (useimport.meta.url). - CJS dynamic
require: Cannot be used directly in ESM.
Conversion Example:
// CJS module
module.exports = {
add: (a, b) => a + b
};
// Equivalent ESM module
export const add = (a, b) => a + b;Modularization Toolchain
Webpack Module Bundling Principles (Entry, Dependency Graph, Output)
Webpack Bundling Process:
- Initialize Parameters: Merge parameters from config and shell commands.
- Start Compilation: Initialize Compiler object with parameters.
- Determine Entry: Identify all entry files based on configuration.
- Compile Modules: Translate modules using configured Loaders, starting from entry files.
- Complete Module Compilation: Obtain final translated content and dependency relationships.
- Output Resources: Assemble modules into Chunks based on entry and dependencies.
- Finish Output: Write files to the file system based on configured paths and filenames.
Core Concepts:
- Entry:
module.exports = {
entry: './src/index.js' // Single entry
// Or
entry: {
app: './src/app.js',
admin: './src/admin.js' // Multiple entries
}
};- Output:
module.exports = {
output: {
filename: '[name].bundle.js', // Output filename
path: path.resolve(__dirname, 'dist'), // Output path
publicPath: '/' // Public path
}
};- Loaders:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}
]
}
};- Plugins:
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
})
]
};Rollup Module Bundling Principles (Tree Shaking, ES Modules Optimization)
Rollup Core Features:
- ES Modules-Based: Leverages ESM’s static structure.
- Tree Shaking: Automatically removes unused code.
- Cleaner Output: Generates code closer to handwritten code.
Tree Shaking Mechanism:
- Static Analysis: Parse AST to determine export/import relationships.
- Mark Usage: Identify which exports are actually used.
- Code Generation: Include only marked, used code.
Rollup Configuration Example:
// rollup.config.js
export default {
input: 'src/index.js', // Entry file
output: {
file: 'bundle.js', // Output file
format: 'esm' // Output format (esm, cjs, umd, iife)
},
plugins: [
// Plugin list
]
};Tree Shaking Configuration:
// Ensure ESM format for optimal Tree Shaking
export default {
input: 'src/index.js',
output: {
file: 'bundle.js',
format: 'esm' // Must use ESM format
},
treeshake: {
// Advanced configuration
moduleSideEffects: false, // Assume no module side effects
propertyReadSideEffects: false, // Assume property access has no side effects
tryCatchDeoptimization: false // Don’t optimize try-catch blocks
}
};Rollup Plugin System:
// Custom Rollup plugin example
export default function myPlugin() {
return {
name: 'my-plugin',
transform(code, id) {
// Transform code
if (id.endsWith('.custom')) {
return {
code: code.replace(/custom/g, 'standard'),
map: null
};
}
return null;
}
};
}Parcel Module Bundling Principles (Zero Configuration, Multi-Format Support)
Parcel Core Features:
- Zero Configuration: Ready to use out of the box.
- Multi-Format Support: Automatically detects input/output formats.
- Multi-Core Compilation: Leverages multi-core CPUs for faster builds.
- Hot Module Replacement: Built-in HMR support.
Parcel Mechanism:
- File System Cache: Caches build results to speed up subsequent builds.
- Dependency Graph: Automatically builds a complete dependency graph.
- Transformation Pipeline: Applies appropriate transformers based on file type.
- Bundling: Packages all resources into optimal formats.
Parcel Configuration Example:
// .parcelrc (usually not needed)
{
"extends": "@parcel/config-default",
"transformers": {
"*.myext": ["@parcel/transformer-raw"]
}
}Parcel Plugin Development:
// Custom Parcel plugin example
import { Transformer } from '@parcel/plugin-api';
export default new Transformer({
async transform({ asset }) {
// Get asset content
let code = await asset.getCode();
// Transform code
code = code.replace(/custom/g, 'standard');
// Update asset content
asset.setCode(code);
// Return transformed asset
return [asset];
}
});Babel Module Transformation (CommonJS to ES Modules)
Babel Core Features:
- Syntax Transformation: Converts new syntax to browser-compatible code.
- Polyfills: Adds missing APIs.
- Module Transformation: Converts between module systems.
Babel Configuration Example:
// .babelrc
{
"presets": [
["@babel/preset-env", {
"targets": "> 0.25%, not dead",
"modules": false // Preserve ES Modules
}]
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}CommonJS to ES Modules Transformation:
// babel-plugin-transform-commonjs (concept example)
// Converts require to import
// Converts module.exports to export
// Before transformation
const fs = require('fs');
module.exports = { read: fs.readFileSync };
// After transformation
import fs from 'fs';
export const read = fs.readFileSync;Practical Usage:
# Install dependencies
npm install --save-dev @babel/core @babel/cli @babel/preset-env
# Transform files
npx babel src --out-dir lib --presets=@babel/preset-envAdvanced Transformation Configuration:
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
modules: 'auto', // Auto-detect module transformation
exclude: ['transform-typeof-symbol'] // Exclude specific transformations
}]
],
plugins: [
['@babel/plugin-transform-modules-commonjs', {
strictMode: false,
noInterop: true // Skip interop code
}]
]
};Configuration and Optimization of Modularization Toolchain
General Optimization Strategies:
- Caching: Leverage build tool caching mechanisms.
- Parallel Processing: Use multi-core CPUs to speed up builds.
- Code Splitting: Split code into reasonable chunks.
- Tree Shaking: Remove unused code.
- On-Demand Loading: Dynamically import non-critical code.
Webpack Optimization Configuration:
// webpack.prod.js
module.exports = {
mode: 'production',
optimization: {
minimize: true,
splitChunks: {
chunks: 'all',
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
}
}
},
runtimeChunk: 'single'
},
performance: {
hints: 'warning',
maxAssetSize: 250000,
maxEntrypointSize: 250000
}
};Rollup Optimization Configuration:
// rollup.prod.js
import { terser } from 'rollup-plugin-terser';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.min.js',
format: 'esm'
},
plugins: [
terser() // Code minification
],
treeshake: {
moduleSideEffects: false
}
};Parcel Optimization Configuration:
// .parcelrc
{
"extends": "@parcel/config-default",
"optimizers": {
"*.js": ["@parcel/optimizer-terser"]
},
"reporters": ["...", "@parcel/reporter-bundle-analyzer"]
}Build Performance Analysis Tools:
- Webpack Bundle Analyzer:
npm install --save-dev webpack-bundle-analyzerconst BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};- Rollup Plugin Visualizer:
npm install --save-dev rollup-plugin-visualizerimport { visualizer } from 'rollup-plugin-visualizer';
export default {
plugins: [
visualizer()
]
};



