Angular 5生产构建main.bundle过大无vendor文件性能问题求助
Hey there, let's tackle your bundle size issue step by step! The core problem here is that your Webpack configuration isn't set up to extract third-party dependencies (like Angular core, PrimeNG, etc.) into a separate vendor.bundle.js—so all those heavy libraries are getting packed directly into your main.bundle.js, making it way too large. Let's fix this:
1. Identify the Root Cause
Looking at your webpack.common.js config:
- You only have
polyfillsandmainin your entry points, no dedicatedvendorentry - Your
CommonsChunkPluginsetup only handles polyfills and async shared code frommain, but doesn't target third-party dependencies fromnode_modules
This is why you're missing the vendor.bundle and stuck with a 2.8MB main.bundle.
2. Update Webpack Configuration to Extract Vendor Code
Step 2.1 Add a Vendor Entry
First, update the entry object in webpack.common.js to include a vendor entry. You can choose one of two approaches:
Option A: Manual Vendor Dependency List (Recommended for Control)
Create a src/vendor.browser.ts file to list all your third-party dependencies:
// src/vendor.browser.ts // Angular core libraries import '@angular/core'; import '@angular/common'; import '@angular/router'; import '@angular/forms'; // Third-party UI components import 'primeng/button'; import 'primeng/table'; import 'primeng/inputtext'; // Utility libraries import 'rxjs'; import 'font-awesome';
Then update the entry in webpack.common.js:
const entry = { polyfills: './src/polyfills.browser.ts', vendor: './src/vendor.browser.ts', // Add this line main: './src/main.browser.ts' };
Option B: Auto-Detect Node Modules (No Manual Maintenance)
If you don't want to manually update the vendor list, replace the entry with this (Webpack will auto-pull all node_modules dependencies):
const entry = { polyfills: './src/polyfills.browser.ts', main: './src/main.browser.ts', vendor: Object.keys(require('../package.json').dependencies) // Auto-include all package.json dependencies };
Step 2.2 Adjust CommonsChunkPlugin Order & Configuration
Update the plugins array in webpack.common.js to prioritize vendor extraction. The order of CommonsChunkPlugin matters in Webpack 3—process vendor first, then other chunks:
plugins: [ new DefinePlugin({ 'ENV': JSON.stringify(METADATA.ENV), 'HMR': METADATA.HMR, 'AOT': METADATA.AOT, 'process.env.ENV': JSON.stringify(METADATA.ENV), 'process.env.NODE_ENV': JSON.stringify(METADATA.ENV), 'process.env.HMR': METADATA.HMR }), // 1. Keep polyfills as a separate bundle new CommonsChunkPlugin({ name: 'polyfills', chunks: ['polyfills'] }), // 2. Extract all third-party dependencies into vendor.bundle new CommonsChunkPlugin({ name: 'vendor', chunks: ['main'], minChunks: (module) => { // Match all modules from node_modules folder return module.context && module.context.includes('node_modules'); } }), // 3. Keep your existing async shared code extraction new CommonsChunkPlugin({ name: 'main', async: 'common', children: true, minChunks: 2 }), // 4. Keep webpack runtime as inline new CommonsChunkPlugin({ minChunks: Infinity, name: 'inline' }), // ... Leave all other existing plugins (CopyWebpackPlugin, HtmlWebpackPlugin, etc.) as-is ]
3. Ensure AOT & Build Optimizer Are Fully Enabled
Double-check your webpack.prod.js to make sure these optimizations are active:
- Confirm
METADATA.AOTis set totrue(your build command's--aotflag should handle this) - Add the Angular Build Optimizer plugin (install it first with
npm i @angular-devkit/build-optimizer --save-dev):
const BuildOptimizerPlugin = require('@angular-devkit/build-optimizer').BuildOptimizerPlugin; // Add this to your webpack.prod.js plugins array new BuildOptimizerPlugin(),
4. Enable Code Compression
Webpack 3 doesn't enable minification by default in production—add UglifyJsPlugin to webpack.prod.js to shrink your bundles:
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin'); plugins: [ new UglifyJsPlugin({ sourceMap: true, uglifyOptions: { compress: { warnings: false, drop_console: true, // Optional: Remove console logs in production pure_getters: true }, output: { comments: false // Strip all comments } } }), // ... Other prod plugins ]
5. Optional: Add Gzip Compression
For even smaller transfer sizes, pre-generate gzip versions of your bundles with compression-webpack-plugin (install with npm i compression-webpack-plugin@1.1.12 --save-dev—this version works with Webpack 3):
const CompressionPlugin = require('compression-webpack-plugin'); // Add to webpack.prod.js plugins new CompressionPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: /\.(js|css|html|svg)$/, threshold: 8192, minRatio: 0.8 }),
Verify the Fix
Re-run your production build command:
npm run build:prod --aot --build-optimizer
You should now see separate vendor.bundle.js, main.bundle.js, and polyfills.bundle.js files. Your main.bundle should drop to a few hundred KB instead of 2.8MB, which will drastically improve production load times.
内容的提问来源于stack exchange,提问作者Robby

