与 rollup 捆绑一个库,该库导入使用条件节点 require 语句的旧版 UMD 库

问题描述 投票:0回答:2

我正在构建一个仅在浏览器中使用的 UMD 库。但是,它依赖于另一个 UMD 库/模块/bundle .js 文件,其中包含 Nodejs 模块的 require 语句。这些语句并不总是运行,但仅当该子库检测到它在 NodeJS 中运行时才运行。对于上下文,所需的 Nodejs 模块是

os
http
https
,但它们都是动态需要的。

我的

rollup.config.js
已经在使用
@rollup/plugin-node-resolve
@rollup/plugin-commonjs
@rollup/plugin-typescript
。但在构建时会触发一些警告。

(!) Missing shims for Node.js built-ins
Creating a browser bundle that depends on "os", "http" and "https". You might need to include https://github.com/FredKSchott/rollup-plugin-polyfill-node
(!) Missing global variable names
https://rollupjs.org/guide/en/#outputglobals
Use "output.globals" to specify browser global variable names corresponding to external modules:
os (guessing "require$$0")
http (guessing "require$$1")
https (guessing "require$$2")

生成的捆绑文件:

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('os'), require('http'), require('https')) :
    typeof define === 'function' && define.amd ? define(['exports', 'os', 'http', 'https'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.ns_ = global.ns_ || {}, global.ns_.Bundle = {}), global.require$$0, global.require$$1, global.require$$2));
})(this, (function (exports, require$$0, require$$1, require$$2) { 'use strict';

// ...

// Pseudo-code
if(node) {
  const os = require$$0;
  //...
}

捆绑器已将我的

require('os')
语句替换为
require$$0
,因此它不会像我预期的那样“有条件地”调用 require 语句。它们已被预先调用(悬挂)。有什么方法可以让 Rollup 不进行提升吗?

javascript node.js typescript rollup
2个回答
2
投票

警告中非常清楚地指出,

os
http
https
模块包含在浏览器捆绑包中,并且 Rollup 无法确定这些模块的正确全局变量名称。

您可以在 Rollup 配置中使用建议的

output.globals
选项为这些模块指定正确的全局变量名称。

类似:

export default {
  output: {
    globals: {
      os: 'os',
      http: 'http',
      https: 'https',
    },
  },
  // other options
};

-或-

您还可以使用

@rollup/plugin-polyfill-node
(通过将其按原样包含在 Rollup 配置中)自动包含这些内置 Node.js 模块的 polyfill。

请告诉我这是否有效。


0
投票

不知道是bug还是什么,但是直接使用

require
就会出现这个问题。当直接使用
require
时,
commonjs
不认为它是动态的。显然它无法在项目的任何地方找到源代码。因此出于某种原因将其吊起。

为了避免这个问题。您需要包装

require
方法并使用
ignoreDynamicRequires
插件的
commonjs
选项。

以下代码

// rollup.config.js

const { defineConfig } = require("rollup");
const commonjs = require("@rollup/plugin-commonjs");

module.exports = [
  defineConfig({
    input: "index.js",
    context: this,
    output: [
      {
        name: "rollup-dynamic-require",
        file: `output.js`,
        sourcemap: "inline",
        format: "umd",
      },
    ],
    plugins: [
      commonjs({
        ignoreDynamicRequires: true, // this is the option for dynamic imports.
      }),
    ],
  }),
];

//index.js

const dynamicRequire = function (module) {
  return require(module);
};

(function rollupDynamicRequire() {
  let required;
  for (const element of [0, 1, 2]) {
    if (element === 0) {
      required = dynamicRequire("http");
    } else if (element === 1) {
      required = dynamicRequire("https");
    } else if (element === 2) {
      required = dynamicRequire("os");
    }
    console.log(required.globalAgent.protocol);
  }
})();

//输出.js

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
    typeof define === 'function' && define.amd ? define(factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global["rollup-dynamic-require"] = factory());
})(this, (function () { 'use strict';

    function getDefaultExportFromCjs (x) {
        return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
    }

    var rollupDynamicRequire = {};

    var hasRequiredRollupDynamicRequire;

    function requireRollupDynamicRequire () {
        if (hasRequiredRollupDynamicRequire) return rollupDynamicRequire;
        hasRequiredRollupDynamicRequire = 1;
        const dynamicRequire = function (module) {
          return require(module);
        };

        (function rollupDynamicRequire() {
          let required;
          for (const element of [0, 1, 2]) {
            if (element === 0) {
              required = dynamicRequire("http");
            } else if (element === 1) {
              required = dynamicRequire("https");
            } else if (element === 2) {
              required = dynamicRequire("os");
            }
            console.log(required.globalAgent.protocol);
          }
        })();
        return rollupDynamicRequire;
    }

    var rollupDynamicRequireExports = requireRollupDynamicRequire();
    var index = /*@__PURE__*/getDefaultExportFromCjs(rollupDynamicRequireExports);

    return index;

}));
© www.soinside.com 2019 - 2024. All rights reserved.