title: Use fs module in React.js,node.js, webpack, babel,express
body: <p>I have a requirement in which I am rendering view in which I display a form. On submit of form i need to gather the form data and create a file and save form data as JSON in that file. I am using React.js, node.js, babel and webpack.</p>
  
  <p>After struggling a bit to achieve this I figured out that I have to use isomorphic or universal javascript i.e use react and render on server side as we cannot use fs module on client side.
  <a href="https://scotch.io/tutorials/react-on-the-server-for-beginners-build-a-universal-react-and-node-app" rel="noreferrer">Referred this for server side</a>.</p>
  
  <p>i run it using: <code>npm run start</code></p>
  
  <p>After this I can see in console that <code>[Object Object]</code> is printed on console from Line 1 in below react component (HomePage.js). But later on when I access this page it gives an error:</p>
  
  <blockquote>
    <p>'bundle.js:18 Uncaught Error: Cannot find module "fs"'</p>
  </blockquote>
  
  <p><strong>How can i use fs module with react ?</strong></p>
  
  <p>Below are code snippets :</p>
  
  <p><strong>webpack.config.js</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>"use strict";
  
  const debug = process.env.NODE_ENV !== "production";
  
  const webpack = require('webpack');
  const path = require('path');
  
  module.exports = {
    devtool: debug ? 'inline-sourcemap' : null,
    entry: path.join(__dirname, 'src', 'app-client.js'),
    devServer: {
      inline: true,
      port: 3333,
      contentBase: "src/static/",
      historyApiFallback: true
    },
    output: {
      path: path.join(__dirname, 'src', 'static', 'js'),
      publicPath: "/js/",
      filename: 'bundle.js'
    },
    module: {
      loaders: [{
        test: path.join(__dirname, 'src'),
        loader: ['babel-loader'],
        query: {
          //cacheDirectory: 'babel_cache',
          presets: debug ? ['react', 'es2015', 'react-hmre'] : ['react', 'es2015']
        }
      }]
    },
    plugins: debug ? [] : [
      new webpack.DefinePlugin({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
      }),
      new webpack.optimize.DedupePlugin(),
      new webpack.optimize.OccurenceOrderPlugin(),
      new webpack.optimize.UglifyJsPlugin({
        compress: { warnings: false },
        mangle: true,
        sourcemap: false,
        beautify: false,
        dead_code: true
      }),
    ]
  };</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>package.json</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>{
    "name": "sample",
    "version": "1.0.0",
    "description": "Simple application to showcase how to achieve universal rendering and routing with React and Express.",
    "main": "src/server.js",
    "scripts": {
      "start": "SET NODE_ENV=production&amp;&amp;babel-node src/server.js",
      "start-dev": "npm run start-dev-hmr",
      "start-dev-single-page": "node_modules/.bin/http-server src/static",
      "start-dev-hmr": "webpack-dev-server --progress --inline --hot",
      "build": "SET NODE_ENV=production&amp;&amp;webpack -p"
    },
    "dependencies": {
      "babel-cli": "^6.11.4",
      "babel-core": "^6.13.2",
      "babel-loader": "^6.2.5",
      "babel-plugin-react-html-attrs": "^2.0.0",
      "babel-preset-es2015": "^6.13.2",
      "babel-preset-react": "^6.11.1",
      "babel-preset-react-hmre": "^1.1.1",
      "ejs": "^2.5.1",
      "express": "^4.14.0",
      "react": "^15.3.1",
      "react-dom": "^15.3.1",
      "react-router": "^2.6.1"
    },
    "devDependencies": {
      "http-server": "^0.9.0",
      "react-hot-loader": "^1.3.0",
      "webpack": "^1.13.2",
      "webpack-dev-server": "^1.14.1"
    }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>server.js</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>use strict';
  
  import path from 'path';
  import { Server } from 'http';
  import Express from 'express';
  import React from 'react';
  import { renderToString } from 'react-dom/server';
  import { match, RouterContext } from 'react-router';
  import routes from './routes';
  import NotFoundPage from './components/NotFoundPage';
  //import fs from 'fs';
  
  //console.log("server" + fs);
  // initialize the server and configure support for ejs templates
  const app = new Express();
  const server = new Server(app);
  app.set('view engine', 'ejs');
  app.set('views', path.join(__dirname, 'views'));
  
  // define the folder that will be used for static assets
  app.use(Express.static(path.join(__dirname, 'static')));
  
  // universal routing and rendering
  app.get('*', (req, res) =&gt; {
    match(
      { routes, location: req.url },
      (err, redirectLocation, renderProps) =&gt; {
  //console.log("renderProps "+ Object.values(routes));
  //console.log("req.url "+ req.url);
        // in case of error display the error message
        if (err) {
          return res.status(500).send(err.message);
        }
  
        // in case of redirect propagate the redirect to the browser
        if (redirectLocation) {
          return res.redirect(302, redirectLocation.pathname + redirectLocation.search);
        }
  
        // generate the React markup for the current route
        let markup;
        if (renderProps) {
          // if the current route matched we have renderProps
          markup = renderToString(&lt;RouterContext {...renderProps}/&gt;);
        } else {
          // otherwise we can render a 404 page
          markup = renderToString(&lt;NotFoundPage/&gt;);
          res.status(404);
        }
  
        // render the index template with the embedded React markup
        return res.render('index', { markup });
      }
    );
  });
  
  // start the server
  const port = process.env.PORT || 3000;
  const env = process.env.NODE_ENV || 'production';
  console.log(`Server starting on http://localhost:${port} [${env}]`)
  server.listen(port, err =&gt; {
    if (err) {
      return console.error(err);
    }
    console.info(`Server running on http://localhost:${port} [${env}]`);
  });</code></pre>
  </div>
  </div>
  </p>
  
  <p>HomePage.js (React component)</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import React from 'react';
  import fs from 'fs';  
  import dateformat from 'dateformat';
  console.log("home page" + fs);  -- Line 1
  class HomePage extends React.Component{
   checkDirectory(directory, callback) {
      fs.stat(directory, function(err, stats) {
        //Check if error defined and the error code is "not exists"
        if (err &amp;&amp; err.errno === 34) {
          //Create the directory, call the callback.
          fs.mkdir(directory, callback);
        } else {
          //just in case there was a different error:
          callback(err)
        }
      });
    }
   handleClick(){
  
  
      var obj = JSON.stringify($('#statusForm').serializeArray());
      
      this.checkDirectory("directory/"+currentDate, function(error) {
        if(error) {
          console.log("oh no!!!", error);
        } else {
          //Carry on, all good, directory exists / created.
          fs.writeFile("directory/"+currentDate+name+".json", obj, function(err) {
          if(err) {
              return console.log(err);
          }
  
          console.log("The file was saved!");
          });
          console.log("exists");
        }
      });*/
  
    }
    render() {
      return (
        &lt;div className="container"&gt;
  
      &lt;form id="statusForm" className="form-horizontal" &gt;
        &lt;div className="form-group"&gt;
          &lt;label className="control-label col-sm-2" for="names"&gt;Select list:&lt;/label&gt;
          &lt;div className="col-sm-10"&gt;
            &lt;select name="names" className="form-control" id="names"&gt;
              &lt;option&gt;Select&lt;/option&gt;
              &lt;option&gt;abc&lt;/option&gt;
              &lt;option&gt;xyz&lt;/option&gt;
            &lt;/select&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className="form-group"&gt;
          &lt;label className="control-label col-sm-2" for="team"&gt;Select list:&lt;/label&gt;
          &lt;div className="col-sm-10"&gt;
            &lt;select name="team" className="form-control" id="team"&gt;
              &lt;option&gt;Select&lt;/option&gt;
              &lt;option&gt;team 1&lt;/option&gt;
              &lt;option&gt;team 2&lt;/option&gt;
            &lt;/select&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className="form-group"&gt;
          &lt;label className="control-label col-sm-2" for="pwd"&gt;Password:&lt;/label&gt;
          &lt;div className="col-sm-10"&gt;
            &lt;input type="textarea" className="form-control" id="todayTask" name="todayTask" placeholder="Enter Task"/&gt;
          &lt;/div&gt;
        &lt;/div&gt;
        &lt;div className="form-group"&gt;
          &lt;div className="col-sm-offset-2 col-sm-10"&gt;
            &lt;button type="button" className="btn btn-default" onClick={this.handleClick.bind(this)}&gt;Submit&lt;/button&gt;
          &lt;/div&gt;
        &lt;/div&gt;
      &lt;/form&gt;
    &lt;/div&gt;
      );
    }
  }
  
  
  export default HomePage;</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>EDIT 1:</strong></p>
  
  <p>I investigated more and found out that if i do not build my app explicitly using npm run build and just update my react component i do not get above error.
  Also, after this if i put file creation logic directly inside render method and on refreshing page it successfully create a file.
  So observation is it does not work with Onclick of button and can work if we refresh the page. it goes to server and thats why it works this way.</p>
  
  <p><strong>EDIT 2:</strong></p>
  
  <p>Page refresh issue resolved by using target:'node' in my webpack config but I do get the error:</p>
  
  <blockquote>
    <p>Uncaught ReferenceError: require is not defined</p>
  </blockquote>
  
  <p>In browser.so file creation logic directly inside render method will create the file the moment we access the page. No refresh required.</p>
  
  <p><strong>Can anyone guide me what is the best way to achieve my desired requirement?</strong> </p>