css-loader: Can't resolve 'fs' when bundle with webpack

Do you want to request a feature or report a bug? Bug

What is the current behavior? Webpack finish bundle without errors with css-loader 0.26.4. After update to 0.27.0 webpacking finished with error:

ERROR in ./~/convert-source-map/index.js
Module not found: Error: Can't resolve 'fs' in 'C:\Projects\project_name\node_modules\convert-source-map'
 @ ./~/convert-source-map/index.js 2:9-22
 @ ./~/css-loader/lib/css-base.js

If the current behavior is a bug, please provide the steps to reproduce.

  1. Update css-loader from 0.26.4 to 0.27.0 version
  2. Run webpack to build

What is the expected behavior? Works without error

Please mention other relevant information such as your webpack version, Node.js version and Operating System. Windows 8.1 Node.js 7.7.2 Webpack 2.2.1

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 455
  • Comments: 101 (12 by maintainers)

Commits related to this issue

Most upvoted comments

Adding

node: {
  fs: 'empty'
}

to webpack config file and the error is gone. Not sure how it works, It seems like webpack did some thing with fs module in web target.

The issue has been acknowledged and we are in process of figuring out a good fix. No need for "me too"s. Please add a thumbs up on the original issue if you want to do that. 👍

add the following to your Webpack config:

node: {
   fs: "empty"
}

@PredokMiF You don’t unpublish anything, ever.

The workaround is sufficient and the bug is actually in webpack, related to fs in the web target.

WORKAROUND thanks to @hdnha11 / @mehdivk

node: {
  fs: 'empty'
}

If using this workaround isn’t viable, version lock to the previous minor version.

same here

For Webpack >5 You shoud add a block to webpack.config.js like this:

//webpack.config.js

module.exports = {
    ...
    resolve: {
        fallback: {
            "fs": false
        },
    }
}

just wanted to add that I fixed this by the answer in https://github.com/josephsavona/valuable/issues/9 about setting target: 'node'

This explains more: http://jlongster.com/Backend-Apps-with-Webpack--Part-I

The target: ‘node’ option tells webpack not to touch any built-in modules like fs or path.

Same for me, had to rollback that update

same here

Did you can to unpublish this version? It will keep calm to all of us

Someone please fix this issue. Non of the mentioned answer could fix it for me

Fixed by adding target: 'node', in webpack.config.js

@Percapio add this

target: 'node'

I get an error like this:

TypeError: fs.readFileSync is not a function

I fixed the problem by changing webpack.config.js:

… var config = Encore.getWebpackConfig(); config.node = { fs: ‘empty’ }; module.exports = config;

and: yarn add --dev file system

same here

Still i am unable to resolve the fs error plz help me

I added node: { fs: 'empty' } without luck,

then I added --config to start command: ̀webpack-dev-sever webpack.config.dev.js`

You must add the --config flag to put in a custom file. ̀webpack-dev-sever --config webpack.config.dev.js`

Boom! It worked.

Me Too. This is still an issue

Same problem - why is this issue closed? Should I 👍 a different issue?

How should I go about solving this issue when importing an npm module that uses Webpack (i.e., when importing an npm module that imports a package that yields this problem)?

To add some clarity: say I’ve create two npm modules, both using Webpack. Let’s call them module A and module B.

Module A imports require, which yields this error. Thus, in webpack.config.js of module A, I add:

  node: {
    console: false,
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  }

Module B then imports module A. However, even though I’ve added the above code in module A, the error still comes up when I try to build module B.

Does anyone know how to solve this problem without adding the above code to module B as well (i.e., modifying only module A)?

I got this problem because I ran: webpack webpack.config.js rather than webpack --config webpack.config.js. It bundled webpack itself and it took forever to bundle.

I came across the same error. I am starting off with JS (with vuejs) and I would like to understand what this does?

I got this error when using the “fetch” library from npm. At first I got the same error but with other packages (net and dns). My first thought was that those are missing dependencies. After running npm install net and npm install dns, those errors were replaced with dgram and fs. The latter one prompted me to hit Google and landed on this issue.

I now added two sections in my webpack config for both fs and dgram, and now the errors are gone.

But I don’t know what this entails. Will my compiled code still work? Even if these sections are configured as being empty? What does it actually do?

Also, is this the right place to ask this? Or should it be rather targeted at vuejs?

nb: I would like to give a bit more insight about my running environment but as I’m still getting my feet wet, I don’t know which commands are the best to represent a snapshot of my dev-environment. If you need some additional output, let me know which commands to run.

So is there proper fix for this? I’m not having any luck in React with these workarounds.

