[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 :)
Related
Is it possible to render template files (such as Pug or Handlebars) dynamically at runtime using Webpack and Express?
My issue is when loading my root page (index.pug), the html loads however no assets are loading.
Example:
app
.set('views', path.join(__dirname, 'views'))
.set('view engine', 'pug')
.use('/', function(req, res) {
res.render('index', {some: 'param'})
})
If I remove the '/' route handler, the page loads with all of the assets just fine.
Client webpack.config.js file:
module.exports = {
entry: {
main: ['webpack-hot-middleware/client?path=/__webpack_hmr&timeout=60000', './index.js', './css/main.css']
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
mode: 'development',
target: 'web',
devtool: '#source-map',
module: {
rules: [
{
test: /\.pug$/,
use: ['html-loader?attrs=false', 'pug-html-loader']
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: './views/index.pug',
filename: "./index.html",
excludeChunks: [ 'app' ]
})
]
}
Server webpack.server.config.js:
module.exports = (env, argv) => {
return ({
entry: {
app: 'app.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
}
]
}
})
}
You can make it work in 2 easy steps (based on the code above).
In server change the views path to where your built template is going to be. In the example above it's going to be inside the dist folder
app
.set("views", "./dist");
.set('view engine', 'pug')
.use('/', function(req, res) {
res.render('index', {some: 'param'})
})
At this point, after we run a build script and start the server we would get a message that there's no view in dist folder, which is correct because engine is looking for a template and all we have are html files
In webpack.config.js in HtmlWebPackPlugin we need to leave a filename as a template
plugins: [
new HtmlWebPackPlugin({
template: './views/index.pug',
filename: "./index.pug",
excludeChunks: [ 'app' ]
})
]
And that's it. Now template engine will find index.pug in dist with injected style and script and generate html from it
Note: In production it's important to set a path for static files, otherwise you won't get your css displayed even though the link tags were injected correctly
app.use(express.static(__dirname));
The above solution worked for me when I run into the same problem, but with the ejs template. I couldn't find the answer to it anywhere, so hopefully, it will save someone hours of frustration.
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!
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>
I'm a webpack newbie. I'm trying to add React to a simple Node project but I've only ever used React with a pre set up webpack dev server and not with another server. Webpack runs it's own node server so this poses one problem for me.
Here's what I need help with:
How do I add hot loading and source mapping if I'm using Express?
How can I add a global Bootstrap css from my public folder with webpack to this project (is there a way to do that kinda of how I did this with the js files and html-webpack-plugin)?
I've tried using webpack's dev server to get get hot loading but I've run into the problem where I have two servers conflicting: webpack and app.js server.
Here's part of my app.js file
var app = module.exports = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(path.join(__dirname, 'public')));
//API Routes
// all other requests
app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
// Starting server
http.createServer(app).listen(port);
.babelrc
{
"presets": [
"react",
"es2015",
"stage-0"
]
}
webpack.config.babel
import webpack from 'webpack'
var HtmlWebpackPlugin = require('html-webpack-plugin')
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/public/index.html',
filename: 'index.html',
inject: 'body'
})
const base = {
entry: {
"jquery": __dirname + '/public/js/lib/jquery/jquery-2.0.3.min.js',
"bootstrap": __dirname + '/public/bootstrap/js/bootstrap.min.js',
"index": __dirname + '/app',
},
output: {
path: __dirname + '/dist',
filename: '[name].js',
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.css$/, loader: 'style!css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]'}
]
},
}
const developmentConfig = {
devtool: 'cheap-module-inline-source-map',
plugins: [HTMLWebpackPluginConfig]
}
export default Object.assign({}, base, developmentConfig)
I tried adding new ExtractTextPlugin("dist/[name].css") to plugins and replacing my css loader with loader: ExtractTextPlugin.extract("style-loader", "css-loader") but I'm still not able to add bootstrap css or any css to my app.
Notice in your webpack.config.babel file you have this output:
output: {
path: __dirname + '/dist',
filename: '[name].js',
},
You need to put this [name].js file in your dist/index.html.
This blog post might be helpful for you for getting yourself properly set up!
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!