I'm using node.js and webpack to create a bundle. From what I've read, node.js should contain fs module for managing files. However when I call require("fs") I get an Cannot find module "fs" error. What should I do?
- 7,153
- 3
- 19
- 27
- 967
- 2
- 7
- 12
9 Answers
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.
- 933
- 8
- 11
-
2Even though webpack is much newer, the `target: 'node'` line is still important and what makes this work on webpack v4 – yagni Oct 06 '21 at 16:40
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
}
- 29,321
- 31
- 106
- 146
-
6I got this error after I added the fs. Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. - configuration.node has an unknown property 'fs'. These properties are valid: object { __dirname?, __filename?, global? } -> Options object for node compatibility features. – SuuSoJeat Oct 12 '20 at 13:52
-
4@SuuSoJeat that is because the version of your webpack is newer from this answer, [see my answer](https://stackoverflow.com/a/64428818/6791254) instead – kia nasirzadeh Oct 19 '20 at 13:52
-
3Adding node: { fs: "empty" } to webpack.config.js did not work but adding "browser": { "fs": false } to package.json did! Success! – ariebear Dec 02 '20 at 07:04
-
-
I had problem with 'path' in some legacy code and I did the exact opposite thing. After removing the "browser": { "path": false} now the webpack injects the correct object! – Hamed Mahdizadeh Nov 15 '21 at 15:35
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.
- 1,664
- 1
- 9
- 8
Add below configuration to your webpack.config.js
resolve: {
fallback: {
fs: false
}
}
- 2,518
- 20
- 26
-
-
1@kia nasirzadeh I have a similar error with Laravel 8 that I can't solve. Could you please help me? https://stackoverflow.com/questions/68032168/how-can-i-solve-the-problem-with-module-os-and-fs-using-npm-in-laravel-8 – marco987 Jun 18 '21 at 10:49
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.
- 11,739
- 4
- 37
- 44
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")')
- 4,570
- 2
- 21
- 38
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,
...
- 721
- 10
- 17
It would be more elegant to use pre-defined solution as:
Adding target: 'node' to webpack config file.
More info on: official documentation
- 53
- 5
For the solution we are building we had to force an older version of webpack:
npm install --save --force webpack@webpack-3
- 26,827
- 28
- 51
- 55
- 27
- 2