0

I have implemented webpack as angular pages are too slow to load (taking 1m+ to load). bundled app.js generated by webpack is very huge in size (around 27MB). hence trying to minify the file using uglify plugin but not able to get that.

Have used the below webpack config but files are not getting minified using the UglifyJsPlugin. Please can you assist if i am missing something.

Appreciate your help and thanks in advance.

Code -

    // Helper: root() is defined at the bottom
    var path = require('path');
    var webpack = require('webpack');

    // Webpack Plugins
    var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
    var autoprefixer = require('autoprefixer');
    var HtmlWebpackPlugin = require('html-webpack-plugin');
    var ExtractTextPlugin = require('extract-text-webpack-plugin');
    var CopyWebpackPlugin = require('copy-webpack-plugin');

    var ENV = process.env.npm_lifecycle_event;
    var isTestWatch = ENV === 'test-watch';
    var isTest = ENV === 'test' || isTestWatch;
    var isProd = ENV === 'build';

    module.exports = function makeWebpackConfig() {
    var config = {};

    if (isProd) {
        config.devtool = 'source-map';
    }
    else if (isTest) {
        config.devtool = 'inline-source-map';
    }
    else {
        config.devtool = 'eval-source-map';
    }

    if (!isTest) {

        config.entry = isTest ? {} : {
            'polyfills': './src/polyfills.ts',
            'vendor': './src/vendor.ts',
            'app': './src/main.ts' // our angular app
        };
    }

    config.output = isTest ? {} : {
        path: root('dist'),
        publicPath: isProd ? '/' : 'http://localhost:8080/',
        filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
        chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
    };

    config.resolve = {
        // only discover files that have those extensions
        extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
    };

    var atlOptions = '';
    if (isTest && !isTestWatch) {

        atlOptions = 'inlineSourceMap=true&sourceMap=false';
    }


    config.module = {
        rules: [
          // Support for .ts files.
          {
              test: /\.ts$/,
              loaders: ['awesome-typescript-loader?' + atlOptions, 'angular2-template-loader', '@angularclass/hmr-loader'],
              exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]
          },

          // copy those assets to output
          {
              test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
              loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
          },

          // Support for *.json files.
          { test: /\.json$/, loader: 'json-loader' },

          // Support for CSS as raw text
          // use 'null' loader in test mode (https://github.com/webpack/null-loader)
          // all css in src/style will be bundled in an external css file
          {
              test: /\.css$/,
              exclude: root('src', 'app'),
              loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader'] })
          },
          // all css required in src/app files will be merged in js files
          { test: /\.css$/, include: root('src', 'app'), loader: 'raw-loader!postcss-loader' },

          // support for .scss files
          // use 'null' loader in test mode (https://github.com/webpack/null-loader)
          // all css in src/style will be bundled in an external css file
          {
              test: /\.(scss|sass)$/,
              exclude: root('src', 'app'),
              loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'postcss-loader', 'sass-loader'] })
          },
          // all css required in src/app files will be merged in js files
          { test: /\.(scss|sass)$/, exclude: root('src', 'style'), loader: 'raw-loader!postcss-loader!sass-loader' },

          // support for .html as raw text
          // todo: change the loader to something that adds a hash to images
          { test: /\.html$/, loader: 'raw-loader', exclude: root('src', 'public') }
        ]
    };

    if (isTest && !isTestWatch) {
        // instrument only testing sources with Istanbul, covers ts files
        config.module.rules.push({
            test: /\.ts$/,
            enforce: 'post',
            include: path.resolve('src'),
            loader: 'istanbul-instrumenter-loader',
            exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]
        });
    }

    if (!isTest || !isTestWatch) {
        // tslint support
        config.module.rules.push({
            test: /\.ts$/,
            enforce: 'pre',
            loader: 'tslint-loader'
        });
    }


    config.plugins = [
      // Define env variables to help with builds
      // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
      new webpack.DefinePlugin({
          // Environment helpers
          'process.env': {
              ENV: JSON.stringify(ENV)
          }
      }),

      // Workaround needed for angular 2 angular/angular#11580
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)@angular/,
        root('./src') // location of your src
      ),

      // Tslint configuration for webpack 2
      new webpack.LoaderOptionsPlugin({
          options: {

              tslint: {
                  emitErrors: false,
                  failOnHint: false
              },

              sassLoader: {
                  //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
              },

              postcss: [
                autoprefixer({
                    browsers: ['last 2 version']
                })
              ]
          }
      })
    ];

    if (!isTest && !isTestWatch) {
        config.plugins.push(
          // Generate common chunks if necessary
          // Reference: https://webpack.github.io/docs/code-splitting.html
          // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
          new CommonsChunkPlugin({
              name: ['vendor', 'polyfills']
          }),

          // Inject script and link tags into html files
          // Reference: https://github.com/ampedandwired/html-webpack-plugin
          new HtmlWebpackPlugin({
              template: './src/public/index.html',
              chunksSortMode: 'dependency'
          }),

          //new webpack.optimize.UglifyJsPlugin({ sourceMap: true, mangle: { keep_fnames: true } }),

          new webpack.optimize.UglifyJsPlugin({
              mangle: true,
              compress: {
                  sequences: true,
                  dead_code: true,
                  conditionals: true,
                  booleans: true,
                  unused: true,
                  if_return: true,
                  join_vars: true,
                  drop_console: true
              }
          }),

          // Extract css files
          // Reference: https://github.com/webpack/extract-text-webpack-plugin
          // Disabled when in test mode or not in build mode
          new ExtractTextPlugin({ filename: 'css/[name].[hash].css', disable: !isProd })
        );
    }

    // Add build specific plugins
    if (isProd) {
        config.plugins.push(
          // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
          // Only emit files when there are no errors
          new webpack.NoEmitOnErrorsPlugin(),

          // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
          // // Dedupe modules in the output
          // new webpack.optimize.DedupePlugin(),

          // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
          // Minify all javascript, switch loaders to minimizing mode
          //new webpack.optimize.UglifyJsPlugin({ sourceMap: true, mangle: { keep_fnames: true } }),

          new webpack.optimize.UglifyJsPlugin({
              mangle: true,
              compress: {
                  sequences: true,
                  dead_code: true,
                  conditionals: true,
                  booleans: true,
                  unused: true,
                  if_return: true,
                  join_vars: true,
                  drop_console: true
              }
          }),   // **this piece of code block is not minifying the js files.**


          // Copy assets from the public folder
          // Reference: https://github.com/kevlened/copy-webpack-plugin
          new CopyWebpackPlugin([{
              from: root('src/public')
          }])
        );
    }

    /**
     * Dev server configuration
     * Reference: http://webpack.github.io/docs/configuration.html#devserver
     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
     */
    config.devServer = {
        contentBase: './src/public',
        historyApiFallback: true,
        quiet: true,
        stats: 'minimal' // none (or false), errors-only, minimal, normal (or true) and verbose
    };

    return config;
}();

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}
chint
  • 47
  • 1
  • 8
  • The config is making the uglification conditional i.e. when `isProd` is true. Could be that the `ENV` value is not 'build' ? Can you confirm ? Side note : if you haven't done already, i recommend to divide up the config into multiple files to make it more easier to understand. – Rakesh Kumar Cherukuri Dec 05 '17 at 20:33
  • yes it is conditional and i have forced the execution to go inside it but with no luck. do i need to add another plugin to minify ? or else if you can point me to some working implementation will also help. i have referred above config from git hub but it seems to be not working as expected. – chint Dec 06 '17 at 02:38
  • Hmm, ok. Its not obvious as to why the config is not working. The only way i see is to debug. I would suggest to start with minimal plugin config. For ex https://webpack.js.org/plugins/uglifyjs-webpack-plugin/#usage. Take out all other plugins except minification. Even the minification plugin takeout all the options and use default.The code needs a bit of refactoring though. The more manageable the config is, the clear the issue will be. – Rakesh Kumar Cherukuri Dec 06 '17 at 04:46
  • Any idea on how to include only the app folder under the webpack rules snapshot given below. I suspect that webpack is taking all the 'ts' files i.e even of node_modules folder. i will need only the ts files bundling under the app folder. i have tried that below but no luck. { test: /\.ts$/, loaders: ['awesome-typescript-loader?' + atlOptions, 'angular2-template-loader', '@angularclass/hmr-loader'], exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/] }, – chint Dec 06 '17 at 06:39
  • Thats a different question. Please do try finding if a question already exists before posting. Here is one you may find useful : https://stackoverflow.com/questions/33001237/webpack-not-excluding-node-modules – Rakesh Kumar Cherukuri Dec 06 '17 at 06:47
  • this is a part of same config. the link shared, i have tried that option with no luck. We were able to reduce the file size by half by setting config.devtool = 'source-map'; – chint Dec 06 '17 at 08:50

0 Answers0