The solution for me was to hack the Angular-CLI module to spoof the missing node modules.

After installing locate the following file:

node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js

Find the node line and add this:

node: { crypto: true, stream: true, fs: 'empty', net: 'empty' }

And that’s it!!!

🎉🎉🎉🎉🎉

Note: You will need to do this patch every time you update the package. So use this script:

package.json

"scripts": {
  ...
  "postinstall": "node patch-webpack.js"
  ...
}

patch-webpack.js

const fs = require('fs');
const f = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
 
fs.readFile(f, 'utf8', function (err,data) {
  if (err) {
    return console.log(err);
  }
  let result = data.replace(/node: false/g, "node: {crypto: true, stream: true, fs: 'empty', net: 'empty'}");
 
  fs.writeFile(f, result, 'utf8', function (err) {
    if (err) return console.log(err);
  });
});

Source: https://blog.lysender.com/2018/07/angular-6-cannot-resolve-crypto-fs-net-path-stream-when-building-angular/

There is a better solution available hee

I have a React SSR (server side rendering) website, and both my server.js and browser.js go through webpack. For this purpose I have:

webpack.server.js:

{
    target: 'node',
}

webpack.browser.js:

{
    node: {
        fs: 'empty',
    }
}

This way my server.js can actually fs.write, and the browser only gets rid of compile errors.

I have a working solution for webpack to transfer any variables in the front-end, if it can help someone.

In your webpack.config.client.js before anything else:

require('dotenv').config()
const webpack = require('webpack')

In your webpack.config.client.js in the plugins section just redefine anything you want in the front-end:

new webpack.DefinePlugin({
    'process.env.MY_VAR': process.env.MY_VAR,
    'process.env.MY_OTHER_VAR': process.env.MY_OTHER_VAR,
    'process.env.MY_STRING': '"' + process.env.MY_STRING + '"',
}),

And that’s all, now you can access process.env.MY_VAR from anywhere in the front-end and you don’t need to call the dotenv in your front-end.

If any of you is using NextJS to fix this problem, you can add:

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
    config.node = {
      fs: 'empty'
    }
    return config
  },
}

To your next.config.js file

  node: {
    fs: 'empty'
  }

The work-around allows us to run the webpack, but if our application needs to use FS for any reason, like write to file, the work-around is now a problem as FS no longer exists.

fs.writeFile is not a function

Does anyone have a different solution?

I’m having the same issue, I don’t know where I have to write the

node: {
 fs: 'empty'
}

@exhuma See the related page on documentation. That describes the default behavior. You can also find possible overrides there. I hope this helps.

Also, is this the right place to ask this? Or should it be rather targeted at vuejs?

Stack Overflow might be better for this type of questions.

Got this error.

[webpack-cli] 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.

on Doing

config = Encore.getWebpackConfig();
config.node = { fs: "empty" };
module.exports = config;

@executives what if you want to access the fs library outside of webpack.config.js ?

Example: File: configLoader.js

const fs = require('fs');

// Get content from file
const config = fs.readFileSync("./config/local/config.json");

const properties = JSON.parse(config);

console.log("Environment: " + properties.environment);
console.log("HomepageUrl: " + properties.homepageUrl);

File: webpack.config.js

"use strict";

const webpack = require('webpack');
const path = require('path');


module.exports = function(env) {
    console.log('NODE_ENV: ', env.NODE_ENV); // 'local'

    const CURRENT_ENV = 'local';
    let NEW_ENV = 'local';
    if (env.NODE_ENV === 'production') {
        NEW_ENV = env.NODE_ENV;
    }
    return {
        node: {
            fs: 'empty'
        },
        entry:  path.join(__dirname, "./", "configLoader.js"),
        output: {
            path: path.join(__dirname, "dist"),
            filename: "bundle.js"
        },
        module: {
            loaders: [
                {
                    test: path.join(__dirname, "src"),
                    loader: 'babel-loader',
                    query: {
                        presets: ['es2015']
                    }
                }
            ]
        },
        plugins: [
            new webpack.NormalModuleReplacementPlugin(/config\/local\/config\.json/, function(resource) {
                resource.request = resource.request.replace(/config\/local\/config\.json/, `/config\/${NEW_ENV}\/config\.json`);
            })
        ]
    }
};

File: local/config.json

{
    "environment": "local",
    "homepageUrl": "http://localhost:8080"
}

File: production/config.json

{
    "environment": "production",
    "homepageUrl": "http://www.google.com"
}

I try and run node dist/bundle.js but I get the following error…

