Examples of webpack2: Scope Hoisting and Code Splitting

Keywords: Javascript Webpack github ECMAScript

Links to the original text: https://github.com/webpack/we...
Translator: @justjavac

This example demonstrates Scope Hosting combined with code splitting.

This is the dependency graph for the example: (solid lines for synchronous imports, dashed lines for asynchronous imports)

All modules except cjs are EcmaScript modules. cjs is a CommonJs module.

Interestingly, placing all modules in a single scope will not work properly for the following reasons:

  • Modules lazy, c, d and cjs require a single chunk
  • Module shared can be accessed by two chunk s (in different ranges)
  • Module cjs is a CommonJs module

Therefore, webpack uses a method called Partial Scope Hosting or Module Cascading, which selects the largest subset of ES modules that can cover the Scope Hosting range and combines it with the default web pack primitives.

To avoid conflicts, module connection identifiers in modules are renamed and internal imports are simplified. The external import and export of the root module uses the existing ESM structure.

example.js

import { a, x, y } from "a";
import * as b from "b";

import("./lazy").then(function(lazy) {
    console.log(a, b.a(), x, y, lazy.c, lazy.d.a, lazy.x, lazy.y);
});

lazy.js

export * from "c";
import * as d from "d";
export { d };

a.js

// module a
export var a = "a";
export * from "shared";

b.js

// module b
export function a() {
    return "b";
};

c.js

// module c
import { c as e } from "cjs";

export var c = String.fromCharCode(e.charCodeAt(0) - 2);

export { x, y } from "shared";

d.js

// module d
export var a = "d";

cjs.js

// module cjs (commonjs)
exports.c = "e";

shared.js

// shared module
export var x = "x";
export * from "shared2";

shared2.js

// shared2 module
export var y = "y";

webpack.config.js

var webpack = require("../../");

module.exports = {
    plugins: [
        new webpack.optimize.ModuleConcatenationPlugin()
    ]
};

js/output.js

/******/ (function(modules) { /* webpackBootstrap */ })
......
/******/ ([
/* 0 */
/*!********************************************!*\
  !*** ./node_modules/shared.js + 1 modules ***!
  \********************************************/
/*! exports provided: x, y */
/*! exports used: x, y */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

// CONCATENATED MODULE: ./node_modules/shared2.js
// shared2 module
var y = "y";

// CONCATENATED MODULE: ./node_modules/shared.js
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return x; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "b", function() { return y; });
// shared module
var x = "x";



/***/ }),
/* 1 */
/*!********************************!*\
  !*** ./example.js + 2 modules ***!
  \********************************/
/*! exports provided:  */
/*! all exports used */
/*! ModuleConcatenation bailout: Module is an entry point */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });

// EXTERNAL MODULE: ./node_modules/shared.js + 1 modules
var shared = __webpack_require__(0);

// CONCATENATED MODULE: ./node_modules/a.js
// module a
var a = "a";


// CONCATENATED MODULE: ./node_modules/b.js
// module b
function b_a() {
    return "b";
};

// CONCATENATED MODULE: ./example.js



__webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, /*! ./lazy */ 3)).then(function(lazy) {
    console.log(a, b_a(), shared["a" /* x */], shared["b" /* y */], lazy.c, lazy.d.a, lazy.x, lazy.y);
});


/***/ })
/******/ ]);

js/0.output.js

