Webpack - объединение двух анонимных модулей в один комбинированный файл.js

Я пытаюсь объединить два требуемых модуля AMD в один файл Javascript комбинированный.js с помощью Webpack.

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 и других источниках, в качестве хорошей практики, они явно рекомендуют не устанавливать имя для каждого модуля, а вместо этого оставлять его анонимным без идентификатора: https://github.com/requirejs/requirejs/wiki/Updating-existing-libraries

" Обычно вы не должны регистрировать именованный модуль, а должны зарегистрироваться как анонимный модуль... "

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 - Вывод - комбинированный.js

https://pastebin.com/Dy9ZcgAc

Попытка загрузки файла и модулей комбинированного.js с RequireJS

[index.html]

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

проблема

При загрузке файла комбинированного.js я всегда получаю первый анонимный модуль, определенный в объединенном файле. И я не знаю, как получить второй модуль, он никогда не устанавливается в переменной requireJS: window.requirejs.s.contexts._.fined

Дополнительная информация

Если я собираю модули с "идентификатором имени" в определении ("имя",..) каждого модуля, он работает отлично, и я могу их отлично загружать, но, как объяснялось выше, называть ваши имена не рекомендуется. модули.

Вопросы

  1. Как я могу объединить эти модули ANONYMOUS в один комбинированный файл.js, загрузить этот файл с requireJS и затем получить каждый модуль?
  2. Может ли быть что-то не так в коде?
  3. Я посмотрел на переменную requireJS: window.requirejs.s.contexts._., Определенную для поиска всех модулей, но второй модуль там никогда не добавляется. Поэтому я полагаю, что это может быть связано с тем, какой шаблон UMD я использую, или с функцией, не поддерживаемой Webpack.

Я совершенно отчаянно пытаюсь ее решить и уже просмотрел множество ресурсов, но не смог найти четкого ответа. большое спасибо

1 ответ

Я думаю, что нашел причину, почему это не работает.

Как только файл webpack комбинированный.js вызывается с RequireJS, он выполнит строку, чтобы вернуть свою собственную главную точку входа:

/******/    // 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**
           //
        }
);

Попытка добавить поддержку и обновить этот пост, как только я заработаю.

Другие вопросы по тегам