为什么我每次都需要在webpack bundle中导入模块?

时间:2017-11-12 16:52:36

标签: javascript import webpack

我使用webpack生成一个包文件,即app.bundle.js。似乎是在每个单独的js文件中我需要导入它将使用的模块。

我一直试图绕过这个,但它很难找到我。我理解捆绑过程的方式是简化:它将您指定的所有文件合并到一个大输出文件中。

这应该意味着一个类在该大文件中被声明为ONCE,并且应该足以作为所有其他类的引用。为什么我需要一次又一次地导入它,当它应该只是在捆绑文件的顶部可用于其后写的每一段代码?

P.S(一个简单的例子)

我有以下文件:

A.js

class A {
    doIt(){
      console.log(this);
    }
}

B.js:

import {A} from "a.js";

class B extends A {

}

main.js:

import {A} from "a.js"
import {B} from "b.js"

在main.js中使用B我也需要导入A.如果A有另一个子类,我也需要导入它。对我来说,这看起来很疯狂,以至于我宁愿在窗户上对所有东西进行暗示。

如果有人知道,请帮助我理解我遗失的内容。

1 个答案:

答案 0 :(得分:0)

  1. Webpack获取您指定的所有文件,并将它们合并为一个大输出文件,以便在正确的范围内在正确的范围内提取相关的模块。
  2. 所以如果我们有:

    // sum.js
    

    var sum = function (a, b) {     return a + b;};

    // multiply.js

    // slightly contrived here - we're going to repeatedly sum to multiply, to illustrate dependency
    // interaction
    var multiply = function (a, b) {
        var total = 0;
        for (var i = 0; i < b; i++) {
            total = sum(a, total);
        }
        return total;
    };
    

    // index.js

    - our application logic
    var totalMultiply = multiply(5, 3);
    var totalSum = sum(5, 3);
    
    console.log('Product of 5 and 3 = ' + totalMultiply);
    console.log('Sum of 5 and 3 = ' + totalSum);
    

    // index.html

    - our entry point to our application
    <html>
    <head>
        <script src="src/sum.js"></script>
        <script src="src/multiply.js"></script>
        <script src="src/index.js"></script>
    </head>
    </html>
    

    这个的输出是:

    Product of 5 and 3 = 15
    index.js:17 Sum of 5 and 3 = 8
    
    • 如果我们在index.html中得到错误的顺序,我们的应用程序将无效。如果index.js包含在其他任何依赖项之前,或者如果在multiply.js之后包含sum.js,我们将得到错误。这是捆绑文件的重点。
    • Webpack可以将我们所有的依赖项都放到一个文件bundle file中,这意味着只需要下载一个依赖项。
      

    2-使依赖关系可用,并链接它们

    • CommonJS使用module.exports将函数或变量导出 - 或使其可用 - 到其他代码。它使用require来引入这些导出的值。

    // sum.js

    var sum = function (a, b) {
        return a + b;
    };
    module.exports = sum;
    

    // multiply.js

    var sum = require('./sum');
    
    var multiply = function (a, b) {
        var total = 0;
        for (var i = 0; i < b; i++) {
            total = sum(a, total);
        }
        return total;
    };
    module.exports = multiply;
    

    // index.js

    - our application logic
    var multiply = require('./multiply');
    var sum = require('./sum');
    
    var totalMultiply = multiply(5, 3);
    var totalSum = sum(5, 3);
    
    console.log('Product of 5 and 3 = ' + totalMultiply);
    console.log('Sum of 5 and 3 = ' + totalSum);
    
    • 请注意,我们已将sum和multiply都用于其他代码,我们在multiple.js和index.js中引入了这些导出函数。
    • 另请注意,我们的index.html现在只需要提取一个文件 - bundle.js。
    • 我们可以公开我们想要的内容,并将其他代码保密。
      

    这就是重点,您需要告诉webpack您需要哪些模块进行通信并相互共享数据。与webpack一样,每个模块的表面积都比完整程序小,从而使验证,调试和测试变得微不足道。编写良好的模块提供了可靠的抽象和封装边界,因此每个模块在整个应用程序中具有一致的设计和明确的目的。

    • 我们还将网络调用从3(sum.js,multiply.js和index.js)减少到 一次通话 - 这有助于加快加载时间。
      

    注意我不建议将库或模块公开为全局,除非你确实需要它,即模块系统的要点是显式声明依赖。

    • ProvidePlugin:此插件使模块在每个模块中都可用作变量。只有在使用变量时才需要该模块。

    示例:在每个模块中都可以使用$和jQuery,而无需编写require(“jquery”)。

    new webpack.ProvidePlugin({
    $: "jquery",
    jQuery: "jquery",
    "window.jQuery": "jquery"
    })
    

    所以:

    // app.js
    $.ajax(...);
    

    有效地转化为:

    // app.js
    require('jquery').ajax(...);
    

    webpack将生成一个加载指定模块的代码,与导入或需要的代码相同。