Serving express static files not working with bundle from webpack :( - node.js

so I have a node/express app that serves back a bundle.js bundled by webpack.
I've been banging my head at this issue for close to 4 nights and I don't know anymore.
I'm getting the Uncaught SyntaxError: Unexpected token < error as the express static middleware is not catching the request and treating it.
webpack.config.js:
output: {
path: BUILD_DIR,
filename: 'bundle.js',
// https://github.com/webpack/webpack-dev-middleware/issues/205
// DO NOT leave publicPath out -- it'll cause errors if we do
publicPath: '/',
},
express middleware:
var serveStatic = require('serve-static')
app.use(serveStatic(
path.join(__dirname, 'statics'),
))
app.use('/dist', express.static('dist'));
app.use('/statics', express.static('statics'));\
index.html:
<script src="bundle.js" type="text/javascript"></script>

Related

NodeJS application cannot find modules after being bundled by Webpack

I'm creating a node/express server that I'm trying to bundle so that I can deploy it onto an IIS server. I should note that this is a backend server only. Once I try to run the code after it has been bundled, I get the following error:
ReferenceError: __WEBPACK_EXTERNAL_MODULE_dotenv__ is not defined
at eval (webpack:///external_%22dotenv%22?:1:18)
at Object.dotenv (C:\inetpub\wwwroot\my-deployments\server\bundle.js:271:1)
at __webpack_require__ (C:\inetpub\wwwroot\my-deployments\server\bundle.js:20:30)
at eval (webpack:///./src/server/server.js?:4:1)
at Object../src/server/server.js (C:\inetpub\wwwroot\my-deployments\server\bundle.js:169:1)
at __webpack_require__ (C:\inetpub\wwwroot\my-deployments\server\bundle.js:20:30)
at eval (webpack:///multi_./src/server/server.js?:1:18)
at Object.0 (C:\inetpub\wwwroot\my-deployments\server\bundle.js:216:1)
at __webpack_require__ (C:\inetpub\wwwroot\my-deployments\server\bundle.js:20:30)
at C:\inetpub\wwwroot\my-deployments\server\bundle.js:84:18
I understand that there seems to be an error with the dotenv module, however I tried with a basic app that only had express installed, and I got the same error but with express instead of dotenv. I figure this is an issue with my webpack.config.js but I can't seem to figure out what would be causing this problem.
webpack.config.js
const path = require('path')
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
target: 'node',
mode: 'development',
entry: {
bundle: ["./src/server/server.js"]
},
externals: [nodeExternals({
importType: 'umd'
})],
plugins: [
new CleanWebpackPlugin(),
new HtmlWebpackPlugin({
title: 'server'
})
],
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
}
}
The issue is in your nodeExternals options. Remove importType: 'umd' and re-bundle. I tested this locally with a small express app and your exact config and it worked for me.
The issue here is that you're telling webpack that all your imports are "external" (not bundled) and that they use umd (Universal Module Definition) to expose their contents.
Umd is often used for client side code so it'll run in multiple different environments (<script> tags, commonjs, amd, es6 modules and so on). As for server side / Nodejs only modules... not so much. The default value of importType is commonjs, which is Node's native module loading system and what the vast majority of server side packages will be using.

Can't access dynamic html using html-webpack-plugin with express server

Recently, I want to use html-webpack-plugin in my project, but face a problem.
Here is part of my server.js and webpack.dev.config.js
server.js
if (process.env.NODE_ENV === 'development')
{
const webpack = require('webpack');
const config = require('./webpack.development.config');
const compiler = webpack(config);
app.use(require('webpack-dev-middleware')(compiler,
{
noInfo: true,
publicPath: '/'
}));
app.use(require('webpack-hot-middleware')(compiler));
}
app.get('*', (req, res) =>
{
res.sendFile(path.resolve(__dirname, 'public/asset','index.html'));
});
webpack.dev.js
plugins: [
new HtmlWebpackPlugin({
template: './public/enter.html',
filename: 'index.html'
}),
new PreloadWebpackPlugin()
]
I can access this directly like http://localhost:3000.
It's supposed to be accessed by any path e.g.http://localhost:3000/counter, but get
Error: ENOENT: no such file or directory, stat
'/Users/paulhuang/Documents/workspace/react-redux-template/public/asset/index.html'
I use npm run build to create a harddisk index.html, and solved the problem.
Any other better idea? Thanks!

bundle.js not found [Webpack]

[UPDATE] bundle.js was actually created in memory. The best way is to keep index.html and bundle.js (configured in webpack.config.js) in the same directory to avoid any issue.
I have been trying to render a simple html file with webpack but can't figure out why I'm getting a 404. I understand that bundle.js could not be found so I tried different paths but it didn't work, any ideas?
I would appreciate your help.
Thanks.
app.js
var express = require('express')
var path = require('path')
const app = express();
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html')
app.get('/', function (req, res) {
res.render('index')
})
app.listen(3000, () => console.log('Example app listening on port 3000!'))
webpack.config.js
module.exports = {
entry: ['./src/index.js'],
output: {
path: __dirname,
publicPath: '/',
filename: 'bundle.js'
},
[...]
index.html
<!DOCTYPE html>
<html>
[...]
<body>
<div class="container"></div>
</body>
<script src="./bundle.js"></script>
</html>
Folder structure
You don't have specified a correct path to your index file. If you have it on a src directory the code will look like this:
entry: [
path.resolve(__dirname, 'src/index')
],
[...]
Otherwise if you have it on your views directory, them the code will be the following:
entry: [
path.resolve(__dirname, 'views/index')
],
[...]
And in your html file is <script src="/bundle.js"></script>
UPDATE
Base on your code at github try changing the following lines
entry: [
path.resolve(__dirname, 'src/index')
],
devServer: {
contentBase: path.resolve(__dirname, 'src')
},
output: {
path: __dirname + '/dist', // Note: Physical files are only output by the production build task `npm run build`.
publicPath: '/',
filename: 'bundle.js'
},
The problem consist in that you're missing the path.resolve(...) in both your entry point and your devServer specifically
Hope 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!

webpack-dev-middleware and Express - can't get them to collaborate

I am trying to set up my first project using Webpack and Express but somehow I am doing something wrong.
This is what I did:
1. CREATED SAMPLE PROJECT
Created a sample project using express-generator. My folder structure is something like:
express-project
-app.js
-webpack.config.js
-public
-javascripts
-modules
-build
2. SET UP HANDLEBARS
Set up handlebars as view/template engine and created a couple of routes
3. WEBPACK CODE
Created the Webpack specific code/configuration as follows
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var webpackHotMiddleware = 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&overlay=false';
module.exports = {
resolve: {
alias: {
handlebars: path.resolve('public/vendor/handlebars-v4.0.5.js'),
bootstrap: path.resolve('public/vendor/bootstrap/js/bootstrap.js'),
pubsub: path.resolve('public/vendor/ba-tiny-pubsub.js')
}
},
context: path.resolve('public/javascripts'),
entry: {
cart: ['./modules/cart', webpackHotMiddleware],
index: ['./modules/products.js', webpackHotMiddleware],
vendor: ['bootstrap', 'pubsub', webpackHotMiddleware]
},
output: {
path: path.resolve('public/javascripts/build'),
publicPath: 'javascripts/build/',
filename: '[name].js',
chunkFilename: "[id].js"
},
module: {
loaders: [
// some loaders here
]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
}
app.js
// some code before
var app = express();
(function() {
// Step 1: Create & configure a webpack compiler
var webpack = require('webpack');
var webpackConfig = require(process.env.WEBPACK_CONFIG ? process.env.WEBPACK_CONFIG : './webpack.config');
var compiler = webpack(webpackConfig);
// Step 2: Attach the dev middleware to the compiler & the server
app.use(require("webpack-dev-middleware")(compiler, {
noInfo: false,
publicPath: webpackConfig.output.publicPath,
stats: {
colors: true
}
}));
// Step 3: Attach the hot middleware to the compiler & the server
app.use(require("webpack-hot-middleware")(compiler, {
log: console.log,
path: '/__webpack_hmr',
heartbeat: 10 * 1000
}));
})();
// some code after
4. JS CODE ON TEMPLATE
Then on the handlebars page I require the bundled javascripts
<script src="javascripts/build/common.js"></script>
<script src="javascripts/build/vendor.js"></script>
<script src="javascripts/build/cart.js"></script>
5. NPM START
Finally if I start the server using the standard npm start I see in the shell that webpack bundles everything with no errors but if I go to localhost:3000/ it does not find any of the assets created by Webpack. Instead if I run webpack to create the various bundles as if I were on production, everything is created correctly and it works as expected.
Hope someone can figure out what I am doing wrong.
Thanks
I managed to figure out what was causing the problem, by adding a slash in these 2 lines everything started to work properly:
context: path.resolve('public/javascripts/'),
path: path.resolve('public/javascripts/build/'),

Resources