Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 production bundle file is too large

Tags:

angular

bundle

i use webpack bundle my angular 2 project, when i bundle the main file. the file is too large, the file size is about 8M. then whenever i refresh my page, there will be a long time for the browser to load and execute the javascript files. I think there may be too many files that i don't needs,but how can i find it and kick it out of my bundle files? thank u for give me some advice or some help.

here is my main part of webpack config: webpack.common.js:

const webpack = require('webpack');
const helpers = require('./helpers');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

module.exports = {
    baseUrl: './',
    entry: {
        // 'polyfills': './src/polyfills.ts',
        // 'vendor': './src/vendor.ts',
        'main': './src/main.ts'
    },
    resolve: {
        extensions: ['', '.ts', '.js', '.json'],
        root: helpers.root('src'),
        modulesDirectories: ['node_modules'],
    },
    module: {
        loaders: [
            {
                test: /\.ts$/,
                loaders: ['awesome-typescript-loader', 'angular2-template-loader'],
                exclude: [/\.(spec|e2e)\.ts$/]
            },
            {
                test: /\.json$/,
                loader: 'json-loader'
            },
            {
                test: /\.css$/,
                loaders: ['raw-loader']
            },
            {
                test: /\.html$/,
                loader: 'raw-loader',
                exclude: [helpers.root('src/index.html')]
            },
            {
                test: /\.scss$/,
                loaders: ['raw-loader', 'sass-loader'] // sass-loader not scss-loader
            },
            {
                test: /\.(jpg|png|gif)$/,
                loader: 'file'
            },
            {
                test: /.(png|woff(2)?|eot|ttf|svg)$/,
                loader: 'url-loader'
            }
        ]

    },
    plugins: [
        new ForkCheckerPlugin(),
        // new CopyWebpackPlugin([
        //     {from: 'src/assets', to: 'assets'},
        //     {from: 'src/app/i18n', to: 'app/i18n'},
        //     {from: 'src/loading.css', to: 'loading.css'},
        //     {from: 'src/fonts', to: 'fonts'},
        //     {from: 'src/favicon.ico', to: ''},
        //     {from: 'src/img', to: 'img'}]),
        new HtmlWebpackPlugin({
            template: 'src/index.html',
            chunksSortMode: 'dependency'
        })
    ],

    node: {
        global: 'window',
        crypto: 'empty',
        process: true,
        module: false,
        clearImmediate: false,
        setImmediate: false
    }

};

webpack.prod.js

const helpers = require('./helpers');
const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js'); // the settings that are common to prod and dev
/**
 * Webpack Plugins
 */
const webpack = require('webpack');
const ProvidePlugin = require('webpack/lib/ProvidePlugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const IgnorePlugin = require('webpack/lib/IgnorePlugin');
const DedupePlugin = require('webpack/lib/optimize/DedupePlugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;
const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
const HOST = process.env.HOST || 'localhost';

module.exports = webpackMerge(commonConfig, {
    devtool: 'source-map',

    output: {
        path: helpers.root('dist'),
        filename: '[name].bundle.js',
        chunkFilename: '[id].chunk.js'
    },

    plugins: [
        // new webpack.NoErrorsPlugin(), // 如果出现任何错误 就终止构建
        // new DedupePlugin(), // 检测完全相同(以及几乎完全相同)的文件 并把它们从输出中移除
        // new webpack.optimize.CommonsChunkPlugin({
        //     name: ['polyfills', 'vendor', 'main'].reverse()
        // }),
        new UglifyJsPlugin({
            beautify: false,
            mangle: { screw_ie8 : true, keep_fnames: true },
            compress: { screw_ie8: true, warnings: false },
            comments: false
        }),
        // new ExtractTextPlugin('[name].[hash].css'), // 把内嵌的 css 抽取成玩不文件 并为其文件名添加 hash 后缀 使得浏览端缓存失效
        new DefinePlugin({ // 定义环境变量
            'process.env': {
                ENV: JSON.stringify(ENV)
            }
        }),
    ],

    htmlLoader: {
        minimize: true,
        removeAttributeQuotes: false,
        caseSensitive: true,
        customAttrSurround: [
            [/#/, /(?:)/],
            [/\*/, /(?:)/],
            [/\[?\(?/, /(?:)/]
        ],
        customAttrAssign: [/\)?\]?=/]
    },

    tslint: {
        emitErrors: true,
        failOnHint: true,
        resourcePath: 'src'
    },

    node: {
        global: 'window',
        crypto: 'empty',
        process: false,
        module: false,
        clearImmediate: false,
        setImmediate: false
    }

});

i dropped my vendor.ts file here is my polyfills.ts

// This file includes polyfills needed by Angular 2 and is loaded before
// the app. You can add your own extra polyfills to this file.
// Added parts of es6 which are necessary for your project or your browser support requirements.
import 'core-js/es6/symbol';
import 'core-js/es6/object';
import 'core-js/es6/function';
import 'core-js/es6/parse-int';
import 'core-js/es6/parse-float';
import 'core-js/es6/number';
import 'core-js/es6/math';
import 'core-js/es6/string';
import 'core-js/es6/date';
import 'core-js/es6/array';
import 'core-js/es6/regexp';
import 'core-js/es6/map';
import 'core-js/es6/set';
import 'core-js/es6/reflect';
import 'core-js/es6/weak-map';
import 'core-js/es6/weak-set';

import 'core-js/es7/reflect';
import 'zone.js/dist/zone';
like image 767
shun Avatar asked Sep 23 '16 02:09

shun


People also ask

How to reduce module size in Angular?

The easiest way to significantly reduce the size of your Angular application is to use the --prod meta flag when you use ng build in the CLI.

How do I make Angular builds smaller?

Use latest angular cli version and use command ng build --prod --build-optimizer It will definitely reduce the build size for prod env.

What is bundle size in Angular?

This will give you a warning if you build Angular and the bundle size exceeds 2MB and throw an error if the bundle size exceeds 5MB. You can adjust the numbers as per your need. You can leverage this feature in your CI/CD pipeline.


1 Answers

I was trying out angular 2 the other day and I faced the same issue as you do, my vendor.js was 6M and this was a simple "Hello World" app...

I've found the following post that helped a lot in understanding how we should act on this issue (for now): http://blog.mgechev.com/2016/06/26/tree-shaking-angular2-production-build-rollup-javascript/

He uses several optimizing and compression techniques (precompile,treeshake, minify, bundle and gzip) on his 1.5M app to reduce its size to just 50kb.

Check it out, hope it helps! :)

EDIT: I've had a few runs with Angular since, and for me the best working approach was to use the angular-cli, which is at v1.0 when I'm writing this and when you run the build with --prod it does everything I wrote in my original post +a usual web server gzips your files. My complete site is under 1MB with this and his has a lot of functionality and also plenty third party stuff as well.

like image 103
Thomas Juhász Avatar answered Sep 30 '22 10:09

Thomas Juhász