$30 off During Our Annual Pro Sale. View Details »

The Era of Module Bundlers - GDG Dev Fest Delhi 2017

The Era of Module Bundlers - GDG Dev Fest Delhi 2017

This talk will walk everyone through the concept and practical usage of JavaScript module bundling and optimisation. With the emergence of advanced bundling tools like Webpack, the JavaScript ecosystem has been enriched with the right set of processes and tools required for creating production-ready builds, which is what this talk aims at covering.
This talk will also cover essential differences between task runners and bundlers with focus on advanced optimisation techniques like Tree shaking and Code splitting.

Arun Michael Dsouza

October 29, 2017
Tweet

More Decks by Arun Michael Dsouza

Other Decks in Programming

Transcript

  1. THE ERA OF MODULE BUNDLERS
    Arun Michael Dsouza
    Software Engineer, AdPushup Inc.
    github.com/arunmichaeldsouza
    twitter.com/amdsouza92
    1

    View Slide

  2. Arun Michael Dsouza
    New Delhi, India
    2

    View Slide

  3. THE ERA OF MODULE BUNDLERS
    https://icons8.com/icon/45069/module
    3
    Image source :

    View Slide

  4. JAVASCRIPT MODULES
    4

    View Slide

  5. MAINTAINABILITY
    REUSABILITY
    EASE OF TESTING
    5
    JavaScript Modules

    View Slide

  6. MODULE SYSTEMS IN JAVASCRIPT
    6

    View Slide

  7. Immediately Invoked Function Expression
    7
    (function() {
    // Module code
    });
    Module Systems in JavaScript

    View Slide

  8. bit.ly/block-scoping-es6
    8
    (function() {
    // Module code
    });
    {
    // Module code
    }
    Module Systems in JavaScript

    View Slide

  9. Object Interface
    bit.ly/design-patterns-javascript
    9
    var math = (function() {
    return {
    sum: function() {
    // Method code
    },
    product: function() {
    // Method code
    }
    };
    })();
    Module Systems in JavaScript

    View Slide

  10. AMD
    COMMON JS
    10
    Module Systems in JavaScript

    View Slide

  11. AMD
    app.js
    11
    define(['math', 'data'], function(math, data) {
    return math.sum(2, 3);
    });
    Module Systems in JavaScript

    View Slide

  12. AMD
    math.js
    12
    define([], function() {
    return {
    sum: function() {
    // Method code
    },
    product: function() {
    // Method code
    }
    };
    });
    Module Systems in JavaScript

    View Slide

  13. COMMON JS
    math.js
    13
    var math = {
    sum: function() {
    // Method code
    },
    product: function() {
    // Method code
    }
    };
    module.exports = math;
    Module Systems in JavaScript

    View Slide

  14. COMMON JS
    app.js
    14
    var math = require('./math');
    var value = math.sum(2, 3);
    Module Systems in JavaScript

    View Slide

  15. MODULE LOADERS
    Module
    Loader
    AMD
    Common JS
    15
    https://github.com/alrra/browser-logos
    Image source :

    View Slide

  16. Common JS / AMD Module Loader
    REQUIRE JS
    AMD Module Loader
    bit.ly/require-js
    bit.ly/system-js
    SYSTEM JS
    16
    Module Loaders

    View Slide

  17. bit.ly/require-js-examples
    17



    Page 1





    Module Loaders

    View Slide

  18. 18
    Module Loaders

    View Slide

  19. 19
    Module Loaders

    View Slide

  20. MODULE BUNDLING
    Module
    Bundler
    Bundle
    Modules
    .css
    .js
    .js
    .png
    .scss
    20
    https://github.com/voodootikigod/logo.js/
    Image source :

    View Slide

  21. HOW DO MODULE BUNDLERS WORK ?
    index.js
    data.js
    math.js
    api.js model.js
    db.js
    sql.js
    unit.js
    constants.js
    jsm.js
    Dependency Graph
    21
    Module Bundling

    View Slide

  22. BROWSERIFY
    NPM modules on the browser side! Yay!
    22
    https://github.com/substack/browserify-website
    Image source :
    Intro to Browserify

    View Slide

  23. 23
    http://bit.ly/mind-blown-gif
    Image source :
    Intro to Browserify

    View Slide

  24. INSTALLATION
    > npm install -g browserify
    USAGE
    > browserify app.js -o bundle.js
    24
    Intro to Browserify

    View Slide

  25. TRANSFORMS
    Babelify
    ES6 ES5
    http://bit.ly/browserify-transforms
    25
    https://github.com/substack/browserify-website
    Image source :
    Intro to Browserify

    View Slide

  26. USING TRANSFORMS
    > browserify app.js -o bundle.js -t [ babelify --presets
    [ es2015 ] ]
    26
    Intro to Browserify

    View Slide

  27. TASK RUNNERS
    27

    View Slide

  28. 28
    grunt.initConfig({
    watchFiles: {
    // Watcher task
    },
    browserify: {
    // Module bundling task
    },
    minifyCss: {
    // CSS optimisation task
    },
    optimiseImages: {
    // Image optimisation task
    },
    uploadOnCDN: {
    // Deployment task
    }
    });
    Task Runners

    View Slide

  29. BABELIFY TRANSFORM
    > npm install grunt grunt-browserify babelify babel-
    preset-es2015 —save-dev
    29
    Task Runners

    View Slide

  30. WEBPACK
    30
    https://webpack.github.io/
    Image source :
    Intro to Webpack

    View Slide

  31. INSTALLATION
    > npm install -g webpack
    USAGE
    > webpack app.js bundle.js
    31
    Intro to Webpack

    View Slide

  32. WEBPACK CONFIG FILE
    32
    module.exports = {
    entry: './app.js',
    output: {
    filename: './bundle.js'
    }
    };
    Intro to Webpack

    View Slide

  33. 33
    https://npm-stat.com/
    Image source :
    Intro to Webpack

    View Slide

  34. LOADERS
    Transform code from one form to another that
    is part of the bundle
    PLUGINS
    Act on the bundle or bundle chunks for
    customisation and optimisation
    34
    Intro to Webpack

    View Slide

  35. BUNDLE OPTIMISATION WITH WEBPACK
    35

    View Slide

  36. BUNDLE ANALYSIS
    36
    Bundle Optimisation with Webpack

    View Slide

  37. WEBPACK BUNDLE ANALYZERS
    http://bit.ly/webpack-bundle-analyzer
    http://bit.ly/webpack-chart
    http://bit.ly/webpack-visualizer
    NPM Module
    Web-based Analysers
    37
    Bundle Optimisation with Webpack

    View Slide

  38. WEBPACK BUNDLE ANALYZER
    plugins: [
    new BundleAnalyzerPlugin( )
    ]
    38
    plugins: [
    new BundleAnalyzerPlugin()
    ]
    Bundle Optimisation with Webpack

    View Slide

  39. plugins: [
    new BundleAnalyzerPlugin( )
    ]
    39
    Bundle Optimisation with Webpack

    View Slide

  40. WEB-BASED BUNDLE ANALYZERS
    > webpack --profile --json > stats.json
    40
    Bundle Optimisation with Webpack

    View Slide

  41. PRODUCTION READY BUNDLE
    41
    Bundle Optimisation with Webpack

    View Slide

  42. 42
    Bundle Optimisation with Webpack

    View Slide

  43. UGLIFICATION
    43
    plugins: [
    new webpack.optimize.UglifyJsPlugin()
    ]
    Bundle Optimisation with Webpack

    View Slide

  44. 44
    Bundle Optimisation with Webpack

    View Slide

  45. NODE ENVIRONMENT VARIABLE
    45
    plugins: [
    new webpack.DefinePlugin({
    'process.env.NODE_ENV':
    JSON.stringify('production')
    })
    ]
    Bundle Optimisation with Webpack

    View Slide

  46. 46
    Bundle Optimisation with Webpack

    View Slide

  47. WEBPACK PRODUCTION FLAG
    > webpack -p
    47
    Bundle Optimisation with Webpack

    View Slide

  48. CSS MINIFICATION
    48
    > npm install css-loader —save-dev
    Bundle Optimisation with Webpack

    View Slide

  49. 49
    Bundle Optimisation with Webpack

    View Slide

  50. CSS MINIFICATION
    50
    ...
    module: {
    loaders: [
    {
    test: /\.css?$/,
    loader: 'css-loader',
    options: {
    minimize: true
    }
    }
    ]
    },
    ...
    Bundle Optimisation with Webpack

    View Slide

  51. 51
    Bundle Optimisation with Webpack

    View Slide

  52. CSS EXTRACTION/ CSS CODE SPLITTING
    52
    > npm install —save-dev extract-text-webpack-plugin
    Bundle Optimisation with Webpack

    View Slide

  53. 53
    ...
    module: {
    loaders: [
    {
    test: /\.css?$/,
    use: ExtractTextPlugin.extract({
    use: [{
    loader: 'css-loader',
    options: {
    minimize: true
    }
    }]
    })
    }
    ]
    },
    plugins: [
    new ExtractTextPlugin('./build/styles.min.css'),
    ]
    CSS EXTRACTION/ CSS CODE SPLITTING
    Bundle Optimisation with Webpack

    View Slide

  54. 54
    Bundle Optimisation with Webpack

    View Slide

  55. BUILD-TIME GZIPPING
    55
    Bundle Optimisation with Webpack

    View Slide

  56. DYNAMIC GZIPPING
    56
    var compression = require('compression');
    app.use(compression());
    Bundle Optimisation with Webpack

    View Slide

  57. BUILD-TIME GZIPPING
    > npm install compression-webpack-plugin --save-dev
    http://bit.ly/webpack-compression-plugin
    57
    Bundle Optimisation with Webpack

    View Slide

  58. 58
    app.get('*.js', function(req, res, next) {
    req.url = req.url + '.gz';
    res.set('Content-Encoding', 'gzip');
    next();
    });
    Bundle Optimisation with Webpack

    View Slide

  59. TREE SHAKING
    Dead Code Elimination
    Works with ES2015 Modules
    59
    Bundle Optimisation with Webpack

    View Slide

  60. math.js
    60
    const sum = (a, b) => a + b;
    const product = (a, b) => a * b;
    export { sum, product };
    Bundle Optimisation with Webpack

    View Slide

  61. app.js
    61
    import { sum } from './math';
    const value = sum(2,3);
    console.log(value);
    Bundle Optimisation with Webpack

    View Slide

  62. babel-loader
    babel-plugin-transform-es2015-modules-commonjs
    62
    Bundle Optimisation with Webpack

    View Slide

  63. ES2015 MODULES (STATIC STRUCTURE)
    Can be tree-shaken
    COMMON JS & OTHERS (DYNAMIC STRUCTURE)
    Cannot be tree-shaken
    63
    Bundle Optimisation with Webpack

    View Slide

  64. 64
    "use strict";
    Object.defineProperty(exports, "__esModule", {
    value: true
    });
    var sum = function sum(a, b) {
    return a + b;
    };
    var product = function product(a, b) {
    return a * b;
    };
    exports.sum = sum;
    exports.product = product;
    Bundle Optimisation with Webpack

    View Slide

  65. HOW TREE SHAKING WORKS
    Babel-loader
    ES6
    65
    Bundle Optimisation with Webpack
    Minifier
    With { modules: false }
    option
    ES5
    Tree-shaken
    code
    ES5
    Code with
    unused exports

    View Slide

  66. 66

    module: {
    loaders: [
    {
    test: /\.jsx?$/,
    loader: 'babel-loader',
    query: {
    presets: [['es2015', { modules: false }]]
    }
    }
    ]
    },

    Bundle Optimisation with Webpack

    View Slide

  67. 67
    "use strict";
    /* harmony export (binding) */
    __webpack_require__.d(__webpack_exports__, "a", function() {
    return sum; });
    /* unused harmony export product */
    var sum = function sum(a, b) {
    return a + b;
    };
    var product = function product(a, b) {
    return a * b;
    };
    Bundle Optimisation with Webpack

    View Slide

  68. 68
    "use strict";
    n.d(t, "a", function() {
    return r
    });
    // Only sum method exported
    var r = function(e, t) {
    return e + t
    }
    Bundle Optimisation with Webpack

    View Slide

  69. CODE SPLITTING
    bundle.js
    styles.css page1.js page2.js
    69
    Bundle Optimisation with Webpack

    View Slide

  70. CSS CODE SPLITTING
    App code with styles
    Separate CSS bundle
    css-loader
    Bundle with processed CSS
    ExtractTextWebpackPlugin
    70
    Bundle Optimisation with Webpack

    View Slide

  71. CODE SPLITTING LIBRARIES
    bundle.js
    JQuery
    Lodash
    App Code
    vendor.js
    JQuery Lodash
    bundle.js
    App Code
    71
    Bundle Optimisation with Webpack

    View Slide

  72. index.js product.js
    72
    import $ from 'jquery';
    // index.js code
    import $ from 'jquery';
    // product.js code
    Bundle Optimisation with Webpack

    View Slide

  73. plugins: [
    new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: 2
    })
    ]
    COMMON CHUNKS PLUGIN
    http://bit.ly/common-chunks-plugin
    73
    Bundle Optimisation with Webpack

    View Slide

  74. 74
    Bundle Optimisation with Webpack

    View Slide

  75. IMPLICIT COMMON VENDOR CHUNK
    75
    plugins: [
    new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
    minChunks: function (module) {
    return module.context &&
    module.context.indexOf('node_modules') !== -1;
    }
    })
    ]
    Bundle Optimisation with Webpack

    View Slide

  76. AUTOMATIC SPLITTING
    76
    import header from 'header';
    import slider from 'slider';
    require.ensure(['./productList'], function(require) {
    require('./productList');
    });
    Bundle Optimisation with Webpack

    View Slide

  77. 77
    Bundle Optimisation with Webpack

    View Slide

  78. 78
    path="/product"
    getComponent={(location, callback) => {
    require.ensure([], require => {
    callback(null, require('./productPage'))
    })
    }}/>
    Bundle Optimisation with Webpack

    View Slide

  79. ES6 MODULES
    79
    ES6 Modules
    const sum = (a, b) => a + b;
    export default sum;
    import sum from './sum';
    bit.ly/state-of-js-modules

    View Slide

  80. THE ERA OF MODULE BUNDLERS
    80
    THANK YOU
    Arun Michael Dsouza
    Software Engineer, AdPushup Inc.
    github.com/arunmichaeldsouza
    twitter.com/amdsouza92

    View Slide