Skip to content
Advertisement

Webpack : Cannot read property ‘readFile’ of undefined, No output files

Using webpack > 5 version. Below is my appDevMiddleware.jscongifuration

const path = require('path');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const webpackHotMiddleware = require('webpack-hot-middleware');

function createWebpackMiddleware(compiler, publicPath) {
return webpackDevMiddleware(compiler, {
    // noInfo: true,
    publicPath,
    // silent: true,
    stats: 'errors-only',
});
}

module.exports = function addDevMiddlewares(app, webpackConfig) {
const compiler = webpack(webpackConfig);
const middleware = createWebpackMiddleware(compiler, webpackConfig.output.publicPath);

app.use(middleware);
app.use(webpackHotMiddleware(compiler));

// Since webpackDevMiddleware uses memory-fs internally to store build
// artifacts, we use it instead
const fs = middleware.fileSystem;

app.get('*', (req, res) => {
    fs.readFile(path.join(compiler.outputPath, 'index.html'), (err, file) => {
    if (err) {
        res.sendStatus(404);
    } else {
        res.send(file.toString());
    }
    });
});
};

When i do npm start of my React App, i’m getting

TypeError: Cannot read property 'readFile' of undefined
at D:master-instore-dashboardservermiddlewaresaddDevMiddlewares.js:29:8

This is exactly showing here

fs.readFile(path.join(compiler.outputPath, 'index.html'), (err, file) => {

I will have to somehow use the promises for readFile which is something like const { readFile } = require('fs').promises

How should i replace const fs = middleware.fileSystem; with promise for this issue?

Advertisement

Answer

webpack-dev-middleware uses memfs as its default outputFileSystem. WDM didn’t expose the API so that you can NOT get the outputFileSystem from the instance of WDM. That’s why you got that error.

You should create your own outputfilesystem, you can use the memfs to do that explicitly. Then, you can get the index.html from the memory file system.

You can use util.promisify() method from util Node.js built-in module to promisify the fs.readFile method.

E.g.

webpack.config.js:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  entry: path.resolve(__dirname, "src/index.js"),
  output: {
    path: path.resolve(__dirname, "dist"),
    filename: "bundle.js",
  },
  plugins: [new HtmlWebpackPlugin({ template: "./src/index.html" })],
  mode: "development",
};

app.js:

const path = require("path");
const util = require("util");
const express = require("express");
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const { createFsFromVolume, Volume } = require("memfs");
const webpackConfig = require("./webpack.config");

const compiler = webpack(webpackConfig);
const app = express();
const fs = createFsFromVolume(new Volume());
fs.join = path.join.bind(path);
const readFile = util.promisify(fs.readFile);

const middleware = webpackDevMiddleware(compiler, {
  publicPath: webpackConfig.output.publicPath,
  stats: "errors-only",
  outputFileSystem: fs,
});
app.use(middleware);

app.get("*", async (req, res) => {
  try {
    const file = await readFile(path.join(compiler.outputPath, "index.html"));
    res.send(file.toString());
  } catch (error) {
    res.sendStatus(404);
  }
});

app.listen(3000, () => console.log("Example app listening on port 3000!"));

Start the server:

⚡  node app.js                                                                                              
Example app listening on port 3000!

Access http://localhost:3000/test:

⚡  curl http://localhost:3000/test                                                <!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
<script defer src="bundle.js"></script></head>

<body>

</body>

</html>

package version:

{
  "name": "68618902",
  "devDependencies": {
    "html-webpack-plugin": "^5.3.2",
    "memfs": "^3.2.2",
    "webpack": "^5.51.1",
    "webpack-dev-middleware": "^5.0.0"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement