Angular 2生产捆绑文件太大

15
我使用Webpack打包我的Angular 2项目,但当我打包主文件时,文件太大了,大小约为8M。每次刷新页面时,浏览器需要很长时间来加载和执行JavaScript文件。我认为可能有很多我不需要的文件,但我如何找到它并从我的打包文件中删除它?谢谢给我一些建议或帮助。
这是我的Webpack配置的主要部分: 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
    }

});

我删除了 vendor.ts 文件,这是我的 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';
2个回答

11

我前几天尝试了 Angular 2,遇到了和你一样的问题,我的 vendor.js 文件大小是 6M,而这只是一个简单的“Hello World”应用程序...

我找到了下面这篇文章,对解决这个问题有很大帮助(目前): http://blog.mgechev.com/2016/06/26/tree-shaking-angular2-production-build-rollup-javascript/

他在他的1.5M应用上使用了多种优化和压缩技术(预编译、摇树优化、缩小、打包和gzip),将其大小减小到仅50kb。

看一下,希望有所帮助!:)

编辑: 我尝试过几次 Angular 后,对我来说最好的方法是使用 angular-cli,在我写这篇文章时它已经更新到了 v1.0,当你使用 --prod 运行构建时,它会执行我在原始帖子中提到的所有操作,还会使用常规 Web 服务器压缩文件。我的整个网站大小不到 1MB,其中包含了很多功能和大量的第三方组件。


我最近使用了 gzip 压缩文件,使文件大小达到 330kb,但是我在使用它所创建的 app.js.gz 文件时遇到了问题。似乎浏览器不喜欢它。我已经发布了一个相关问题,请您帮忙查看一下:http://stackoverflow.com/questions/41047617/angular2-gzip-issue-when-i-run-my-app - AngularM
我运行了ng build --prod命令并创建了gzip文件,但是index.html文件没有使用它们。我正在使用angular-cli。有任何想法为什么它仍在使用完整大小的文件? - Vic
我刚试了一下,对我来说它没有创建gzip文件,而这是正确的机制。您的Web服务器应该在运行时压缩文件。在大多数Web服务器上,这是默认设置。 - Thomas Juhász

-3

Angular 2支持懒加载路由组件;您可以使用angular2-router-loader

或者您可以使用Webpack分割配置;

您还可以使用ato / uglify来压缩您的代码;

希望这个答案能够帮助到您。


你的回答是基于XmlHttpRequest的链接,而问题是关于静态解决方案的。你没有回答问题。 - peterh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接