Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Express/Webpack failing on dokku and heroku

Procfile:

build: npm run prod
web: nodemon server.js

Package.json

  "scripts": {
    "prod": "NODE_ENV=production webpack -p --config ./webpack.prod.config.js --progress --optimize-dupe"
  }

Webpack.prod.config:

var path = require('path');
var webpack = require('webpack');

module.exports = {
  devtool: null,
  entry: [
    './assets/js/index'
  ],
  output: {
    path: path.join(__dirname, 'public/dist/'),
    filename: 'bundle.js',
    publicPath: '/public/'
  },
  plugins: [
    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      compress: {
        warnings: false
      }
    }),
    new webpack.DefinePlugin({
      'process.env': { NODE_ENV: '"production"' }
    })
  ],
  module: {
    loaders: [
      {
        test: /\.js$/,
        loader: 'babel',
        include: path.join(__dirname, 'assets/js'),
        exclude: path.join(__dirname, 'node_modules/')
      },
      {
        test: /\.css$/,
        include: path.join(__dirname, 'assets/css'),
        loader: 'style-loader!css-loader'
      }
    ]
  }
}

Server.js:

var path = require('path'),
    express = require('express'),
    app = express(),
    port = process.env.PORT || 5000

app.use(express.static(path.join(__dirname, 'public')))

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname + '/index.html'))
})

var server = app.listen(port, function() {
    var host = server.address().address
    console.log('Listening at http://%s:%s', host, port)
})

Errors:

Dokku, 502 Bad Gateway:

2016/03/03 22:43:12 [error] 5419#0: *303 connect() failed (111: Connection refused) while connecting to upstream, client: 185.49.14.190, server: xxx.xxx, request: "GET http://testp3.pospr.waw.pl/testproxy.php HTTP/1.1", upstream: "http://172.17.0.4:5000/testproxy.php", host: "testp3.pospr.waw.pl"
2016/03/03 23:54:58 [error] 5419#0: *305 connect() failed (111: Connection refused) while connecting to upstream, client: 185.49.14.190, server: xxx.xxx, request: "GET http://testp4.pospr.waw.pl/testproxy.php HTTP/1.1", upstream: "http://172.17.0.4:5000/testproxy.php", host: "testp4.pospr.waw.pl"
2016/03/04 00:55:35 [error] 5419#0: *307 connect() failed (111: Connection refused) while connecting to upstream, client: 207.46.13.22, server: xxx.xxx, request: "GET /robots.txt HTTP/1.1", upstream: "http://172.17.0.4:5000/robots.txt", host: "artempixel.com.br"
2016/03/04 00:55:41 [error] 5419#0: *309 connect() failed (111: Connection refused) while connecting to upstream, client: 207.46.13.22, server: xxx.xxx, request: "GET / HTTP/1.1", upstream: "http://172.17.0.4:5000/", host: "artempixel.com.br"

There are no errors from Heroku's logs, only on the frontend:

Uncaught SyntaxError: Unexpected token < - bundle.js:1

npm run prod should create a file in /public/dist/, like it does on my local machine, but this directory is not present on either the heroku instance or the dokku instance, no error is display that it failed to create it, but if I try heroku run --app app mkdir public/dist it will silently fail, as if I try to access the directory it just 'created' it does not exist. I have also tried to manually run the npm run prod, it is successful, no dir is created, no errors are presented.

I believe there is also an issue with what my express server is trying to serve, my bundle.js is being served as index.html, I am not sure if this is an issue with there being no bundle.js to serve, or, even if there was, the app.get('*') has been misconfigured and is serving index.html blindly.

I simply want a static index.html file to serve my bundle.js so React can take over and do its thing, this doesn't seem possible with heroku, so I have tried to wedge an express server in between, any ideas?

like image 734
speak Avatar asked Feb 07 '23 14:02

speak


1 Answers

I was using a block in my express server similar to the one you are using:

app.get('*', function(req, res) {
  res.sendFile(path.join(__dirname + '/index.html'))
})

In production, my bundle.js file existed on the server, but this block was causing the browser to interpret the contents of the bundle.js file to be the contents of the index.html file, which is where there exists HTML code starting with <, hence the error.

For me, the error was solved in production by removing that app.get('*') block. I thought I needed the block in the first place to anchor request urls relative to the root url, not relative to whatever url path of the current page. It seems this is no longer an issue for me, perhaps because I included leading "/" in front of all my ajax api request urls.

This error popped up in production but not development probably because webpack dev server doesn't use an actual bundle file but holds the bundle in memory. But an actual bundle file is used in production.

Note: to get my configuration working, I also had to make sure express could recognize the bundle as a static file at the appropriate location:

app.use('/dist', express.static(path.join(__dirname, 'dist')));

The '/dist', part was key, else the bundle was showing up in the root path, not the path specified by my webpack config output.

like image 71
s2t2 Avatar answered Feb 12 '23 09:02

s2t2