使用webpack时,Node找不到模块“fs”。

93

我正在使用node.js和webpack创建一个捆绑包。根据我的了解,node.js应该包含用于管理文件的 fs 模块。然而,当我调用 require("fs") 时,我收到一个找不到模块"fs" 的错误。我该怎么办?

10个回答

70

当我使用webpack进行打包时,遇到了这个问题,后来在这个讨论串中找到了答案。

对我而言解决方法是使用以下配置:

module.exports = {
  entry: "./app",
  output: {
    path: __dirname,
    filename: "bundle.js"
  },
  module: {
      loaders: [
          {  
              test: /\.js$/,
              exclude: 'node_modules',
              loader: 'babel',
              query: {presets: ['es2015']},
          }
      ]
  },
  target: 'node'
};

通过将目标设置为node,webpack将进行必要的更改以打包您的node应用程序

编辑:此答案针对已被取代的webpack 1.x版本。


5
虽然 Webpack 更加新颖,但 target: 'node' 代码行仍然很重要,它使得在 Webpack v4 上工作成为可能。 - yagni
是的,同意,只需要target: 'node'就可以了,而且,使用webpack v5.88.2时,加载器的结构已经发生了变化,请参考:https://webpack.js.org/concepts/loaders/。 - undefined
只需检查一下NODE版本,可能有一些包需要更新的版本 - undefined

45
如果您在nodejs环境中运行webpack bundle,则需要在webpack.config.js文件中添加target: 'node',否则webpack将采用目标的默认值为web 在此查看
您可以通过以下两种方式解决此问题:
将以下配置添加到webpack.config.js文件中。
node: {
    fs: "empty"
}

或者

将以下配置添加到你的package.json文件中

"browser": {
    "fs": false
}

编辑:

有望解决的修复方法是

"browser": {
   "fs": false
}

7
在添加了 fs 后,我遇到了这个错误。 配置对象无效。Webpack 使用了一个不符合 API 模式的配置对象进行初始化。
  • configuration.node 具有一个未知属性 'fs'。有效属性为: object { __dirname?, __filename?, global? } -> 用于节点兼容性功能的选项对象。
- SuuSoJeat
5
这是因为你的 webpack 版本比这个答案中的版本要新,所以请参考我的答案 - TechDogLover OR kiaNasirzadeh
6
在webpack.config.js中添加节点{ fs: "empty" }并没有起作用,但在package.json中添加"browser": { "fs": false }却成功了! - ariebear
package.json 的入口做到了这一点。谢谢 :) - Mayank Dudakiya
我在一些旧代码中遇到了“路径”问题,而我做了完全相反的事情。删除“browser”:{“path”:false}后,现在webpack注入了正确的对象! - Hamed Mahdizadeh

23

在你的webpack.config.js文件中添加以下配置

resolve: {
  fallback: {
    fs: false
  }
}

当我更新到 Laravel Mix v6 时,这个方法对我有效。 - Stetzon
1
@kia nasirzadeh,我在Laravel 8中遇到了类似的错误,无法解决。你能帮我吗?https://stackoverflow.com/questions/68032168/how-can-i-solve-the-problem-with-module-os-and-fs-using-npm-in-laravel-8 - marco987

22
当我打包使用Web Workers的NW.js应用程序(其中又启用了Node)时,遇到了同样的问题。
我找到的解决方案是在“externals”中包含每个本地模块,并将前缀“commonjs”添加到模块名称中。例如:
    ...
    target: "webworker", // or 'node' or 'node-webkit'
    externals:{
        fs:    "commonjs fs",
        path:  "commonjs path"
    }
    ...

我在不同的项目中为目标"webworker"和"node-webkit"做了同样的事情,以解决相同的问题。


9

我需要构建一个类,在浏览器中执行时使用fetch,在node中执行时使用fs。由于其他原因,制作单独的捆绑包不切实际,因此我制作了一个面向浏览器的单个捆绑包。

我使用的解决方案是,如果脚本在node中运行,则使用eval('require("fs")')

const fs = eval('require("fs")')

浏览器兼容性(在浏览器中fsnull):

const fs = typeof window === 'object'
    ? null
    : eval('require("fs")')

8

在试过互联网上所有的方法(targetexternalsnode 配置)之后,唯一有效的解决方案是替换:

const filesystem = require("fs")
        or
import fs from "fs"

通过特定的webpack版本

const fs = __non_webpack_require__("fs")

这会生成一个不被webpack解析的require函数。


1
我的Electron不理解__non_webpack_require__是什么。 - paddotk

3
除了PDG的答案,还有以下内容:

我习惯于这种简短的复制/粘贴方式。

使用pathfs

var nodeModules = {};
fs.readdirSync(path.resolve(__dirname, 'node_modules'))
  .filter(x => ['.bin'].indexOf(x) === -1)
  .forEach(mod => { nodeModules[mod] = `commonjs ${mod}`; });

// Before your webpack configuration

module.exports = {
...
}

然后在您的配置文件中,将nodeModules变量包含在externals中。

...
externals: nodeModules,
...

2

使用预定义解决方案会更加优雅,例如:在webpack配置文件中添加target: 'node'

更多信息请参考:官方文档


0

明确一下,我不是一个专业的node.js开发者,只是一个不幸的前端开发者,试图使用别人的代码。

你可能会想知道为什么会出现错误,显然,node.js提供了比前端更多的功能,许多开源模块如fspath等,用于构建后端方法。

那么我该如何忽略实现中的后端部分,以使其正常工作呢?


选项1

使后端模块无效

添加到webpack.config.js

resolve: {
    fallback: {
        fs: false,
        path: false,
    },
},

同时也要在package.json中添加相应的配置,否则你很可能会遇到Filed 'browser' doesn't contain a valid alias configuration的错误。

"browser": {
    "fs": false,
    "path": false,
}, 

如果依赖项不依赖于后端模块,那么这将起作用,也就是说,不要在运行时写本地文件之类的操作,并且不要从任何在该模块中声明的原型中访问prototype


选项2

browserify polyfill

polyfill基本上是填补功能差距的一段代码,browserify提供了模拟该依赖项接口的对象,在缩小的代码中,例如,如果调用fs.readFile,它不会抛出undefined error,而是函数将返回null并继续运行。

resolve: {
    fallback: {
        fs: require.resolve("browserify-fs"),,
        path: require.resolve("path-browserify"),,
    },
},

你可能会注意到前缀browserify-和后缀-browserify是不同的,这不是笔误,根据你实际需要搜索npm上的有效名称。以下是一些常见名称,您可以直接使用:

  • browserify-fs
  • browserify-zlib
  • browserify-shim
  • path-browserify
  • stream-browserify
  • crypto-browserify

这里有一个快速提示,在插件多项填充之后,production模式构建可能会编译出巨大的文件大小。你可能想直接使用development 模式,尽管它会写入大量文件。


-2

为了我们正在构建的解决方案,我们不得不强制使用旧版本的webpack:

npm install --save --force webpack@webpack-3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接