I am trying to deploy a simple react app, built with webpack, on Heroku but I am getting this error: [![enter image description here][1]][1]
While on local it runs without any problem. When running the command heroku logs --tail --app myApp I get these logs, where in the end it still says Build succeeded + error webpack not found:
2021-09-23T16:43:10.842485+00:00 app[web.1]: sh: 1: webpack: not found
2021-09-23T16:43:10.847661+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2021-09-23T16:43:10.847852+00:00 app[web.1]: npm ERR! syscall spawn
2021-09-23T16:43:10.847936+00:00 app[web.1]: npm ERR! file sh
2021-09-23T16:43:10.848030+00:00 app[web.1]: npm ERR! errno ENOENT
2021-09-23T16:43:10.852550+00:00 app[web.1]: npm ERR! assessment@1.0.0 start: `webpack serve --config ./webpack.config.js --mode development`
2021-09-23T16:43:10.852592+00:00 app[web.1]: npm ERR! spawn ENOENT
2021-09-23T16:43:10.852656+00:00 app[web.1]: npm ERR!
2021-09-23T16:43:10.852708+00:00 app[web.1]: npm ERR! Failed at the assessment@1.0.0 start script.
2021-09-23T16:43:10.852755+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
2021-09-23T16:43:10.855613+00:00 app[web.1]:
2021-09-23T16:43:10.855700+00:00 app[web.1]: npm ERR! A complete log of this run can be found in:
2021-09-23T16:43:10.855749+00:00 app[web.1]: npm ERR! /app/.npm/_logs/2021-09-23T16_43_10_853Z-debug.log
2021-09-23T16:43:10.969506+00:00 heroku[web.1]: Process exited with status 1
2021-09-23T16:43:11.000000+00:00 app[api]: Build succeeded
2021-09-23T16:43:11.025930+00:00 heroku[web.1]: State changed from starting to crashed
2021-09-23T16:43:11.099764+00:00 heroku[web.1]: State changed from crashed to starting
2021-09-23T16:43:12.966234+00:00 heroku[web.1]: Starting process with command `npm start`
2021-09-23T16:43:13.949091+00:00 app[web.1]:
2021-09-23T16:43:13.949101+00:00 app[web.1]: > assessment@1.0.0 start /app
2021-09-23T16:43:13.949102+00:00 app[web.1]: > webpack serve --config ./webpack.config.js --mode development
2021-09-23T16:43:13.949102+00:00 app[web.1]:
2021-09-23T16:43:13.953260+00:00 app[web.1]: sh: 1: webpack: not found
2021-09-23T16:43:13.956297+00:00 app[web.1]: npm ERR! code ELIFECYCLE
2021-09-23T16:43:13.956485+00:00 app[web.1]: npm ERR! syscall spawn
2021-09-23T16:43:13.956570+00:00 app[web.1]: npm ERR! file sh
2021-09-23T16:43:13.956655+00:00 app[web.1]: npm ERR! errno ENOENT
2021-09-23T16:43:13.959694+00:00 app[web.1]: npm ERR! assessment@1.0.0 start: `webpack serve --config ./webpack.config.js --mode development`
2021-09-23T16:43:13.959750+00:00 app[web.1]: npm ERR! spawn ENOENT
2021-09-23T16:43:13.959805+00:00 app[web.1]: npm ERR!
2021-09-23T16:43:13.959848+00:00 app[web.1]: npm ERR! Failed at the assessment@1.0.0 start script.
2021-09-23T16:43:13.959888+00:00 app[web.1]: npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
It seems that somehow it cannot find the webpack dependency.
This is my webpack:
const webpack = require('webpack');
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: path.resolve(__dirname, './src/index.js'),
module: {
rules: [
// React loader
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: ['babel-loader']
},
// css loader
{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
},
// Images loader
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
// SVG loader
{
test: /\.svg$/,
use: [
{
loader: 'svg-url-loader',
options: {
limit: 10000,
},
},
],
},
]
},
resolve: {
extensions: ['*', '.js', '.jsx'],
},
output: {
path: path.resolve(__dirname, './build'),
filename: 'bundle.js',
},
plugins: [
new HtmlWebpackPlugin({
title: 'Founders Lair Assessment',
filename: 'index.html',
template: path.resolve(__dirname, './src/public/index.html'),
inject: 'body'
}),
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: path.resolve(__dirname, './build'),
port: 3000,
hot: true
},
};
This is my package.json:
"scripts": {
"start": "webpack serve --config ./webpack.config.js --mode development",
"predeploy": "npm run build",
"deploy": "gh-pages -d build",
"build": "webpack --mode production",
"heroku-prebuild": "npm install --dev"
},
"keywords": [],
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.12.10",
"@babel/preset-env": "^7.12.11",
"@babel/preset-react": "^7.12.10",
"antd": "^4.9.4",
"axios": "^0.21.0",
"babel-loader": "^8.2.2",
"css-loader": "^5.0.1",
"file-loader": "^6.2.0",
"gh-pages": "^3.1.0",
"html-webpack-plugin": "^5.0.0-beta.1",
"lodash": "^4.17.10",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-hot-loader": "^4.13.0",
"style-loader": "^2.0.0",
"svg-url-loader": "^7.1.1",
"webpack": "^5.11.0",
"webpack-cli": "^4.2.0",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"dotenv": "^8.2.0"
}
Any idea how to fix this issue? [1]: https://i.sstatic.net/khbm0.png
The problem is that the heroku container does not know how to serve your project by default. You need to install a local server so that your files can be requested. As such, you need to do the following:
add express as a dependency. your package.json file should have express under "dependencies", like so: "express": "^4.18.1" (don't forget the comma at the end, if needed)
you will then need a server.js file with the following content:
const express = require('express') const path = require('path');
const app = express() const port = process.env.PORT || 3000
app.use(express.static(path.join(__dirname, 'build')));
the start script in package.json should be "node server.js"
now deploy all this to heroku and it should work
PS: or if you don't like this approach (although imo it is the cleanest), then you probably need to add webpack as a dependency (and not devDependency) and it will probably work but it's not recommended to use dev configs in production.