Open1

Webpackのバンドルコードリーディング

Urushihara TakeruUrushihara Takeru

ミニマイズされたやつを変数名変えたりコメントで見やすくしたやつをup。
動的importした時どうなってるのかを調べたつもりが結構ちゃんと読んだのでメモ。

// main.js
(() => {
  var globalObject,
    t,
    chunkRoot = {
      // エントリーポイントのチャンク
      465: function (i, exportsObject, callback) {
        var exportFn,
          // Objectの形式を整えるやつpart1
          o =
            (this && this.__createBinding) ||
            (Object.create
              ? function (e, t, r, n) {
                  void 0 === n && (n = r);
                  var o = Object.getOwnPropertyDescriptor(t, r);
                  (o &&
                    !("get" in o
                      ? !t.__esModule
                      : o.writable || o.configurable)) ||
                    (o = {
                      enumerable: !0,
                      get: function () {
                        return t[r];
                      },
                    }),
                    Object.defineProperty(e, n, o);
                }
              : function (e, t, r, n) {
                  void 0 === n && (n = r), (e[n] = t[r]);
                }),
          // Objectの形式を整えるやつpart2
          i =
            (this && this.__setModuleDefault) ||
            (Object.create
              ? function (e, t) {
                  Object.defineProperty(e, "default", {
                    enumerable: !0,
                    value: t,
                  });
                }
              : function (e, t) {
                  e.default = t;
                }),
          normalizeModule =
            (this && this.__importStar) ||
            function (_this) {
              if (_this && _this.__esModule) return _this;
              var t = {};
              if (null != _this)
                for (var r in _this)
                  "default" !== r &&
                    Object.prototype.hasOwnProperty.call(_this, r) &&
                    o(t, _this, r);
              return i(t, _this), t;
            };
        void 0 ===
          (exportFn = function (callback, t) {
            // main
            "use strict";
            console.log("this is template"),
              setTimeout(() => {
                !(async function () {
                  const module = await new Promise((e, t) => {
                    callback
                      .asyncLoad(814)
                      .then(
                        function () {
                          var t = [callback(814)];
                          e.apply(null, t);
                        }.bind(this)
                      )
                      .catch(t.bind(this));
                  }).then(normalizeModule);
                  console.log(module.hoge("ge"));
                  const module2 = await new Promise((e, t) => {
                    callback
                      .asyncLoad(195)
                      .then(
                        function () {
                          var t = [callback(195)];
                          e.apply(null, t);
                        }.bind(this)
                      )
                      .catch(t.bind(this));
                  }).then(normalizeModule);
                  console.log(module2.moge());
                  const module3 = await new Promise((e, t) => {
                    callback
                      .asyncLoad(814)
                      .then(
                        function () {
                          var t = [callback(814)];
                          e.apply(null, t);
                        }.bind(this)
                      )
                      .catch(t.bind(this));
                  }).then(normalizeModule);
                })();
              }, 1e3);
          }.apply(exportsObject, [callback, exportsObject])) ||
          (i.exports = exportFn);
      },
    },
    chunkObject = {};
  // チャンクの中身を実行するやつ
  function callback(chunkId) {
    var cachedChunk = chunkObject[chunkId];
    if (void 0 !== cachedChunk) return cachedChunk.exports;
    var i = (chunkObject[chunkId] = { exports: {} });
    return (
      chunkRoot[chunkId].call(i.exports, i, i.exports, callback), i.exports
    );
  }
  (callback.proxy = chunkRoot),
    (callback.loadRoot = {}),
    (callback.asyncLoad = (chunkId) =>
      Promise.all(
        Object.keys(callback.loadRoot).reduce(
          (prev, curr) => (callback.loadRoot[curr](chunkId, prev), prev),
          []
        )
      )),
    (callback.getBundleName = (e) => e + ".bundle.js"),
    (callback.getGlobalThis = (function () {
      if ("object" == typeof globalThis) return globalThis;
      try {
        return this || new Function("return this")();
      } catch (e) {
        if ("object" == typeof window) return window;
      }
    })()),
    (callback.hasProperty = (e, t) =>
      Object.prototype.hasOwnProperty.call(e, t)),
    (globalObject = {}),
    (t = "webpack-boilerplate:"),
    (callback.loadScript = (chankPath, n, i, a) => {
      if (globalObject[chankPath]) globalObject[chankPath].push(n);
      else {
        var scriptElement, l;
        if (void 0 !== i)
          for (
            var scriptElements = document.getElementsByTagName("script"), s = 0;
            s < scriptElements.length;
            s++
          ) {
            var p = scriptElements[s];
            if (
              p.getAttribute("src") == chankPath ||
              p.getAttribute("data-webpack") == t + i
            ) {
              scriptElement = p;
              break;
            }
          }
        scriptElement ||
          ((l = !0),
          ((scriptElement = document.createElement("script")).charset =
            "utf-8"),
          (scriptElement.timeout = 120),
          callback.nc && scriptElement.setAttribute("nonce", callback.nc),
          scriptElement.setAttribute("data-webpack", t + i),
          (scriptElement.src = chankPath)),
          (globalObject[chankPath] = [n]);
        var cleanUpScriptElement = (global, event) => {
            (scriptElement.onerror = scriptElement.onload = null),
              clearTimeout(f);
            var o = globalObject[chankPath];
            if (
              (delete globalObject[chankPath],
              scriptElement.parentNode &&
                scriptElement.parentNode.removeChild(scriptElement),
              o && o.forEach((e) => e(event)),
              global)
            )
              return global(event);
          },
          f = setTimeout(
            cleanUpScriptElement.bind(null, void 0, {
              type: "timeout",
              target: scriptElement,
            }),
            12e4
          );
        (scriptElement.onerror = cleanUpScriptElement.bind(
          null,
          scriptElement.onerror
        )),
          (scriptElement.onload = cleanUpScriptElement.bind(
            null,
            scriptElement.onload
          )),
          l && document.head.appendChild(scriptElement);
      }
    }),
    (() => {
      var e;
      callback.getGlobalThis.importScripts &&
        (e = callback.getGlobalThis.location + "");
      var t = callback.getGlobalThis.document;
      if (!e && t && (t.currentScript && (e = t.currentScript.src), !e)) {
        var r = t.getElementsByTagName("script");
        r.length && (e = r[r.length - 1].src);
      }
      if (!e)
        throw new Error(
          "Automatic publicPath is not supported in this browser"
        );
      (e = e
        .replace(/#.*$/, "")
        .replace(/\?.*$/, "")
        .replace(/\/[^\/]+$/, "/")),
        (callback.p = e);
    })(),
    (() => {
      var chunkIdsObject = { 179: 0 };
      callback.loadRoot.load = (bundleId, allChunkPromises) => {
        var prevChunkStatus = callback.hasProperty(chunkIdsObject, bundleId)
          ? chunkIdsObject[bundleId]
          : void 0;
        // chunkIdsObjectに存在したらスキップ
        if (0 !== prevChunkStatus)
          if (prevChunkStatus) allChunkPromises.push(prevChunkStatus[2]);
          else {
            var i = new Promise(
              (resolve, reject) =>
                (prevChunkStatus = chunkIdsObject[bundleId] = [resolve, reject])
            );
            allChunkPromises.push((prevChunkStatus[2] = i));
            var chunkPath = callback.p + callback.getBundleName(bundleId),
              c = new Error();
            callback.loadScript(
              chunkPath,
              (r) => {
                if (
                  callback.hasProperty(chunkIdsObject, bundleId) &&
                  (0 !== (prevChunkStatus = chunkIdsObject[bundleId]) &&
                    (chunkIdsObject[bundleId] = void 0),
                  prevChunkStatus)
                ) {
                  var i = r && ("load" === r.type ? "missing" : r.type),
                    a = r && r.target && r.target.src;
                  (c.message =
                    "Loading chunk " +
                    bundleId +
                    " failed.\n(" +
                    i +
                    ": " +
                    a +
                    ")"),
                    (c.name = "ChunkLoadError"),
                    (c.type = i),
                    (c.request = a),
                    prevChunkStatus[1](c);
                }
              },
              "chunk-" + bundleId,
              bundleId
            );
          }
      };
      var t = (pushFn, moduleInfo) => {
          var n,
            chunkId,
            [chunkIdList, module, l] = moduleInfo,
            u = 0;
          // 記録のないチャンクをチェック
          if (chunkIdList.some((t) => 0 !== chunkIdsObject[t])) {
            // チャンクの中身に他からアクセスできるようにオブジェクトにおいておく
            for (n in module)
              callback.hasProperty(module, n) &&
                (callback.proxy[n] = module[n]);
            l && l(callback);
          }
          for (pushFn && pushFn(moduleInfo); u < chunkIdList.length; u++)
            // チャンクの存在チェックと実行
            // 実行したらchunkの集約objectのそのチャンクに0をセットして完了とみなす
            (chunkId = chunkIdList[u]),
              callback.hasProperty(chunkIdsObject, chunkId) &&
                chunkIdsObject[chunkId] &&
                chunkIdsObject[chunkId][0](),
              (chunkIdsObject[chunkId] = 0);
        },
        chunkBuffer = (self.webpackChunkwebpack_boilerplate =
          self.webpackChunkwebpack_boilerplate || []);
      chunkBuffer.forEach(t.bind(null, 0)),
        (chunkBuffer.push = t.bind(null, chunkBuffer.push.bind(chunkBuffer)));
    })(),
    // こっから始まる
    callback(465);
})();

// ~~~~~~~~~~~~~~~~~~~~~
// 195.bundle.js
(self.webpackChunkwebpack_boilerplate =
  self.webpackChunkwebpack_boilerplate || []).push([
  // chunkIdList
  [195],
  // module
  {
    195: (e, o, callback) => {
      var t;
      (t = function (e, o) {
        "use strict";
        Object.defineProperty(o, "__esModule", { value: !0 }),
          (o.moge = void 0),
          (o.moge = function () {
            return "ko";
          });
      }.apply(o, [callback, o])),
        console.log(o);
      void 0 === t || (e.exports = t);
    },
  },
]);

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// src/index.ts
console.log("this is template");

async function hoge() {
  const a = await import("./hoge");
  console.log(a.hoge("ge"));
  const b = await import("./moge");
  console.log(b.moge());
}

setTimeout(() => {
  hoge();
}, 1000);