Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I setup webpack to NOT recompile angular every single time?

Recently I started working on simple HTML5 canvas game + angular2 for routing, displaying highscores etc. Since I am not touching angular2 core, I would like to NOT recompile everything and bundle all together into one big file. Much more I would prefer to have angular2 core + http + router, and my app in separate files.

Right now I am getting almost 5MB bundle and even larger .map which suspend my pc for a short duration while loading in browser(mouse getting stuck, music stop playing for a moment, like half a sec) which is very annoying(I guess, it is because of bundle size). Could I use multiple entry points to get this work?

Here is my webpack config:

module.exports = {
  devtool: 'source-map',
  entry: './src/app/bootstrap',
  output: {
    path: __dirname + '/dist', publicPath: 'dist/', filename: 'bundle.js'
  },
  resolve: {
    extensions: ['', '.js', '.ts']
  },
  module: {
    loaders: [
      {
        test: /\.ts/, loaders: ['ts-loader'], exclude: /node_modules/
      }
    ]
  }
};

I am using angular 2.0.0-beta.0 and webpack 1.12.2

like image 560
Eggy Avatar asked Jan 01 '16 13:01

Eggy


People also ask

Does webpack automatically minify?

Webpack v4+ will minify your code by default in production mode .

Does Angular use webpack by default?

Usually, webpack is hidden behind the Angular command-line tool. But in some cases, it may be necessary to tweak the configuration of webpack when building an Angular application. In earlier versions of Angular, it was possible to eject the webpack configuration and modify it directly.


1 Answers

Update: consider the cache option.

The answer to your question is: Yes. You can use multiple entry points.

Here is an example that I'm using.

var path = require('path');

var webpack = require('webpack');
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var ProvidePlugin = webpack.ProvidePlugin;
//var UglifyJsPlugin = webpack.optimize.UglifyJsPlugin;

module.exports = {
    devtool: 'source-map',
    debug: true, // set false in production
    cache: true,

    entry: {
        'vendor': './src/vendor.ts', // third party dependencies
        'app': './src/app/app.ts' // our app
    },

    output: {
        path: root('dist'),
        filename: '[name].js',
        sourceMapFilename: '[name].map',
        chunkFilename: '[id].chunk.js',
        pathinfo: true
    },

    resolve: {
        extensions: ['', '.ts', '.js', '.json', '.css', '.html']
    },

    module: {
        loaders: [
            {
                test: /\.ts$/,
                loader: 'ts-loader',
                query: {
                    'ignoreDiagnostics': [
                        2403, // 2403 -> Subsequent variable declarations
                        2300, // 2300 -> Duplicate identifier
                        2374, // 2374 -> Duplicate number index signature
                        2375  // 2375 -> Duplicate string index signature
                    ]
                },
                exclude: [/\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]
            },

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

            // support for .css
            {test: /\.css$/, loaders: ['style', 'css']},
        ],
        noParse: [/angular2-polyfills/]
    },

    plugins: [
        new CommonsChunkPlugin({name: 'vendor', filename: 'vendor.js', minChunks: Infinity}),
        new CommonsChunkPlugin({name: 'common', filename: 'common.js', minChunks: 2, chunks: ['app', 'vendor']}),
        new ProvidePlugin({
            $: "jquery",
            jQuery: "jquery",
            Cookies: "js-cookie"
        })
//        new UglifyJsPlugin() // use for production
    ],

    // Other module loader config
    tslint: {
        emitErrors: true,
        failOnHint: false
    },
    // our Webpack Development Server config
    devServer: {
        contentBase: 'src',
        publicPath: '/__build__',
        colors: true,
        progress: true,
        port: 3000,
        displayCached: true,
        displayErrorDetails: true,
        inline: true
    }
};

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}

function rootNode(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return root.apply(path, ['node_modules'].concat(args));
}

This config is a little more complex than yours. It comes from this Angular 2 / Bootstrap 4 / OAuth2 Github project that uses Webpack.

That will put the Angular stuff (and RxJS and anything else) in a 'vendor' bundle, but you have to make a vendor.ts file that calls in the stuff you need.

vendor.ts:

require('./css/bootstrap.css');
require('./css/main.css');

import 'angular2/bundles/angular2-polyfills';

import 'angular2/platform/browser';
import 'angular2/core';
import 'angular2/http';
import 'angular2/router';

Then add the following code to the bottom of your index.html file.

<script src="dist/common.js"></script>
<script src="dist/vendor.js"></script>
<script src="dist/app.js"></script>

You might have to adjust some of the paths to connect up properly, depending on where your index.html file sits in relation to the other folders.

But that, I think, will do it for you. Check the Github project to see it al in action.

like image 177
Michael Oryl Avatar answered Nov 15 '22 05:11

Michael Oryl