使用webpack发布使用浏览器消耗的库

时间:2018-05-13 13:42:24

标签: node.js webpack bundle

要了解如何使用webpack捆绑库,库链接为:https://github.com/InteractiveAdvertisingBureau/Consent-String-SDK-JS/ 我尝试了以下结构:

> /dist
>   - index.html 
> /src
>   - index.js 
> package.json 
> webpack.config.js

内容: 的的index.html

<!doctype html>
<html>
  <head>
    <title>Hello Webpack</title>
  </head>
  <body>
    <script src="bundle.js"></script>
    <script type="text/javascript">
        var consentData = new CSLib();
        console.log('euconsent : '+consentData);
    </script>
  </body>
</html>

index.js

require('consent-string');

webpack.config.js:

const path = require('path')

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'bundle.js',
    library: 'CSLib',
    libraryTarget: 'umd',
    path: path.resolve(__dirname, 'dist')
  }

}

运行 npm run build 后,生成bundle.js文件 但是在尝试访问索引文件时,浏览器中出现错误,例如CSlib未定义。 请你帮忙,我真的很感激。

1 个答案:

答案 0 :(得分:0)

首先,您需要将require('consent-string');的结果绑定到某个位置。我不知道图书馆,但看着他们的npm页面你应该能够做到以下几点。

const { ConsentString : CSLib} = require('consent-string');

然而即使你这样做,由于webpack实际工作的一些细节,它也行不通。基本上每个模块,或者说文件,都在它自己的范围内执行,并且它们不会泄漏到全局上下文。它是如何做到的?请允许我演示。

Webpack内部基础知识

让我们从以下导入jquery的示例文件开始,打印“test”并导出一些内容。

const $ = require('jquery');
console.log("test");

export function test() {
    console.log("test");
}

在此文件上运行webpack并打开bundle.js。您会发现它首先定义一个函数,如下所示:function(modules)。这是webpacks引导功能。如果你真的计算了所有括号,你会发现它已被定义,然后立即使用带有以下签名function(module, exports, __webpack_require__)的函数数组调用。此数组中的每个函数都代表一个模块,或者说是一个文件,webpack已包含在该模块中。你会发现一个由webpack生成的模块0。它看起来像这样:

/* 0 */
/***/function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(1); 
/***/ }

所有这一切都是致电__webpack_require__(1)。那怎么办? __webpack_require__作为参数传递给我们所在的模块函数,但如果你查看引导函数,你会发现它在那里被定义。它的工作原理如下

  1. 如果具有给定id的模块(id是我们之前讨论过的模块数组的索引)已经“安装”,则只返回模块导出的属性。如果模块在installedModules数组中有一个条目,则已安装该模块。

  2. 否则,定义一个新的模块对象(存储模块id,如果它已经加载并且它的导出)然后用一些参数调用模块函数,我将在后面讨论。

  3. 将模块标记为已加载,将模块对象添加到installedModules,并返回其exports属性(我们将在一分钟内看到exports的填充方式)。

  4. 现在让我们看一下webpack如何转换我们给它的代码。它可以在模块1中找到(从模块0中调用),如下所示(可能还有一些簿记内容,但我会忽略它,我认为这是出于兼容性原因):

    var $ = __webpack_require__(2);
    
    console.log("test");
    
    function test() {
        console.log("test");
    }
    exports.test = test;
    

    第一行是var $ = __webpack_require__(2);我们已经讨论过了。它只导入jquery,它是模块2(这就是模块2占用大部分文件的原因,因为它包含了所有jquery)。

    然后我们有console.log("test");。我们传递的代码没有任何改变。

    但我们导出的功能已分为两个语句。首先定义函数,然后将其作为属性添加到exportsexports对象由__webpack_require__传入,它表示模块导出的属性。它存储在模块对象中的installedModules中。请记住,对__webpack_require__的任何后续调用都只会返回此模块对象的exports属性。

    tldr :Webpack会将所有这些基于花哨模块的操作转换为__webpack_require__的调用,用于导入语句的导入和exports的赋值。这给人一种错觉,即每个模块都存在于它自己的小世界中。

    这对您意味着什么

    由于每个模块都在其自己的范围内运行,因此您需要将使用require('consent-string');的代码与require语句分组。总之,您的index.js应如下所示:

    const { ConsentString : CSLib} = require('consent-string');
    var consentData = new CSLib();
    console.log('euconsent : '+consentData);