Module not found: Error: Can't resolve 'fs' Using Webpack
Asked Answered
E

3

13

Hi im using socket io in my application. Which is requiring fs. when i try to bundle my javascript using below webpack config. im getting error can not resolve 'fs'.

Module not found: Error: Can't resolve 'fs' in 'my application path/node_modules/socket.io/lib'

i found by adding target:'node' and node:{fs:'empty'}. this issue got resolved.

But there is an issue in sass-loader. Getting below error.

ERROR in javascript/bundle.js from UglifyJs
Unexpected token: name (zlibLimiter) [javascript/bundle.js:60019,4]
Child extract-text-webpack-plugin ../../../node_modules/extract-text-webpack-plugin/dist ../../../node_modules/css-loader/index.js??ref--2-2!../../../node_modules/sass-loader/lib/loader.js!s

running the application ignoring above error. getting below error.

external "crypto":1 Uncaught ReferenceError: require is not defined
    at Object.__decorate (external "crypto":1)
    at __webpack_require__ (bootstrap 93620a17882f7a2aa1d3:19)
    at Object.byteToHex (rng.js:4)
    at __webpack_require__ (bootstrap 93620a17882f7a2aa1d3:19)

Below is my webpack config and versions. Can some one please help me to resolve this issue.

"webpack": "~3.6.0", npm -v 5.8.0 node -v v8.4.0

const webpack = require('webpack');
const env = process.env.NODE_ENV;
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const extractSass = new ExtractTextPlugin({
  filename: 'css/[name].css',
  allChunks: false
});


let output = {
  path: __dirname + '/src/main/resources/static/',
  filename: 'javascript/[name].js'
};

if (env === 'debug' || env === 'nondev') {
  output = {
    path: __dirname + '/target/classes/static/',
    filename: 'javascript/[name].js'
  };
}

let config = {
  context: __dirname + '/app/js/src',
  entry: {
    bundle: './index.jsx',
    application: './static/scss/application.scss',
    'application-pdap': './static/scss/application-pdap.scss'
  },
  output: output,
  devtool: 'cheap-module-source-map',
  module: {
    rules: [
      {
        test: /.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
        query: {presets: ['es2015', 'react']}
      },
      {
        test: /\.(woff|woff2|eot|ttf|svg|png|jpg|gif)$/,
        loader: 'file-loader?limit=1024&name=images/[name].[ext]'
      },
      {
        test: /\.(scss|css)$/,
        include: [path.resolve(__dirname, 'app/js/src/static/scss')],
        use: ExtractTextPlugin.extract({
          publicPath: '../',
          use: [
            {
              loader: 'css-loader',
              options: {
                minimize: true,
                sourceMap: false
              }
            },
            {loader: 'sass-loader'}
          ],
          fallback: 'style-loader'
        })
      }
    ]
  },
  plugins: [extractSass],

};

if (env === 'production' || env === 'nondev') {
  config.devtool = 'nosources-source-map';

  config.plugins.push(
    new webpack.DefinePlugin({
      'process.env': {NODE_ENV: '"production"'}
    })
  );

  config.plugins.push(new webpack.optimize.UglifyJsPlugin({
    compress: {warnings: false},
    comments: false,
    sourceMap: false,
    minimize: false
  }));
}

module.exports = config;
Earthaearthborn answered 20/4, 2018 at 0:39 Comment(1)
You should accept the submitted answer or explain why it didn't work for youBorghese
M
9

The solution depends on the type of application you want to build. Usually front-end and back-end JavaScript code are bundled separately, effectively creating two output bundles.

Front-end

For a frontend/web project, add the socket.io client libary to your app bundle. There is no need to include any node dependencies (fs) or mock entries like node: { fs:'empty' }. You can choose target:'web' or leave it out, as it is the default.

Back-end

Pick target:'node' and install socket.io server library. You do not need to specify externals: ["fs"] as shown in the other answer, because target: 'node' will take care of not bundling path, fs and other built-in modules.

Better avoid npm i fs - this is a needless escape hatch and a security risk. There have already happened cases of malicious npm packages with common package names.

You could even deliberate about, wether a node backend bundle is needed at all. An alternative is to install webpack-node-externals, which treats either all or specific npm packages as "externals" and excludes them from the bundle:

var nodeExternals = require('webpack-node-externals');

module.exports = {
  target: 'node', // ignore built-in modules like path, fs, etc.
  externals: [nodeExternals()], // ignore all modules in node_modules folder
  // ...
};

This makes sense for the back-end, as all dependencies are installed in node_modules at server start time and don't need to be included in the bundle.

Exclude files from loaders

To exclude files from certain loaders and their transformations, you can use exclude module rule. An example is to omit node_modules from babel-loader transformations:

{ test: /\.(jsx|js)$/, exclude: /node_modules/, loader: "babel-loader" }

Further reading

Mccready answered 15/8, 2019 at 16:54 Comment(3)
This is a much better solution!Endear
To anyone interested in loading socket.io in the browser, the solution is to use the socket.io-client module which doesn't require fsWeatherworn
correct answer imoMerci
M
2

Just install fs (npm i fs), and add at your webpack config

externals: ["fs"],
Mediation answered 6/7, 2018 at 7:4 Comment(6)
Isn't fs available by default? Why npm i fs ?Miun
This error occurs while webpack trying to retrive socket.io module., and search requred libs at current socket.io catalog. And if You do not have fs installed at current projects directory, you should install it.Mediation
Not sure that this is safe to do anymore. Note from NPM: "This package name is not currently in use, but was formerly occupied by another package. To avoid malicious use, npm is hanging on to the package name, but loosely, and we'll probably give it to you if you want it."Sallysallyann
Best working answer IMO, as it does not require loading node.Borghese
Doesn't work any more "Uncaught ReferenceError: fs is not defined at eval (external "fs"?a40d:1)"Huber
Downvoted, this seems like a very bad advice. At best, it's a shady workaround, at worse, it's a security issue.Woolfell
S
1

If someone is still facing this issue, you can try the following workaround. Update your webpack file to including the following configuration:

node: {
    fs: 'empty',
}

We had a similar issue within our project and adding this specific configuration resolved the 'fs' related error in webpack. It's also worth checking the version of Webpack version. we had to revert back the webpack and webpack cli versions to 4.0.0 and 4.2.0 respectively.

Severally answered 29/11, 2020 at 15:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.