Webpack main.js error "Unexpected token <" when served from express server - node.js

I'm trying to serve my react app from an express server with a catch all route so that users can still access react routes when they refresh the page or manually type in a url. However, when I try to serve the app entry point, /dist/index.html, from my express server I get Uncaught SyntaxError: Unexpected token <
When I look at the main.js file in the sources tab of the console, this is what is see:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>React E-Store</title>
</head>
<body>
<div id="root">
</div>
</body>
<script src="/dist/main.js"></script>
</html>
This is what my server.js file looks like:
const express = require('express')
const path = require('path')
const port = process.env.PORT || 8080
const app = express()
// Handles all routes so you do not get a not found error
app.get('/*', function (request, response){
response.sendFile(path.resolve(__dirname, "dist", "index.html"))
})
app.listen(port)
console.log("server started on port " + port)
and here is my webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: './index.html',
filename: 'index.html',
inject: 'body'
})
module.exports = {
entry: './src/app.js',
output: {
path: path.resolve('dist'),
publicPath: '/dist/',
filename: '[name].js'
},
module: {
loaders: [
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ },
{ test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/ },
{
test: /\.(png|jp(e*)g|svg)$/,
loader: 'url-loader',
options: {
limit: 8000, // Convert images < 8kb to base64 strings
name: 'images/[hash]-[name].[ext]'
}
},
{
test: /\.sass$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]}
]
},
plugins: [HtmlWebpackPluginConfig]
}
I appreciate any help

Related

Isomorphic Render wont get my css or styling

I am using react as the client side and node.js as the server side, and using webpack to transpile. When I start the website on local host it is missing all of its styling and css. Any Ideas?
This is my frontend webpack that handles the transpiling of my frontend code
const path = require('path');
const nodeExternals = require('webpack-node-externals');
module.exports = {
target: 'node',
externals: [nodeExternals()],
entry: './frontend/src/App',
output: {
path: path.resolve(__dirname, 'backend/build'),
filename: 'bundle.js',
libraryTarget: 'commonjs2',
libraryExport: 'default'
},
module: {
rules: [
{
test: /\.jsx$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
},
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
},
{
test: /\.css$/,
use: [ 'css-loader'],
sideEffects: true
}
]
}
};
This is my backend/server.js that handles server rendering
const express = require('express');
const React = require('react');
const { renderToString } = require('react-dom/server');
const App = require('../backend/build/bundle');
const { matchPath } = require('react-router-dom');
const app = express();
// This is the middleware that will handle all routes
app.get('*', (req, res) => {
// We create a context object that will be passed to the StaticRouter
const context = {};
// Render the app component to a string
const html = renderToString(
React.createElement(App, {
location: req.url,
context,
})
);
// If the app component set a context.url value, it means the user
// tried to access a protected route that they are not authenticated for.
// In this case, we redirect them to the login page.
if (context.url) {
res.redirect(context.url);
} else {
// Send the rendered HTML as the response
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>My App</title>
</head>
<body>
<div id="root">${html}</div>
<script src="/build/bundle.js"></script>
</body>
</html>
`);
}
});
app.listen(3000, () =\> {
console.log('Server is listening on port 3000');
});
This is my frontend App.js
import React from "react";
import { StaticRouter } from "react-router-dom/server";
import { Footer, Contact, Who, Header } from "./containers";
import { Navbar, Background } from "./components";
import { Route, Routes } from "react-router-dom";
import "./App.css";
const App = (props) =\> {
return (
\<StaticRouter location={props.location} context={props.context}\>
\<Navbar /\>
\<Routes\>
\<Route exact path="/" element={\<Header /\>} /\>
\<Route path="/about" element={\<Who /\>} /\>
\<Route path="/contact" element={\<Contact /\>} /\>
\</Routes\>
\<Footer /\>
\</StaticRouter\>
);
};
export default App;
And this is my index.js
import React from 'react';
import ReactDom from 'react-dom';
import './index.css';
import App from './App';
ReactDom.render(
\<BrowserRouter\>
\<App /\>
\</BrowserRouter\>,
document.getElementById('root')
)
I have tried to add the styling-loader to the webpack config for the frontend but I end up getting an error where the document is not defined. The routing works fine, just no css or images, just basic html is being rendered`

Webpack: Cannot get index.html with express server middleware

I followed the official getting started instructions of webpack to setup a litte test project and config file. As they recommend, I use an express server with webpack middleware.
The setup
server.js:
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
})
);
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
My directory folder looks like this:
- dist/
- assets/
- css/
- bundle.index.html
- bundle.about.html
- index.html
- about.html
- src/
- fonts/
- images/
- sass/
- templates/
- about.html
- index.html
- ts/
- abstracts/
- utils/
- pages/
- about.ts
- index.ts
An this is my webpack.config (removed unnecessary items for this purpose).
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
module.exports = {
mode: mode,
entry: {
index: './src/ts/pages/index.ts',
about: './src/ts/pages/about.ts',
},
output: {
filename: 'bundle.[name].js',
path: path.resolve(__dirname, './dist'),
clean: true,
publicPath: '.',
assetModuleFilename: 'assets/[name][ext][query]',
},
devServer: {
port: 3000,
sockPort: 3000,
contentBase: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
title: 'Index',
filename: 'index.html',
template: 'dist/index.html',
chunks: ['index'],
}),
new HtmlWebpackPlugin({
title: 'about',
filename: 'about.html',
template: 'dist/about.html',
chunks: ['about'],
}),
],
module: {
rules: [
{
test: /\.html$/i,
loader: "html-loader",
},
// Support von versch. Grafiktypen
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
generator: {
filename: './assets/images/[name][ext][query]'
}
},
// Support von Fonts
{
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
generator: {
filename: './assets/fonts/[name][ext][query]'
}
},
],
},
resolve: {
extensions: ['.ts'],
alias: {
Style: path.resolve(__dirname, './src/sass'),
Fonts: path.resolve(__dirname, './src/fonts'),
Images: path.resolve(__dirname, './src/images'),
}
}
};
The problem
Running localhost:3000 in my browser, express returns Cannot get /.
Running localhost:3000 in my browser, express returns Cannot get / index.html.
Running localhost:3000/dist/index.html in my browser, express returns Cannot get dist/index.html.
So simply said, I cannot accees anything. Why? My config says that the
dist directory should be used as root directory.
devServer: {
port: 3000,
sockPort: 3000,
contentBase: path.resolve(__dirname, 'dist'),
},
Below values for the publicPath option should work:
publicPath: 'auto'
publicPath: '/'
publicPath: ''
Complete example:
webpack.config.js:
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
entry: {
index: "./src/ts/pages/index.ts",
about: "./src/ts/pages/about.ts",
},
output: {
filename: "bundle.[name].js",
path: path.resolve(__dirname, "./dist"),
clean: true,
publicPath: "",
},
plugins: [
new HtmlWebpackPlugin({
title: "Index",
filename: "index.html",
template: "src/templates/index.html",
chunks: ["index"],
}),
new HtmlWebpackPlugin({
title: "about",
filename: "about.html",
template: "src/templates/about.html",
chunks: ["about"],
}),
]
};
src/templates/index.html:
<!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>
</head>
<body>
index
</body>
</html>
src/ts/pages/index.ts:
console.log("index");
server.js:
const express = require("express");
const webpack = require("webpack");
const webpackDevMiddleware = require("webpack-dev-middleware");
const app = express();
const config = require("./webpack.config.js");
const compiler = webpack(config);
app.use(
webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath,
})
);
app.listen(3000, function () {
console.log("Example app listening on port 3000!\n");
});
Result:
Package versions:
"devDependencies": {
"html-webpack-plugin": "^5.3.2",
"webpack": "^5.51.1",
"webpack-cli": "^4.8.0",
"webpack-dev-server": "^4.0.0"
},
"dependencies": {
"express": "^4.17.1",
"webpack-dev-middleware": "^5.0.0"
}

Express Static files on server not loading correctly but React Front end is loading correctly?

I have a ReactJS project with Node/Express serving my server. On my front end (React) is serving port 3312 and on my server it's serving port (5000). When I load my front end through port 3312, everything looks great and my react router routes works fine. (My api's work everything is great). However, when I try and serve static files and see if I get the same result through my server (port 5000) I only see the styles on my page. (I have a background color) I don't see any of the html whatsoever that the static files should be serving?
I get no errors in the console when I look at localhost:5000. However, my css styles are displaying on the page correctly (cause I have a background color set on my body). However, I cannot see any of my front end React displaying html code. I went inside my index.html file and put a simple test in the root div and it's displaying but I don't understand why my React code isn't displaying on my server.
I most likely think the problem is with the express static files not serving my images or React Router code. I should also note that I'm not using create-react-app I'm using webpack dev server react no cli.
Also, I'm not using create-react-app I'm using no cli for custom webpack.
Here is my code:
(Node Server)
const express = require("express");
const path = require("path");
const router = express.Router();
const app = express();
const port = 5000;
// Serve static files on server
app.use("/public", express.static(__dirname + "/../public"));
app.get("*", function(request, response) {
response.sendFile(path.join(__dirname + "/../public/index.html"));
});
if (app.get("env") === "development") {
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
} else {
app.listen(port, "171.33.4.126", () => {
console.log(`Server started on port ${port}`);
});
}
routes.js
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/homepage";
import AboutPage from "./components/aboutpage";
import Contactpage from "./components/contactpage";
export default (
<Router>
<div>
<Switch>
<Route exact path="/" component={Landingpage} />
<Route exact path="/about" component={AboutPage} />
<Route exact path="/contact" component={Contactpage} />
</Switch>
</div>
</Router>
);
index.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Routes from "./routes";
ReactDOM.render(<div>{Routes}</div>, document.getElementById("root"));
index.html
<!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" />
<meta name="theme-color" content="#000000" />
<link
href="/public/assets/css/styles.css"
rel="stylesheet"
type="text/css"
/>
<title>Site</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Webpack Configuration Development
const webpack = require("webpack");
const path = require("path");
// const HtmlWebPackPlugin = require("html-webpack-plugin");
const BrowserSyncPlugin = require("browser-sync-webpack-plugin");
module.exports = {
devServer: {
historyApiFallback: true,
port: 3312,
proxy: {
"/api": "http://localhost:5000"
}
},
entry: ["babel-polyfill", __dirname + "/src/index.js"],
output: {
path: path.join(__dirname, "/public"),
filename: "bundle.js",
publicPath: "/"
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
query: {
presets: ["react", "env", "stage-0"]
}
}
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
}
]
},
plugins: [
// new HtmlWebPackPlugin({
// template: "./public/index.html"
// }),
new BrowserSyncPlugin({
host: "localhost",
port: 3312,
files: [
"./public/*.html",
"./public/assets/scss/*.scss",
"./public/assets/variables/*.scss",
"./public/assets/mixins/*.scss",
"./public/assets/reset/*.scss"
],
proxy: "http://localhost:3312/"
})
]
};
Here is a screenshot of my folder structure:
Screenshot of network status in console:
Your react code is not showing up because index.html is not including it. Is public/bundle.js your transpiled react code? If so, add the following line to index.html, right after <div id="root"></div>:
<script src="/public/bundle.js"></script>
If not, then change the path pointed by src to the correct one.
You can see your css styles just fine because you are already including those in index.html.
UPDATE: a couple of points based on your webpack config:
Change the port in which you are running webpack-dev-server to 3000. You will also have to change BrowserSyncPlugin's proxy to http://localhost:3000/. You can then go to localhost:3312 in your browser and requests will be proxied to the webpack-dev-server running on port 3000.
Correct me if I'm wrong, but you have not posted your index.html in its entirety. I'm guessing you already have a line that looks like <script src="/bundle.js"></script> somewhere in that .html file -- based on your latest comment, it seems it is being added by HtmlWebPackPlugin. webpack-dev-server is serving bundle.js through /, the publicPath you've specified in webpack's output option. This works just fine as long as you access your site through localhost:3312 or localhost:3000. However, your express.js server running on port 5000 has no idea webpack-dev-server is serving bundle.js at /; as a result of that, you end up seeing none of your react code when you go to localhost:5000. As for the styles, you are already serving them correctly through /public/assets/css, which the express.js server understands because you've specified that in this line: app.use("/public", express.static(__dirname + "/../public")). The solution is to change the line <script src="/bundle.js"></script> in your .html file to:
<script src="http://localhost:3312/bundle.js"></script>
Also, in webpack's output option, change the publicPath to http://localhost:3312/. Now, as long as you have webpack-dev-server running (with BrowserSyncPlugin), you can access
your site at localhost:5000 and your bundle.js file should be
served just fine.
Try the following:
Webpack Config
module.exports = {
devServer: {
contentBase: path.join(__dirname, "/public"),
historyApiFallback: true,
port: 3000,
proxy: {
"/api": "http://localhost:5000"
}
},
entry: ["babel-polyfill", __dirname + "/src/index.js"],
output: {
path: path.join(__dirname, "/public"),
filename: "bundle.js",
publicPath: "http://localhost:3312/"
},
module: {
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
query: {
presets: ["react", "env", "stage-0"]
}
}
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
}
]
},
plugins: [
new BrowserSyncPlugin({
host: "localhost",
port: 3312,
files: [
"./public/*.html",
"./public/assets/scss/*.scss",
"./public/assets/variables/*.scss",
"./public/assets/mixins/*.scss",
"./public/assets/reset/*.scss"
],
proxy: "http://localhost:3000/"
})
]
};
index.html
<!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" />
<meta name="theme-color" content="#000000" />
<link
href="/assets/css/styles.css"
rel="stylesheet"
type="text/css"
/>
<title>Site</title>
</head>
<body>
<div id="root"></div>
<script src="http://localhost:3312/bundle.js"></script>
</body>
</html>
Oh sorry, it looks like the problem is in index.js. Change {Routes} to <Routes />
import React, { Component } from "react";
import ReactDOM from "react-dom";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Routes from "./routes";
ReactDOM.render(<div><Routes/></div>, document.getElementById("root"));
You have another problem in routes.js. Export a component like
import React from "react";
import { BrowserRouter as Router, Route, Switch } from "react-router-dom";
import HomePage from "./components/homepage";
import AboutPage from "./components/aboutpage";
import Contactpage from "./components/contactpage";
// make this a component
export default ()=>(
<Router>
<Switch>
<Route exact path="/" component={Landingpage} />
<Route exact path="/about" component={AboutPage} />
<Route exact path="/contact" component={Contactpage} />
</Switch>
</Router>
);

