【问题标题】:how code splitting works with import/export and babel and webpack?代码拆分如何与导入/导出以及 babel 和 webpack 一起使用?
【发布时间】:2019-02-19 22:29:51
【问题描述】:

我正在尝试回答,

何时使用 import/export 以及何时使用 require()/module.exports?但是当我尝试挖掘时,它似乎变得复杂了。

这是我的理解

  • require()/module.exports: 这是模块系统的 nodejs 实现。这会同步加载模块。
  • 使用 es6,我们可以使用导入/导出。 the docs

import 语句用于导入由另一个模块导出的绑定。无论您是否声明它们,导入的模块都处于严格模式。 import 语句不能在嵌入脚本中使用,除非此类脚本具有 type="module"。

问题1:这如何与 babel 或 webpack 或一般浏览器一起工作?

在探索过程中,我遇到了诸如 CommonJs、requireJs、异步模块定义 (AMD) 之类的东西

问题 2:我更感兴趣的是了解 时间线 以及这些东西在 javascript 中是如何演变的?

【问题讨论】:

  • "何时使用 require()/module.exports?" - 从不。或者:仅在旧版应用程序中。
  • 嘿@Bergi 解释?请。
  • 嗯 ES6 模块在几乎所有方面都好得多,除了原生支持。

标签: javascript node.js webpack ecmascript-6 babeljs


【解决方案1】:

这如何与 babel 或 webpack 或一般浏览器一起使用?

Babel 和 Webpack 遵循 ES 规范并将 import / export 语句转换为一个文件。由于它们还支持require 语法,它们通常将import 语句转换为require() 调用并将export 语句转换为module exports,然后为模块提供自定义加载器。例如:

 // A.js
 export default function() { }

 // B.js
 import A from "./A";
 A();

然后它被转译为以下require 语法:

 //A.js
 exports.default = function() {};

 //B.js
 var A = require("./A").default;
 A();

然后可以将其包装成如下内容:

 (function() { // prevent leaking to global scope
   // emulated loader:
   var modules = {};

   function require(name) { return modules[name]; }

   function define(name, fn) {
     var module = modules[name] = { exports: {} };
     fn(module, module.exports, require);
   }


  // The code:
  define("A", function(module, exports, require) {
      // A.js
     exports.default = function() { };
  });

  define("B", function(module, exports, require) { 
    // B.js
   var A = require("A").default;
    A();
  });
 })();

这些东西在 javascript 中是如何演变的?

几年前,编写JS仅限于浏览器,加载多个js源的唯一方法是使用多个<script>标签并使用全局对象来交换功能。那是丑陋的。

然后 Nodejs 被发明了,他们需要一种更好的方式来处理模块并发明了 require() 东西。

规范的编写者看到了对本机语法的需求,因此引入了import / export

Babel 和其他人随后编写了转译器。

【讨论】:

    【解决方案2】:

    打包器所做的 webpack 如下:

    1. 您在配置中指定输入文件
    2. 您在配置中指定一个输出文件

    Webpack 将查看输入文件requires(commomJS 模块系统)或imports(ES6 模块系统)的所有文件。然后,它通过加载程序根据文件名扩展汇集代码。 Loaders 可以将单个文件转换为浏览器可以理解的代码。加载器的一个例子是 babel 或 sass/scss 编译器。

    不同的文件被加载器转译后,插件可以在 将生成的代码转换成其他东西。捆绑包只是一堆代码,它们共同构成了一个功能

    在webpack的内部我不会太深入的讲,但是最重要的是要明白:

    您使用 webpack,因此您可以将代码拆分到多个文件中,这使它们更易于维护和使用。但是,客户端请求所有这些文件对性能来说会很糟糕(许多 HTTP 请求开销)。因此,我们将文件捆绑到一个文件或几个文件中,以减少这种开销。

    【讨论】:

      【解决方案3】:

      一般来说,如果你使用像 webpack 这样的打包工具,或者使用 Babel 进行翻译,你应该使用 import/export 语法编写所有现代代码...... npm 模块可能更喜欢 require/module 语法,但你仍然可以导入它们。

      同样值得注意的是import() 方法,它返回一个应该解析为异步导入的根模块的promise。 Webpack 可以将它们捆绑为异步模块,前提是您已将其配置为这样做。

      在实践中,通过 babel 和 webpack 等工具的解决方案将回退到针对 node_modules 查找的节点样式行为,其中标准是传输路径,有利于相对路径。额外支持取决于每个环境。

      您可以在现代浏览器和当前节点中试验 esm 支持(在此答案的标志后面)。这些行为有些不一致,但定义明确。如有疑问,请尝试并尝试。

      【讨论】:

        猜你喜欢
        • 2016-01-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-26
        • 2017-12-14
        • 2016-12-11
        • 1970-01-01
        • 2016-06-15
        相关资源
        最近更新 更多