угловая сборка 5 создает main.bundle в МБ, что создает проблемы с производительностью - PullRequest
0 голосов
/ 17 мая 2018

Я использую Angular 5 для своего проекта с веб-пакетом 3.10. Когда я пытаюсь собрать приложение, сборка имеет основной пакетный файл размером примерно 2,8 МБ, что создает проблемы с производительностью в производственной среде. Я использую "npm run build: prod --aot --build-optimizer" для сборки приложения. Я просмотрел другие статьи о переполнении стека, чтобы понять решение, и понял, что сборка, которая у меня есть, не содержит файла поставщика. Я пытался использовать разные способы, предложенные в разных статьях, но все тщетно. пожалуйста, помогите в этом. для справки я загружаю свои webpack.config.js, webpack.common.js, webpack.prod.js, main.browser.ts, polyfills.ts

webpack.config.js

switch (process.env.NODE_ENV) {
  case 'prod':
  case 'production':
    module.exports = require('./config/webpack.prod')({env: 'production'});
    break;
  case 'test':
  case 'testing':
    module.exports = require('./config/webpack.test')({env: 'test'});
    break;
  case 'dev':
  case 'development':
  default:
    module.exports = require('./config/webpack.dev')({env: 'development'});
}

webpack.common.js

const helpers = require('./helpers');

/**
 * Webpack Plugins
 *
 * problem with copy-webpack-plugin
 */
const DefinePlugin = require('webpack/lib/DefinePlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlElementsPlugin = require('./html-elements-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const ngcWebpack = require('ngc-webpack');

const buildUtils = require('./build-utils');


/**
 * Webpack configuration
 *
 * See: http://webpack.github.io/docs/configuration.html#cli
 */
module.exports = function (options) {
  const isProd = options.env === 'production';
  const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, options.metadata || {});
  const ngcWebpackConfig = buildUtils.ngcWebpackSetup(isProd, METADATA);
  const supportES2015 = buildUtils.supportES2015(METADATA.tsConfigPath);

  const entry = {
    polyfills: './src/polyfills.browser.ts',
    main:      './src/main.browser.ts'
  };

  Object.assign(ngcWebpackConfig.plugin, {
    tsConfigPath: METADATA.tsConfigPath,
    mainPath: entry.main
  });

  return {

    entry: entry,


    resolve: {
      mainFields: [ ...(supportES2015 ? ['es2015'] : []), 'browser', 'module', 'main' ],

      extensions: ['.ts', '.js', '.json'],


      modules: [helpers.root('src'), helpers.root('node_modules')],


      alias: buildUtils.rxjsAlias(supportES2015)
    },


    module: {

      rules: [
        ...ngcWebpackConfig.loaders,


        {
          test: /\.css$/,
          use: ['to-string-loader', 'css-loader'],
          exclude: [helpers.root('src', 'styles')]
        },


        {
          test: /\.scss$/,
          use: ['to-string-loader', 'css-loader', 'sass-loader'],
          exclude: [helpers.root('src', 'styles')]
        },

        {
          test: /\.html$/,
          use: 'raw-loader',
          exclude: [helpers.root('src/index.html')]
        },

        /**
         * File loader for supporting images, for example, in CSS files.
         */
        {
          test: /\.(jpg|png|gif)$/,
          use: 'file-loader'
        },

        /* File loader for supporting fonts, for example, in CSS files.
        */
        {
          test: /\.(eot|woff2?|svg|ttf)([\?]?.*)$/,
          use: 'file-loader'
        }

      ],

    },

    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
      }),


      new CommonsChunkPlugin({
        name: 'polyfills',
        chunks: ['polyfills']
      }),

      new CommonsChunkPlugin({
        minChunks: Infinity,
        name: 'inline'
      }),
      new CommonsChunkPlugin({
        name: 'main',
        async: 'common',
        children: true,
        minChunks: 2
      }),



      new CopyWebpackPlugin([
        { from: helpers.root('src/assets'), to: 'assets' },
        { from: helpers.root('src/assets/img'), to: 'assets/img' },
        { from: helpers.root('src/meta')},
        { from: helpers.root('node_modules/font-awesome'), to: 'font-awesome' },
        { from: helpers.root('node_modules/primeng/resources/primeng.min.css'), to: 'resources' },
        { from: helpers.root('node_modules/primeng/resources/themes/_theme.scss'), to: 'resources/themes' },
        { from: helpers.root('src/assets/css/themes/citi-prime'), to: 'resources/themes/citi-prime' }
      ],
        isProd ? { ignore: [ 'mock-data/**/*' ] } : undefined
      ),

      /*
      * Plugin: HtmlWebpackPlugin
      * Description: Simplifies creation of HTML files to serve your webpack bundles.
      * This is especially useful for webpack bundles that include a hash in the filename
      * which changes every compilation.
      *
      * See: https://github.com/ampedandwired/html-webpack-plugin
      */
      new HtmlWebpackPlugin({
        template: 'src/index.html',
        title: METADATA.title,
        chunksSortMode: function (a, b) {
          const entryPoints = ["inline","polyfills","sw-register","styles","vendor","main"];
          return entryPoints.indexOf(a.names[0]) - entryPoints.indexOf(b.names[0]);
        },
        metadata: METADATA,
        inject: 'body',
        xhtml: true,
        minify: isProd ? {
          caseSensitive: true,
          collapseWhitespace: true,
          keepClosingSlash: true
        } : false//,
        //baseUrl: isProd ? '.' : '/'
      }),


      new ScriptExtHtmlWebpackPlugin({
        sync: /inline|polyfills|vendor/,
        defaultAttribute: 'async',
        preload: [/polyfills|vendor|main/],
        prefetch: [/chunk/]
      }),

      new HtmlElementsPlugin({
        publicPath: '/',
        headTags: require('./head-config.common')
      }),


      new LoaderOptionsPlugin({}),

      new ngcWebpack.NgcWebpackPlugin(ngcWebpackConfig.plugin),


      new InlineManifestWebpackPlugin(),
    ],


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

  };
}

