我正在使用node.js和webpack创建一个捆绑包。根据我的了解,node.js应该包含用于管理文件的 fs
模块。然而,当我调用 require("fs")
时,我收到一个找不到模块"fs"
的错误。我该怎么办?
当我使用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版本。
node: {
fs: "empty"
}
或者
将以下配置添加到你的package.json文件中
"browser": {
"fs": false
}
编辑:
有望解决的修复方法是
"browser": {
"fs": false
}
在你的webpack.config.js文件中添加以下配置
resolve: {
fallback: {
fs: false
}
}
...
target: "webworker", // or 'node' or 'node-webkit'
externals:{
fs: "commonjs fs",
path: "commonjs path"
}
...
我在不同的项目中为目标"webworker"和"node-webkit"做了同样的事情,以解决相同的问题。
我需要构建一个类,在浏览器中执行时使用fetch
,在node中执行时使用fs
。由于其他原因,制作单独的捆绑包不切实际,因此我制作了一个面向浏览器的单个捆绑包。
我使用的解决方案是,如果脚本在node中运行,则使用eval('require("fs")')
。
const fs = eval('require("fs")')
浏览器兼容性(在浏览器中fs
为null
):
const fs = typeof window === 'object'
? null
: eval('require("fs")')
在试过互联网上所有的方法(target
,externals
,node
配置)之后,唯一有效的解决方案是替换:
const filesystem = require("fs")
or
import fs from "fs"
通过特定的webpack版本
const fs = __non_webpack_require__("fs")
这会生成一个不被webpack解析的require函数。
__non_webpack_require__
是什么。 - paddotk我习惯于这种简短的复制/粘贴方式。
使用path和fs:
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,
...
明确一下,我不是一个专业的node.js
开发者,只是一个不幸的前端开发者,试图使用别人的代码。
你可能会想知道为什么会出现错误,显然,node.js
提供了比前端更多的功能,许多开源模块如fs
、path
等,用于构建后端方法。
那么我该如何忽略实现中的后端部分,以使其正常工作呢?
使后端模块无效
添加到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
。
browserify polyfill
polyfill基本上是填补功能差距的一段代码,browserify
提供了模拟该依赖项接口的对象,在缩小的代码中,例如,如果调用fs.readFile
,它不会抛出undefined error
,而是函数将返回null
并继续运行。
resolve: {
fallback: {
fs: require.resolve("browserify-fs"),,
path: require.resolve("path-browserify"),,
},
},
你可能会注意到前缀browserify-
和后缀-browserify
是不同的,这不是笔误,根据你实际需要搜索npm上的有效名称。以下是一些常见名称,您可以直接使用:
这里有一个快速提示,在插件多项填充之后,production
模式构建可能会编译出巨大的文件大小。你可能想直接使用development
模式,尽管它会写入大量文件。
为了我们正在构建的解决方案,我们不得不强制使用旧版本的webpack:
npm install --save --force webpack@webpack-3
target: 'node'
代码行仍然很重要,它使得在 Webpack v4 上工作成为可能。 - yagnitarget: 'node'
就可以了,而且,使用webpack v5.88.2时,加载器的结构已经发生了变化,请参考:https://webpack.js.org/concepts/loaders/。 - undefined