Can't resolve 'fs' using webpack and react

16,389

Solution 1

You can't use any modules that come with the Node Core API in the browser, they just won't work there. Node Core Modules rely on C/C++ binaries which won't be present in the browser. So you'll need to find an equivalent approach to replacing any fs use in your react app.

One approach would be to serve the file you want to work with over HTTP via a Node JS backend to your React app. You could read the file using fs in your Node server, and place that logic within a route, call that route from your React App via HTTP and stream it back. Then you will have the file data within your React App and can work with it as you need.

This GitHub repo has a listing of Node Core Libraries that Webpack has ported over for browser usage. Unfortunately fs isn't one of them.

Solution 2

Add in package.json

  "browser": {
    "crypto": false,
    "fs": false,
    "path": false,
    "os": false,
    "net": false,
    "stream": false,
    "tls": false
    },

Add in webpack:

node: { fs: 'empty' },
  devtool: options.devtool,
  target: 'web', // Make web variables accessible to webpack, e.g. window
Share:
16,389

Related videos on Youtube

Jenna
Author by

Jenna

Updated on June 04, 2022

Comments

  • Jenna
    Jenna about 2 years

    I keep getting the error in the description when I try to build my application for my Node server.

    I am ultimately trying to read a .docx file for docxtemplater, but without 'fs' working, it's not looking to bright.

    I have tried to use the node:{fs:"empty"} workaround that I've seen on many solutions, but it's still giving me the same error or propagating up to the console when I am running it on the browser.

    Here is what I have in my webpack.config.js:

    var path = require('path');
    var webpack = require('webpack');
    //var HtmlWebpackPlugin = require('html-webpack-plugin');
    var UglifyJsPlugin = require('uglifyjs-webpack-plugin');
    var DashboardPlugin = require('webpack-dashboard/plugin');
    
    const sourcePath = path.join(__dirname, './front_end');
    const buildPath = path.join(__dirname, './src/bin');
    
    module.exports = {
        devtool: 'source-map',
        //home directory for webpack must be absolute
        //context: sourcePath,
        //Application Execution and Webpack Bundling
        entry: {
            js: path.join(sourcePath, 'index.js')
            //html: './index.html',
        },
        output: {
            //Must be absolute path
            path: sourcePath,
            //publicPath: buildPath,
            //publicPath: path.join(__dirname, '/src/bin'),
            filename: "bundle.js"
        },
    
        resolve: {
            extensions: [
                '.webpack-loader.js',
                '.web-loader.js',
                '.loader.js',
                '.js',
                '.jsx'
            ],
            modules: [
                path.join(__dirname),
                "node_modules"
            ],
        },
        module: {
            rules: [
                {
                    test: /\.js$|\.jsx$/,
                    exclude: /node_modules/,
                    use: [
                        "babel-loader",
                        "eslint-loader",
                    ]
                },
                {
                    test: /\.html/,
                    exclude: /node_modules/,
                    use: [
                        "file-loader",
                    ]
                },
                {
                    test: /\.css/,
                    exclude: /node_modules/,
                    use: [
                        "style-loader",
                        'css-loader'
                    ]
                },
                {
                    test: /\.(gif|png)/,
                    exclude: /node_modules/,
                    use: [
                        "url-loader"
                    ]
                }
            ],
            loaders: [
                {
                    test: /\.js$|\.jsx$/,
                    loader: 'babel-loader',
                    exclude: /node_modules/,
                    query: {
                        presets: ['es2016', 'react']
                    }
                },
                {
                    test: /\.css$/,
                    loader: 'style-loader',
                    use: ['style-loader', 'css-loader'],
                    exclude: /node_modules/
                },
                {
                    test: /\.html$/,
                    loader: "file?name=[name].[ext]"
                },
                {
                    test: /\.(jpe?g|png|gif|svg)$/i,
                    loaders: [
                        'file?hash=sha512&digest=hex&name=[hash].[ext]',
                        'image-webpack?bypassOnDebug&optimizationLevel=7&interlaced=false'
                    ]
                }
            ]
        },
        plugins: [
         ],
        stats: {
            assets: true,
            colors: true,
            errors: true,
            errorDetails: true,
            hash: true,
        }
    };
    
    • Mike 'Pomax' Kamermans
      Mike 'Pomax' Kamermans over 6 years
      There is no "file system" to load data from, so if you need that data on the web, either rewrite your logic so you can ask for that data by calling your server, use the browser's ability to load assets through <img> and <link> etc. or use a special loader that lets you bundle them in.
  • jeyko
    jeyko over 3 years
    node: { fs: 'empty' } no longer works in webpack 5
  • RancheroBeans
    RancheroBeans about 3 years
    This was a helpful pattern for me @peteb -- thank you :)