I have created the sample Angular 2 project with Webpack based on Angular documentation. Webpack is more convenient module bundler. Webpack roams over your application source code, looking for import statements, building a dependency graph, and emitting one (or more) bundles. With plugin "loaders" Webpack can preprocess and minify different non-JavaScript files such as TypeScript, SASS, and LESS files.

Setup the project

git clone https://github.com/SodhanaLibrary/angular2-webpack-prod-dev-setup.git
npm install
Now your project is ready. Start the project
npm start
Open http://localhost:8080 in your browser. You can see welcome screen.  Now create production version
npm run build
Above command creates dist folder consists of HTML file and bundle js file

Webpack setup

Now we will discuss the webpack setup. Observe below project structure
config - config folder consists of all configuration files. 
webpack.config.js - When user runs webpack command, webpack will look for webpack.config.js by default
webpack.common.js - This is common webpack configuration for development, testing and production
src - folder for all source files
main.ts - this is the entry point of the application which bootstraps whole application. index.html will load this file first
polyfills.ts - this file consists imports of ES6 and ES7 polyfills. This file is the entry point to generate final polyfills.js
vendor.ts - this file consists imports of RXJS and Angular libraries. This file is the entry point to generate vendor.js

webpack.common.js

Observe entry property. Here 3 entry points are there. Webpack will bundle these and create polyfills.js, vendor.js, app.js 
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var helpers = require('./helpers');

module.exports = {
  entry: {
    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'app': './src/main.ts'
  },

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

  module: {
    loaders: [
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader', 'angular2-template-loader']
      },
      {
        test: /\.html$/,
        loader: 'html'
      },
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
        loader: 'file?name=assets/[name].[hash].[ext]'
      },
      {
        test: /\.css$/,
        exclude: helpers.root('src', 'app'),
        loader: ExtractTextPlugin.extract('style', 'css?sourceMap')
      },
      {
        test: /\.css$/,
        include: helpers.root('src', 'app'),
        loader: 'raw'
      }
    ]
  },

  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ['app', 'vendor', 'polyfills']
    }),

    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ]
};
HtmlWebpackPlugin reads index.html and adds generated polyfills.js, verdor.js, app.js to it.

Webpack.dev.js

var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

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

  output: {
    path: helpers.root('dist'),
    publicPath: 'http://localhost:8080/',
    filename: '[name].js',
    chunkFilename: '[id].chunk.js'
  },

  plugins: [
    new ExtractTextPlugin('[name].css')
  ],

  devServer: {
    historyApiFallback: true,
    stats: 'minimal'
  }
});
This webpack dev configuration merges with webpack.common.js configuration. Observe output property here, which gives dist as path folder.  The Webpack dev server makes dist as the main folder to serve content

package.json scripts

Observe below start property which executes webpack-dev-server on port 8080
"scripts": {
    "start": "webpack-dev-server --inline --progress --port 8080",
    "test": "karma start",
    "build": "rimraf dist && webpack --config config/webpack.prod.js --progress --profile --bail"
}
Here build command runs webpack with config/webpack.prod.js, this generates production ready files

webpack.prod.js

This file uses UglifyJsPlugin for uglifying the output production ready js files.  webpack.DefinePlugin will define the environment as 'production'. 
var webpack = require('webpack');
var webpackMerge = require('webpack-merge');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var commonConfig = require('./webpack.common.js');
var helpers = require('./helpers');

const ENV = process.env.NODE_ENV = process.env.ENV = 'production';

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

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

  htmlLoader: {
    minimize: false // workaround for ng2
  },

  plugins: [
    new webpack.NoErrorsPlugin(),
    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.UglifyJsPlugin({ // https://github.com/angular/angular/issues/10618
      mangle: {
        keep_fnames: true
      }
    }),
    new ExtractTextPlugin('[name].css'),
    new webpack.DefinePlugin({
      'process.env': {
        'ENV': JSON.stringify(ENV)
      }
    })
  ]
});

0 comments:

Blogroll

Follow this blog by Email

Popular Posts