Webpack - 将两个匿名模块组合成一个combined.js文件

时间:2017-05-14 17:42:04

标签: javascript webpack require umd

我正在尝试使用 Webpack 将两个需要的amd模块合并到一个combined.js javascript文件中。

module1.js

//module1.js - objectTest1
(function (root, factory) {
    'use strict';

    //Universal Module Definition
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.returnExports = factory();
    }
}(this, function () {
    'use strict';

     return function objectTest1() {
          var test = '1';
          return test;
     };
}));

module2.js

//module2.js - objectTest2
(function (root, factory) {
    'use strict';

    //Universal Module Definition
    if (typeof define === 'function' && define.amd) {
        // AMD
        define(factory);
    } else if (typeof exports === 'object') {
        // Node, CommonJS-like
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.returnExports = factory();
    }
}(this, function () {
    'use strict';

     return function objectTest2() {
          var test = '2';
          return test;
    };
}));

推荐的良好做法

在requireJS wiki和其他来源中,作为一种好的做法,他们明确建议不要为每个模块设置一个名称,而是在没有id的情况下保持匿名: https://github.com/requirejs/requirejs/wiki/Updating-existing-libraries#anon

" 通常你不应该注册一个命名模块,而是注册为匿名模块... "

WebPack - 将模块合并到一个js文件中

[webpack.config.js]

module.exports= {
    entry: [
        "./modules/module1.js",
        "./modules/module2.js"
    ],
    output: {
        filename:"combined.js",
        libraryTarget: "umd",
        umdNamedDefine: true
    }
};

[Ejecute WebPack合并]

webpack.js
webpack 2.5.1
Time: 64ms
Asset     Size  Chunks             Chunk Names
combined.js  5.11 kB       0  [emitted]  main
   [0] ./modules/module1.js 551 bytes {0} [built]
   [1] ./modules/module2.js 551 bytes {0} [built]
   [2] multi ./modules/module1.js ./modules/module2.js 40 bytes {0} [built]

WebPack - 输出 - combined.js

https://pastebin.com/Dy9ZcgAc

尝试使用RequireJS

加载combined.js文件和模块

[index.html的]

require(["combined", "combined/modules/module1", "combined/modules/module2"], 
        function (combined, objectTest1, objectTest2) {
           //combined = objectTest1
           //
           //objectTest1 = objectTest1 - OK!
           //
           //objectTest2 = objectTest1 - **WRONG**
           //
        }
);

问题

加载combined.js文件时,我总是得到组合文件中定义的第一个匿名模块。我不知道如何获得第二个模块,它从未在requireJS变量中设置: window.requirejs.s.contexts ._。已定义

其他信息

如果我使用&id; id名称构建模块'在每个模块的define(' name',..)中,它工作得很好,我可以完美地加载它们,但如上所述,命名模块并不是一个好习惯。

问题

  1. 如何在一个combined.js文件中组合这些ANONYMOUS模块,用requireJS加载该文件,然后获取每个模块?
  2. 代码中可能有问题吗?
  3. 我查看了requireJS变量: window.requirejs.s.contexts ._。已定义以查找所有模块,但第二个模块从未添加到那里。所以我想这可能是我正在使用的UMD模式或Webpack不支持的功能的问题。
  4. 我正在试图解决它并且已经查看了许多资源,但是找不到明确的答案。 非常感谢

1 个答案:

答案 0 :(得分:0)

我想我找到了它无效的原因。

使用RequireJS调用webpack combined.js文件后,它将执行该行以返回其自己的主入口点:

/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = 2);

我们有一个位置为[0] = module1的数组; position [1] = module2,position [2] = webpack_entry_point。如果我们查看那些行,它将执行我们在文件末尾可以看到的webpack_entry_point代码:

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

最后一行:"module.exports = __webpack_require__(1);"是重要的一行,因为它说什么模块对象将被返回。 如果我们将它设置为"module.exports = __webpack_require__(0);",那么将返回objectTest1,然后我们将其设置为"module.exports = __webpack_require__(1);",然后将返回objectTest2,因为module.exports不能返回2个不同的东西并且会被覆盖。

保持与匿名模块兼容的解决方案是将构造函数中的标识字符串传递给webpack,以便能够处理要返回的模块,如上面不支持的示例:

require(["combined", "combined/modules/module1", "combined/modules/module2"], 
        function (combined, objectTest1, objectTest2) {
           //combined = objectTest1
           //
           //objectTest1 = objectTest1 - OK!
           //
           //objectTest2 = objectTest1 - **WRONG**
           //
        }
);

尝试添加支持并在我开始工作后更新此帖子。