➜  03_branching git:(master) ✗ node dist/bundle.js
/Users/jamesmurphy/Development/Repos/clients/PacktPublishing/NodeJsDesignPatterns/Chapter08/exercises/03_branching/dist/bundle.js:73
const config = fs.readFileSync("./config/local/config.json");
                  ^

TypeError: fs.readFileSync is not a function
    at Object.<anonymous> (/Users/jamesmurphy/Development/Repos/clients/PacktPublishing/NodeJsDesignPatterns/Chapter08/exercises/03_branching/dist/bundle.js:73:19)
    at __webpack_require__ (/Users/jamesmurphy/Development/Repos/clients/PacktPublishing/NodeJsDesignPatterns/Chapter08/exercises/03_branching/dist/bundle.js:20:30)
    at /Users/jamesmurphy/Development/Repos/clients/PacktPublishing/NodeJsDesignPatterns/Chapter08/exercises/03_branching/dist/bundle.js:63:18
    at Object.<anonymous> (/Users/jamesmurphy/Development/Repos/clients/PacktPublishing/NodeJsDesignPatterns/Chapter08/exercises/03_branching/dist/bundle.js:66:10)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)

I works if I run

node configLoader.js

But if I run the webpack command:

webpack --env.NODE_ENV=production
node dist/bundle.js

It fails…

Anyone know what’s going on?

None of these suggestions have worked for my env. How is this not fixed?

@majidgh72 Your solution lets webpack bundle the code successfully but when I run the app I get error

Uncaught reference Error: process is not defined

Could someone respond with an explicit file path (ex. node_modules/webpack/package.json) for where I need to add node: { fs: ‘empty’ }, and also include the entire file? I can’t find this magical webpack config file everyone is raving about. I have been struggling for a number of hours trying to get file-system to work and have tried adding node: { fs: ‘empty’ } to a number of places but it doesn’t work.

I’m working in angular 8.0.1

Also, if anyone knows a working alternative to file-system, let me know.

Thanks

mee too

Hi - when I did target: 'node',

the error went away. Then I got global not defined,

so I fixed it with 'global': {}, in webpack.definePlugin({...})

Then I got a GetEnv error saying SERVER_HOST not defined… but it is… so there’s a slew of errors that I’m swimming in - I hope someone can take a look at my boilerplate and give me hand? Thank you!

Modify webpack.config.js:

var path = require('path');

module.exports = {
  entry: './src/main.js',
  target: 'node',
  output: {
    path: path.join(__dirname, 'build'),
    filename: 'backend.js'
  }
}

Refer here

This link may help you.

  resolve: {
    modules: ['app', 'node_modules'],
    extensions: [
      '.js',
      '.jsx',
      '.react.js',
    ],
    mainFields: [
      'browser',
      'jsnext:main',
      'main',
    ],
  },
  node: { fs: 'empty' },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
  performance: options.performance || {},
});

@justinstander Here’s my settled-upon solution:

I keep a file one directory above my project that contains my relevant env vars in JSON format.

In my webpack.prod.config.js file, I perform the following code:

var fs = require('fs');

var config = JSON.parse(fs.readFileSync('../env-vars.env'));

module.exports = {
  ...
  plugins: [
    new webpack.DefinePlugin({
      'USER_URL': JSON.stringify(config.userURL),
      'DATA_URL': JSON.stringify(config.dataURL)
    })

In my code, I use these vars like so:

export const CONFIG = {
  ...
  userURL: USER_URL || 'https://localhost',
  dataURL: DATA_URL || 'https://localhost'
};

This works for me in my environment. My sensitive data is kept in a file outside the project. Node gets to use fs to import that data, and WebPack gets to supply it in global vars. Those vars are not exposed on the window object.

I hope this helps you with your project!

@J-Gallo Thank you so much!

next.config.js

module.exports = {
  webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
    config.node = {
      fs: 'empty',
      module: "empty",
    };
    return config;
  },
};

I just had to add the module: "empty", as well.

I got it to work when I added the following element inside module.exports in my webpack.config file

node: {
        fs: 'empty'
},

Why is this issue closed? I just spent the last two days racking my brains, until I finally stumbled upon this bug report with a lucky combination of search keywords. The workaround seems like a really bad one. Will we see a fix?

@samayo I fixed the issue adding it to the karma.conf.js file. The file’s content is now like this:

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular/cli'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular/cli/plugins/karma')
    ],
    files: [
      { pattern: './config.json', watched: false }
    ],
    exclude: [
      './config.json'
    ],    
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      reports: ['html', 'lcovonly'],
      fixWebpackSourcePaths: true
    },
    angularCli: {
      config: './angular-cli.json',
      environment: 'dev'
    },
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false,
    webpack: {
      node: {
        fs: "empty"
      }
    }
  });
};

