为什么要使用Webpack?

3

我花了几天的时间来配置Webpack,现在终于让它跑起来并测试成功。然而,我发现Webpack生成的bundle.js文件包含了许多我无法理解为何需要的不必要代码。

index.js

import greet from './greet';

console.log("I'm the entry point");
greet();

greet.js

function greet() {
    console.log('Have a great day!');
};

export default greet;

如此简单。但是bundle.js。
!(function(e) {
  var t = {};
  function n(r) {
    if (t[r]) return t[r].exports;
    var o = (t[r] = { i: r, l: !1, exports: {} });
    return e[r].call(o.exports, o, o.exports, n), (o.l = !0), o.exports;
  }
  (n.m = e),
    (n.c = t),
    (n.d = function(e, t, r) {
      n.o(e, t) || Object.defineProperty(e, t, { enumerable: !0, get: r });
    }),
    (n.r = function(e) {
      "undefined" != typeof Symbol &&
        Symbol.toStringTag &&
        Object.defineProperty(e, Symbol.toStringTag, { value: "Module" }),
        Object.defineProperty(e, "__esModule", { value: !0 });
    }),
    (n.t = function(e, t) {
      if ((1 & t && (e = n(e)), 8 & t)) return e;
      if (4 & t && "object" == typeof e && e && e.__esModule) return e;
      var r = Object.create(null);
      if (
        (n.r(r),
        Object.defineProperty(r, "default", { enumerable: !0, value: e }),
        2 & t && "string" != typeof e)
      )
        for (var o in e)
          n.d(
            r,
            o,
            function(t) {
              return e[t];
            }.bind(null, o)
          );
      return r;
    }),
    (n.n = function(e) {
      var t =
        e && e.__esModule
          ? function() {
              return e.default;
            }
          : function() {
              return e;
            };
      return n.d(t, "a", t), t;
    }),
    (n.o = function(e, t) {
      return Object.prototype.hasOwnProperty.call(e, t);
    }),
    (n.p = ""),
    n((n.s = 0));
})([
  function(e, t, n) {
    "use strict";
    n.r(t);
    var r = function() {
      console.log("Have a great day!");
    };
    console.log("I'm the entry point"), r();
  }
]);

似乎 WebPack 生成了很多无用的代码,对我来说毫无意义。bundle.js 文件大小也比 index.js 和 greet.js 大 3 倍。简单的开发构建看起来也很混乱、杂乱无章。
那么,为什么我还要继续投入时间使用 WebPack?它输出的所有额外代码是什么原因?有什么更好的替代方案可以帮助我从模块化开发环境中发布代码吗?
我真的很感谢您帮助我理解是否应该使用 WebPack。
谢谢!

尝试编写一个大型的React应用程序,不使用任何打包工具,看看你能做到什么程度 :) - Dominic
3个回答

5

bundle.js 的文件大小比 index.js 和 greet.js 大三倍

Webpack 必须为浏览器无法处理的事物(例如模块加载)添加一些 polyfills。如果你只有两行代码,这些 polyfills 会显得非常笨重,但是如果你编写了数千行代码,你将不会注意到任何重大的开销,因为这些 polyfills 只添加一次。

那么,我为什么要继续投入时间来使用 Webpack 进行我的项目?

因为它可以为大型项目生成更小的捆绑包,还允许你编写 ESnext 和干净、模块化的代码。

它输出的所有额外代码是什么,为什么要存在?

它保持全局范围的清洁,添加一些 helpers 和一个模块加载器,然后加载第一个模块:

// IIFE to keep global scope clean, ! to prevent Automatic Semicolon Insertion fun
!(function init(modules) {
  var cache = {}; // cache the modules results
  // All modules are in an array, their index is a unique identifier
  function require/*n*/(index/*r*/) {
    if (cache[index]) return cache[index].exports;
    var context/*o*/= (cache[index = { index/*i*/: index, loaded/*l*/: false/*!1*/, exports: {} });

    modules[index].call(
      context.exports, 
      context,
      context.exports, 
      require
    );
    context.loaded = true /*!0*/;
    return context.exports;
  }

  require.modules = modules; // I'm not sure why?...
  require.cache = cache;

  // helper for adding a getter
  require.addGetter /*n.d*/ = function(object, key, getter) {
    require.has(object, key) || Object.defineProperty(object, key, { enumerable: true, get: getter });
  });

  require.prepareExport /*n.r*/ = function(export) {
    if("undefined" != typeof Symbol && Symbol.toStringTag)
      Object.defineProperty(export, Symbol.toStringTag, { value: "Module" });

    Object.defineProperty(export, "__esModule", { value: true });
  };

 // I have no idea what that is doing

  require.startModule /*n.s*/ = 0;
  require(require.startModule); // start execution
})([
  /* Your modules, identified by index */
  function mainModule(context, exports, require) {
      "use strict"; // better performance
      require.prepareExport(export); // as you could override exports in your module, this has to be called afterwards

     var otherModule = function() { // inlined!
        console.log("Have a great day!");
     };

    console.log("I'm the entry point"), 

    otherModule();
  } /* ... more modules would follow here if not inlined */
]);

是否有更好的选择来帮助我从模块化开发环境中发布我的代码?

有其他选择,但不确定它们是否“更好”。


4
我同意Webpack添加了大量你可能不需要的垃圾。它还有一个近乎疯狂的配置文件。
为了简单起见,你可以只使用脚本标签加载模块文件,并将Webpack抛到一边!(仅在现代浏览器(Edge16+,FF60+,Chrome61+,Safari11+)中适用)。
<script type="module" src="greet.js">
<script type="module" src="app.js">

你也可以使用更简单的Webpack替代方案,如ParcelJS或Rollup。这些编译器都可以做很多事情,具体取决于您的需求:
- 将您的模块捆绑成一个大的bundle.js文件 - 使代码兼容旧的遗留浏览器。 - 将scss转译为css,typescript转译为javascript等。 - 启动带有自动重新加载功能的开发服务器 - 构建整个网站文件夹,仅包括项目中实际使用的文件。

1
“或者更现实的是,你可以使用一个打包工具来生成既适用于现代浏览器又兼容老旧浏览器的捆绑包。不必再用Webpack了,只需使用脚本标签加载模块文件即可。” - str
2
“现实”取决于上下文。如今,并不是每个项目都必须在IE8上运行。但是,我不会说你不需要一个打包工具。只是当你学习JavaScript基础和模块时,你并不需要它。 - Kokodoko

0

我曾与捆绑器进行过艰苦的战斗。但还有其他方法。通过几年的经验和试错,我提出的最佳替代方案是我的项目Zwitterion:https://github.com/lastmjs/zwitterion

它被设计成静态文件服务器的替换品。 它支持ES2015+、TypeScript、AssemblyScript、Rust、C、C++,很快可能也会支持JSX、TSX和Vue。 您不必改变您的文件结构或直观开发的方式。 只需编写源代码,使用脚本元素或模块导入包含它,然后就可以工作了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接