Express static middleware returning error in log

I have a completed project done on my local machine and am currently learning how to deploy it to production. I figured out a lot of things in the documentation for production and such but I have been stuck for awhile now on the part on how to tell my server to serve my static assets that contain my build files that I executed with web pack. For the record, I'm not using create-react-app I'm using the webpack-dev-server cli.
I've only ever connected to my server successfully and ran routes through it using MySQL but I never tested serving the static files on the server when my development was ready for production. I'm getting an error in the console when I try to serve my static build files. I can't tell if the error is because I have my routes being served wrong on my server or there is an issue in my index.html build.
Here is my code the server file is big so I'll only show the relevant parts pertaining to the issue I'm stuck on:
Server file:
const express = require("express");
const bodyParser = require("body-parser");
const path = require("path");
const cors = require("cors");
const router = express.Router();
const app = express();
const port = 5000;
app.use(cors());
// Body Parser Middleware
app.use(bodyParser.json({ limit: "50mb" }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header(
"Access-Control-Allow-Headers",
"Origin, X-Requested-With, Content-Type, Accept"
);
next();
});
app.get("*", function(request, response) {
response.sendFile(path.join(__dirname + "/../public/index.html"));
});
// Serve static files on server
app.use("../", express.static(__dirname + "public/index.html"));
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
Build Index.html File
<!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">
<meta name="theme-color" content="#000000">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
crossorigin="anonymous">
<link href='https://fonts.googleapis.com/css?family=PT+Sans:400,400italic,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/all.css">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.0/css/v4-shims.css">
<link href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css" rel="stylesheet">
<link rel="stylesheet" href="/public/assets/css/pignose.calendar.min.css">
<link href="/public/assets/css/styles.css" rel="stylesheet" type="text/css">
<title></title>
</head>
<body>
<div id="root"></div>
<script type="text/javascript" src="/public/assets/js/jquery-3.3.1.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
crossorigin="anonymous"></script>
<!-- Ck Editor Library -->
<script src="/public/assets/js/plugins/ckeditor/ckeditor.js"></script>
<!-- Pignose Calendar -->
<script src="/public/assets/js/pignose.calendar.full.min.js"></script>
<script type="text/javascript" src="/public/assets/js/scripts.js"></script>
</body>
</html>
Webpack Production
const webpack = require("webpack");
const path = require("path");
const CompressionPlugin = require("compression-webpack-plugin");
const nodeExternals = require("webpack-node-externals");
const HtmlWebPackPlugin = require("html-webpack-plugin");
var browserConfig = {
entry: ["babel-polyfill", __dirname + "/src/index.js"],
output: {
path: path.resolve(__dirname + "/build"),
filename: "bundle.js",
publicPath: "/"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
query: {
presets: ["react", "env", "stage-0"]
}
}
},
{
test: /\.css$/,
use: [
{ loader: "style-loader" },
{ loader: "css-loader" },
{ loader: "sass-loader" }
]
}
]
},
plugins: [
new CompressionPlugin({
filename: "[path].gz[query]",
algorithm: "gzip",
minRatio: 0.8,
threshold: 8192
}),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify("production")
}),
new HtmlWebPackPlugin({
template: "./public/index.html"
})
]
};
var serverConfig = {
target: "node",
externals: [nodeExternals()],
entry: __dirname + "/server/main.js",
output: {
path: path.resolve(__dirname + "/build"),
filename: "bundle.js",
publicPath: "/"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
query: {
presets: ["react", "env", "stage-0"]
}
}
}
]
}
};
module.exports = [browserConfig, serverConfig];
Folder Architecture
Error log I'm getting when I try to connect to my port for my build files:
second error:
In express middleware configurations order matters, since app.get("*", function(request, response) is in the top every request will go through that and send the index.html. Change the order like this
// Serve static files on server
app.use('/public', express.static(__dirname + "/../public"));
app.get("*", function (request, response) {
response.sendFile(path.join(__dirname + "/../public/index.html"));
});
and it should work
Edit
As your request to extend my answer, what was happening here is since you haven't configured the public direcotry, express server will get to the next request handler which is app.get("*" , ... which sends the index.html as the response. So when you request this javascript file
<script type="text/javascript" src="/public/assets/js/jquery-3.3.1.min.js"></script>
It will send the index.html as i mentioned without sending the jquery-3.3.1.min.js and same for every js and css files, but your browser is expecting a javascript file and try to parse it so the file <!doctype> .. is parsing and since it is not a valid javascript, it prints the error. Hope that helps

How to use webpack-dev-middleware with feathers / express?

I'm trying to get a feathersjs app started with a reactjs frontend. Using the webpack-dev-middleware and webpack-hot-middleware, I should be able to simply extend the feathers app with all this webpack stuff during development. The only problem is always end up getting a feathers 404 page whenever I fetch the js file from webpack.
Currrently, here's my directory structure:
/feathers/public/index.html
/feathers/src/app.js
/react/src/index.js
/react/webpack.config.js
/react/develop.js
/feathers/src/app.js is is default feathers app, serves static files from the public folder.
.use('/', serveStatic( app.get('public') ))
In /react/develop.js, I'm requiring the feathers app and extending it with the webpack middlewares.
const app = require('../feathers/src/app');
const config = require('./webpack.config');
const path = require('path');
const webpack = require('webpack');
var compiler = webpack(config);
app.use(require('webpack-dev-middleware')(compiler, {
publicPath: '/',
stats: {colors: true},
}));
app.use(require('webpack-hot-middleware')(compiler));
const port = app.get('port');
const server = app.listen(port);
server.on('listening', () =>
console.log(`Feathers application started on ${app.get('host')}:${port}`)
);
Sadly this isn't working at all. For reference, here's my /react/webpack.config.js
var webpack = require("webpack")
module.exports = {
devtool: 'source-map',
entry: [
'webpack-hot-middleware/client',
'src/index.js'
],
output: {
path: '/',
filename: "bundle.js",
},
module: {
loaders: [
{ test: /\.js$/, loader: "babel", exclude: /node_modules/, query: { presets: ['es2015', 'react', 'stage-0'] } },
{ test: /\.(svg|png|jpe?g|gif|ttf|woff2?|eot)$/, loader: 'url?limit=8182' },
]
},
resolve: {
root: [
__dirname,
__dirname + '/src',
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
]
}
And /feathers/public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>React App</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
I've tried messing around with the publicPath stuff but no luck. Any ideas how to get this working? I've spend a solid 2 hours on this and got no where. Here's a link to the repo I'm working with for more context.
I see from your repository that you got this to work by including the webpack dev/hot middlewares in the proper place, in feathers/src/middleware/index.js where they will be used before Feathers' notFound middleware returns the 404. Middleware order matters!
Exporting a function for this purpose like you did in react/middleware.js is a clean solution to this problem, because it isolates the concern of setting up the webpack middleware from the backend itself (all the webpack stuff stays in the frontend).
Hope this helps anyone else!

Resources