【问题标题】:Webpack Uncaught ReferenceError: require is not defined after removing node_modules from bundle.jsWebpack Uncaught ReferenceError: 从 bundle.js 中删除 node_modules 后未定义要求
【发布时间】:2017-04-18 22:32:52
【问题描述】:
bundle.js      2.83 kB   0  [emitted]  main
bundle.js.map  3.36 kB   0  [emitted]  main

当我使用自定义外部添加下面的代码时,我可以将node_modules 直接包含在bundle.js 输出中。

bundle.js      743 kB       0  [emitted]  main
bundle.js.map  864 kB       0  [emitted]  main

这显着减小了捆绑包的大小。 但我在浏览器中收到错误提示: Uncaught ReferenceError: require is not defined 在浏览器中。有谁知道如何解决这个问题?

var path = require("path"),
  fs = require("fs");

// return what's in the node modules folder apart from ".bin"
const nodeModules = fs
  .readdirSync("./node_modules")
  .filter(d => d != ".bin");

/**
 * Remove non-direct references to modules from bundles
 *
 * @param {any} context
 * @param {any} request
 * @param {any} callback
 * @returns
 */
function ignoreNodeModules(context, request, callback) {
  // IF someone is importing a module e.g. "import {chatModule} from
  // "./components/chat" using a relative path, then we're okay with them bringing
  // in into the bundle
  if (request[0] == ".") 
    return callback();

  // IF someone is doing "import {Subject} from "rxjs/Subject" only want to know
  // if first part is a node_module
  const module = request.split("/")[0];
  if (nodeModules.indexOf(module) !== -1) {
    // append "commonjs " - tells webpack to go and grab from node_modules instead
    // of including in bundle
    return callback(null, "commonjs " + request);
  }

  return callback();
}

module.exports = {
  entry: "./src/index.tsx",
  output: {
    filename: "bundle.js"
  },
  devtool: "source-map",
  resolve: {
    extensions: ["", ".ts", ".tsx", ".js"]
  },
  module: {
    loaders: [
      {
        test: /\.ts(x?)$/,
        loader: "ts-loader"
      }
    ]
  },
  // Runs our custom function everytime webpack sees a module
  externals: [ignoreNodeModules]
}

【问题讨论】:

    标签: javascript webpack commonjs


    【解决方案1】:

    你的包更小,因为你没有包含你的node_modules,但这会导致一个根本问题:你不再将依赖项发送到浏览器,所以你的代码根本无法运行强>。您可能知道,浏览器本身并不支持require(),因此您当前的ignoreNodeModules 函数告诉Webpack 跳过捆绑它们并保留在require() 中,但浏览器不知道如何处理它。

    如果您想减小包大小,请考虑使用 Webpack 的 code splitting,以便您仅捆绑每个页面/部分所需的依赖项。或者,您可以考虑使用浏览器端 require() 加载程序,例如 RequireJS

    使用 externals 仅对分发服务器端 Node 库真正有用,在这种情况下,您希望库的使用者提供您的依赖项,而不是将它们与您的库捆绑在一起。

    documentation about externals 上的 cmets 也值得一读,以了解有关该问题的更多背景信息。

    【讨论】:

    • 就最佳实践而言,是进行代码拆分还是使用浏览器端的 require() 加载器(例如 RequireJS)更好?
    • 这取决于您的服务器和应用程序。如果您使用的是 HTTP2,答案是根本不捆绑,因为它可以轻松处理多个并发请求。否则,我会使用代码拆分,因为 Webpack 对它的支持比 RequireJS 好一点(但它技术上没有任何问题)。
    • 太棒了!非常感谢您的建议。我以前没有听说过很多关于 HTTP2 的内容,但我会研究一下 :) 否则我会进行代码拆分,看看它是如何进行的。
    • @ClementOh 很高兴它有所帮助 - 如果您认为这个问题现在已解决,请不要忘记接受。如果您对此有任何其他问题,请随时在此处回复链接,以便我收到通知并尝试查看!
    • 完成。谢谢你的提议!非常感谢您的帮助!我实际上对 webpack 有疑问,并在下面的链接中表达。很高兴看到你的想法:stackoverflow.com/questions/40959835/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 2019-03-19
    • 1970-01-01
    • 2016-08-16
    • 2023-02-02
    相关资源
    最近更新 更多