As you can see, at the end of the file, I added a new webpack entry and inside it the mentioned solution.

For Webpack 4, you need to add this in webpack.config.js:

module.exports = {
  node: {
    fs: 'empty',
  },
}

For Webpack 5, you need to add this in webpack.config.js (upgrade to v5):

module.exports = {
  resolve: {
    fallback: {
      fs: false,
    },
  },
}

So, this is for webpack 4 users. Maybe it might help others who bump into this thread. There is a configuration param called target. So this resolves the ‘fs’ error in webpack

When i use fs as empty , there is no way for the bundled code to know /access fs modules of nodejs and that becomes a problem when we use it elsewhere in the code. So atleast I definitely do not recommend the fs:empty usage as suggested above

module.exports = {
	entry: './src/index.ts',
	  mode: 'production',
	  **target: 'node',**
	  module: {
		rules: [
		  {
			test: /\.ts$/,
			use: [
			  'ts-loader',
			],
			exclude: /node_modules/,

		  },
		  
		]
	   
	  },
	....
..
};

And here is my tsconfig. The module config is set to commonjs and target to es2015

{```

“compilerOptions”: { “module”: “commonjs”, “declaration”: true, “removeComments”: true, “emitDecoratorMetadata”: true, “experimentalDecorators”: true, “target”: “es2015”, “noErrorTruncation”: true, “allowJs”: true, “esModuleInterop”: true, “allowSyntheticDefaultImports”: true, “lib”: [“ES2015”, “ES2016”, “ES2018”, “ES2019”, “ES2020”, “ESNext”], “sourceMap”: true, “rootDir”: “./src”, “outDir”: “./dist”, “baseUrl”: “./”, “declarationMap”: true,
}, “include”: [“src/**/*.ts”], “exclude”: [“node_modules”, “dist”, “test”], “compileOnSave”: true }

For those of you using Nuxt.js for Vue.s server-side rendering, webpack can be extended as follows:

nuxt.config.js

module.exports = {
  ...
  build: {
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        ...
        config.node = {
          fs: 'empty'
        }
      }
    }
  }
}

However, if you need fs for any reason, you may run into the same issues as mentioned above and require further workarounds

npm install fs --save doesn’t seem to have any affect in my case. https://webpack.js.org/configuration/target/ hints I should be using target: 'web'. This gives me Can’t resolve ‘fs’. node: { fs: "empty", } gives me _fs2.default.readFileSync is not a function. Changing to target: 'node' gives me require is not defined (people also mentioning this in comments here.

Oops, I’ve been trying to run a node module in the browser to do some validation. Of course, the browser doesn’t have file system access. In the end I just ran build on the node module and import or require the /dist .js file

package.json add

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

@vijayakumar-psg587 so the fix for you was this

The module config is set to commonjs and target to es2015

?

Came across this issue while playing with worker-loader, but the related issues in worker-loader are all marked as fixed. I just tried adding the node: { fs: 'empty' } trick, but also had to add module: ‘empty’ to it to get that to work.

This seems to work, but has caused a four-fold increase in bundle size for the browser 😮 zero increase in the same module built for node.

This dependency was not found:
* fs in ./node_modules/fs-extra/lib/index.js, ./node_modules/fs-extra/lib/empty/index.js and 2 others

To install it, you can run: npm install --save fs

wait for me to give a test repo

@bebraw With your fix of this issue, I have a Uncaught ReferenceError: Buffer is not defined in the lib/convert-source-map.js file, in the browser.

Thanks @majidgh72, the migration to webpack 5 talks about fs as a fallback.

https://webpack.js.org/migrate/5/

Please provide minimum reproducible test repo

after adding {fs: ‘empty’} I get this: external_"url":1 Uncaught ReferenceError: require is not defined at eval (external_"url":1) at Object.url (bundle.js:1065) at __webpack_require__ (bundle.js:683) at fn (bundle.js:60) at Object.eval (webpack:///(:8080/webpack)-dev-server/client?:6:11) at eval (webpack:///(:8080/webpack)-dev-server/client?:249:30) at Object../node_modules/webpack-dev-server/client/index.js?http://0.0.0.0:8080 (bundle.js:763) at __webpack_require__ (bundle.js:683) at fn (bundle.js:60) at eval (webpack:///multi_(:8080/webpack)-dev-server/client?:1:1)

@samayo I’m not sure what I got could help you.

I fix this error by installing node-sass into devDenpendency, if I install node-sass into denpendency, I will get this error, I’m not sure you use node-sass or not, you can check some packages in denpendency and devDenpendency