webpackJsonp([0],[
/* 0 */,
/* 1 */,
/* 2 */
/*!*****************************!*\
  !*** ./node_modules/cjs.js ***!
  \*****************************/
/*! no static exports found */
/*! exports used: c */
/*! ModuleConcatenation bailout: Module is not an ECMAScript module */
/***/ (function(module, exports) {

// module cjs (commonjs)
exports.c = "e";


/***/ }),
/* 3 */
/*!*****************************!*\
  !*** ./lazy.js + 2 modules ***!
  \*****************************/
/*! exports provided: d, c, x, y */
/*! all exports used */
/*! ModuleConcatenation bailout: Module is referenced from these modules with unsupported syntax: ./example.js (referenced with import()) */
/***/ (function(module, __webpack_exports__, __webpack_require__) {

"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
var d_namespaceObject = {};
__webpack_require__.d(d_namespaceObject, "a", function() { return a; });

// EXTERNAL MODULE: ./node_modules/cjs.js
var cjs = __webpack_require__(2);
var cjs_default = /*#__PURE__*/__webpack_require__.n(cjs);

// EXTERNAL MODULE: ./node_modules/shared.js + 1 modules
var shared = __webpack_require__(0);

// CONCATENATED MODULE: ./node_modules/c.js
// module c


var c = String.fromCharCode(cjs["c"].charCodeAt(0) - 2);



// CONCATENATED MODULE: ./node_modules/d.js
// module d
var a = "d";

// CONCATENATED MODULE: ./lazy.js
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "c", function() { return c; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "x", function() { return shared["a" /* x */]; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "y", function() { return shared["b" /* y */]; });
/* concated harmony reexport */__webpack_require__.d(__webpack_exports__, "d", function() { return d_namespaceObject; });





/***/ })
]);

Minimized

webpackJsonp([0],[,,function(n,r){r.c="e"},function(n,r,t){"use strict";Object.defineProperty(r,"__esModule",{value:!0});var e={};t.d(e,"a",function(){return d});var u=t(2),c=t(0),o=String.fromCharCode(u.c.charCodeAt(0)-2),d="d";t.d(r,"c",function(){return o}),t.d(r,"x",function(){return c.a}),t.d(r,"y",function(){return c.b}),t.d(r,"d",function(){return e})}]);

Info

Uncompressed

Hash: 6596ce0a50ccbbaa89c6
Version: webpack 3.5.1
      Asset     Size  Chunks             Chunk Names
0.output.js   1.9 kB       0  [emitted]  
  output.js  7.39 kB       1  [emitted]  main
Entrypoint main = output.js
chunk    {0} 0.output.js 286 bytes {1} [rendered]
    > [] 4:0-16
    [3] ./lazy.js + 2 modules 242 bytes {0} [built]
        [exports: d, c, x, y]
        import() ./lazy [] ./example.js 4:0-16
     + 1 hidden module
chunk    {1} output.js (main) 390 bytes [entry] [rendered]
    > main [] 
    [0] ./node_modules/shared.js + 1 modules 105 bytes {1} [built]
        [exports: x, y]
        [only some exports used: x, y]
        harmony import shared [1] ./example.js + 2 modules 3:0-23
        harmony import shared [3] ./lazy.js + 2 modules 6:0-30
    [1] ./example.js + 2 modules 285 bytes {1} [built]
        [no exports]

Minimized (uglify-js, no zip)

Hash: 6596ce0a50ccbbaa89c6
Version: webpack 3.5.1
      Asset       Size  Chunks             Chunk Names
0.output.js  364 bytes       0  [emitted]  
  output.js    1.66 kB       1  [emitted]  main
Entrypoint main = output.js
chunk    {0} 0.output.js 286 bytes {1} [rendered]
    > [] 4:0-16
    [3] ./lazy.js + 2 modules 242 bytes {0} [built]
        [exports: d, c, x, y]
        import() ./lazy [] ./example.js 4:0-16
     + 1 hidden module
chunk    {1} output.js (main) 390 bytes [entry] [rendered]
    > main [] 
    [0] ./node_modules/shared.js + 1 modules 105 bytes {1} [built]
        [exports: x, y]
        [only some exports used: x, y]
        harmony import shared [1] ./example.js + 2 modules 3:0-23
        harmony import shared [3] ./lazy.js + 2 modules 6:0-30
    [1] ./example.js + 2 modules 285 bytes {1} [built]
        [no exports]

Welcome to pay attention to my public number and front-end articles:

Posted by Nick Zaccardi on Tue, 12 Feb 2019 19:51:19 -0800