wepack.prod.js


const helpers = require('./helpers');
const buildUtils = require('./build-utils');

/**
 * Used to merge webpack configs
*/
const webpackMerge = require('webpack-merge');
/**
 * The settings that are common to prod and dev
*/
const commonConfig = require('./webpack.common.js');

/**
 * Webpack Plugins
 */
const SourceMapDevToolPlugin = require('webpack/lib/SourceMapDevToolPlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HashedModuleIdsPlugin = require('webpack/lib/HashedModuleIdsPlugin')
const PurifyPlugin = require('@angular-devkit/build-optimizer').PurifyPlugin;
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');



function getUglifyOptions (supportES2015) {
  const uglifyCompressOptions = {
    pure_getters: true, /* buildOptimizer */
    // PURE comments work best with 3 passes.
    // See https://github.com/webpack/webpack/issues/2899#issuecomment-317425926.
    passes: 3         /* buildOptimizer */
  };

  return {
    ecma: supportES2015 ? 6 : 5,
    warnings: false,    // TODO verbose based on option?
    ie8: false,
    mangle: true,
    compress: uglifyCompressOptions,
    output: {
      ascii_only: true,
      comments: false
    }
  };
}

module.exports = function (env) {
  const ENV = process.env.NODE_ENV = process.env.ENV = 'production';
  const supportES2015 = buildUtils.supportES2015(buildUtils.DEFAULT_METADATA.tsConfigPath);
  const METADATA = Object.assign({}, buildUtils.DEFAULT_METADATA, {
    host: process.env.HOST || 'localhost',
    port: process.env.PORT || 8080,
    ENV: ENV,
    HMR: false
  });


  METADATA.envFileSuffix = METADATA.E2E ? 'e2e.prod' : 'prod';

  return webpackMerge(commonConfig({ env: ENV, metadata: METADATA }), {


    output: {


      path: helpers.root('dist'),


      filename: '[name].[chunkhash].bundle.js',


      sourceMapFilename: '[file].map',


      chunkFilename: '[name].[chunkhash].chunk.js'

    },

    module: {

      rules: [


        {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: 'css-loader'
          }),
          include: [helpers.root('src', 'styles')]
        },


        {
          test: /\.scss$/,
          loader: ExtractTextPlugin.extract({
            fallback: 'style-loader',
            use: 'css-loader!sass-loader'
          }),
          include: [helpers.root('src', 'styles')]
        },

      ]

    },


    plugins: [

      new SourceMapDevToolPlugin({
        filename: '[file].map[query]',
        moduleFilenameTemplate: '[resource-path]',
        fallbackModuleFilenameTemplate: '[resource-path]?[hash]',
        sourceRoot: 'webpack:///'
      }),



      new ExtractTextPlugin('[name].[contenthash].css'),

      new PurifyPlugin(), /* buildOptimizer */

      new HashedModuleIdsPlugin(),
      new ModuleConcatenationPlugin(),


      new UglifyJsPlugin({
        sourceMap: true,
        uglifyOptions: getUglifyOptions(supportES2015)
      }),
     
    

    ],


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

  });
}

S

main.browser.js

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { environment } from 'environments/environment';

//import '../node_modules/font-awesome/css/font-awesome.min.css';
//import '../node_modules/primeng/resources/themes/omega/theme.scss';
//import '../node_modules/primeng/resources/primeng.min.css';

import './styles/styles.scss'


import { AppModule } from './app';


