节点在使用 webpack 时无法找到模块“ fs”

我使用 node.js 和 webpack 来创建一个 bundle。据我所知,node.js 应该包含用于管理文件的 fs模块。但是,当我调用 require("fs")时,我得到一个 Cannot find module "fs"错误。我该怎么办?

154946 次浏览

I came across this problem myself when bundling with webpack and found the answer on this thread.

The way to solve it for me was to use the following config:

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

By setting target to node webpack will make the necessary changes to bundle your node application

Edit: This answer targeted webpack 1.x which has now been superseded.

I had the same issue when bundling a NWjs application using webworkers (which in turn had node enabled).

The solution I found was to include each native module I used in externals with the prefix commonjs to the name of the module. For example:

    ...
target: "webworker", // or 'node' or 'node-webkit'
externals:{
fs:    "commonjs fs",
path:  "commonjs path"
}
...

I've done the same for targets "webworker" and "node-webkit" in different projects to solve the same issue.

If you are running your webpack bundle in nodejs environment then target: 'node' is required in webpack.config.js file otherwise webpack takes default value as web for target check here.

You can resolve the issue in two ways

Add below configuration to your webpack.config.js

node: {
fs: "empty"
}

OR

Add below configuration to your package.json

"browser": {
"fs": false
}

Edit:

promising fix is

"browser": {
"fs": false
}

In addition to the answer of PDG

I'm used to this short copy/paste candy.

Using path and 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 = {
...
}

Then inside your configuration file, include the nodeModules variable in the externals

...
externals: nodeModules,
...

For the solution we are building we had to force an older version of webpack:

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

I needed to build a class that would use fetch if executed in a browser, or fs if executed in node. For other reasons, it was impractical to produce separate bundles, so I produced a single browser-targeted bundle.

The solution I used was to use eval('require("fs")') if the script was running in node.

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

Browser-safe (fs is null in the browser):

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

After trying everything I found on the internet (target, externals, node configs), the only solution that actually worked for me was replacing:

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

by the special webpack version

const fs = __non_webpack_require__("fs")

This generates a require function that is not parsed by webpack.

Add below configuration to your webpack.config.js

resolve: {
fallback: {
fs: false
}
}

It would be more elegant to use pre-defined solution as:
Adding target: 'node' to webpack config file.

More info on: official documentation