export function main(): Promise<any> {
  return platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .then(environment.decorateModuleRef)
    .catch((err) => console.error(err));
}


switch (document.readyState) {
  case 'loading':
    document.addEventListener('DOMContentLoaded', _domReadyHandler, false);
    break;
  case 'interactive':
  case 'complete':
  default:
    main();
}

function _domReadyHandler() {
 document.removeEventListener('DOMContentLoaded', _domReadyHandler, false);
 main();
}

polyfills.js

 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/weak-map';
 import 'core-js/es6/set';


 import 'classlist.js';  // Run `npm install --save classlist.js`.


import 'core-js/es6/reflect';
import 'core-js/es7/reflect';



 import 'web-animations-js';  // Run `npm install --save web-animations-js`.

import 'zone.js/dist/zone';

if ('production' === ENV) {
  // Production

} else {

  // Development
}

Ответы [ 3 ]

0 голосов
/ 17 мая 2018

У вас могут быть компоненты / директивы / модули, объявленные в одном большом модуле, а не отдельно.

В нашем проекте эта проблема возникла из-за исторического контекста.Затем наш основной блок включает в себя некоторые другие модули, которые должны быть в отдельном блоке.Это из-за плохой структуры.

Конечно, лениво загруженные модули - ваши друзья, как упоминалось Пани Кумар .

0 голосов
/ 26 июня 2018

я вижу, что в package.json есть скрипт aot- 'npm run build: aot: prod'.это позволит включить во время компиляции кода.команда, которую вы запускаете, может быть не включена в приложении.Кроме того, просто убедитесь, что AOT работает, вам нужно переместить все закрытые переменные и методы в общедоступные, а также проверить наличие мертвого кода в html, если он выдает ошибку.Надеюсь, что это работает.

0 голосов
/ 17 мая 2018
Размер

main.bundle.js может быть уменьшен отложенной загрузкой, которая создает модули, которые могут быть загружены по требованию

пример:

import { Routes, RouterModule } from "@angular/router";
import { ModuleWithProviders } from "@angular/core";



import { AuthenticateService } from '../authenticate/authenticate.module';
import { FacilitiesComponent } from './components/facilities.component';


const projectsRoutes: Routes = [

    {
        path: '',
        component: FacilitiesComponent,
        canActivate: [AuthenticateService],
        canActivateChild: [AuthenticateService],
        children: [
            {
                path: 'projectlist',
                loadChildren: './projects-list/projects-list.module#ProjectsListModule'
            },
            {
                path: 'project/:pid/docmng/:fid',
                loadChildren: '../facilities/project-document/project.module#ProjectModule'
            }
        ]
    }
];



export const FacilitiesRouting: ModuleWithProviders = RouterModule.forChild(projectsRoutes);


$ npm run build

> skysite-platform-client2@0.0.0 build E:\SkySite-new\skysite-platform-client
> ng build --prod

Date: 2018-05-17T12:40:26.949Z
Hash: 0b89e566c023ac3d2fb5
Time: 156588ms
chunk {8} 8.3421be99f16d735369c2.chunk.js () 1.67 kB  [rendered]
chunk {scripts} scripts.b23d003bdba35060d12d.bundle.js (scripts) 503 kB [initial] [rendered]
chunk {0} 0.e85cc76f90b3ae5b88a6.chunk.js (common) 123 kB  [rendered]
chunk {1} 1.31677c41f09d5a650d83.chunk.js () 2.47 MB  [rendered]
chunk {2} 2.52380e8925d7e658149e.chunk.js () 89.9 kB  [rendered]
chunk {3} 3.92474b63b4fbb521a866.chunk.js () 82.5 kB  [rendered]
chunk {4} 4.0faac9190c7b1e36d1e6.chunk.js () 151 kB  [rendered]
chunk {5} 5.f3296c5e15119655f3ce.chunk.js () 1.77 kB  [rendered]
chunk {6} 6.eb8af258a302bd9d066e.chunk.js () 131 kB  [rendered]
chunk {7} 7.0521fe6f5f3714081264.chunk.js () 115 kB  [rendered]
chunk {9} 9.92a24c750caada0e26c2.chunk.js () 9.35 kB  [rendered]
chunk {10} 10.3dd571f08fa3895c8730.chunk.js () 49 kB  [rendered]
chunk {11} polyfills.165ea84e5245184acc68.bundle.js (polyfills) 98.2 kB [initial] [rendered]
chunk {12} main.b02e6fabeb708e73d01f.bundle.js (main) 500 kB [initial] [rendered]
chunk {13} styles.cdbcc00089657e555f43.bundle.css (styles) 222 kB [initial] [rendered]
chunk {14} inline.3153333f01d40d57ce09.bundle.js (inline) 1.65 kB [entry] [rendered]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...