I configured webpack dev middleware, when I go to index page / all works fine, otherwise page Not Found, how to make work dev server for all paths ?
const Koa = require('koa');
const webpack = require('webpack');
const devMiddleware = require('koa-webpack-dev-middleware')
const path = require('path');
const fs = require('fs');
const PORT = 3000;
const app = new Koa();
const config = require('./webpack.config');
const compiler = webpack(config);
app.use(devMiddleware(compiler, {
publicPath: config.output.publicPath,
historyApiFallback: true,
stats: { colors: true },
}));
app.listen(PORT, function () {
console.log(`Dev Server port: "${3000}"`);
});
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
publicPath: '/',
},
devtool: 'inline-source-map',
plugins: [
new CleanWebpackPlugin(['dist']),
new HtmlWebpackPlugin({
title: 'Output Management'
})
],
module: {
rules: [
{
test: /.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
}
]
}
}
Related
I am struggling a bit to find a solution to using webpack on the both the frontend and the server part of a nodejs project.
I am building an express solution with different API endpoints and a frontend that uses EJS for templating that will use these endpoints for data handling.
Basically what I am trying to achieve is to using webpack to compile my SCSS and JS on the frontend and also a solution that will compile EJS and inject the CSS and JS bundles into the frontend.
My current server.js
const express = require('express')
const formidable = require('express-formidable');
const session = require('express-session')
const bodyparser = require('body-parser')
const app = express()
const path = require('path');
const auth = require('./app/middleware/authorization/auth')
const upload = require('./app/middleware/filehandling/upload')
app.set('port', process.env.PORT || 8080);
app.set('view engine', 'ejs')
app.set('views', path.join('views'));
app.use(session({
secret: hash.getRandomString(16),
resave: true,
saveUninitialized: true
}))
app.use(express.json())
app.use('/public', express.static(path.resolve(__dirname, 'public')));
app.use(formidable());
app.use(passport.initialize());
app.use(passport.session());
app.use(bodyparser.urlencoded({ extended: true }))
app.use(bodyparser.json())
//DIFFERENT ROUTES DOWN HERE
app.listen(3000, () => {
console.log('listening on port 3000')
})
My folder structure is
public
- upload/
src
- scss/
- index.js
views
- partials/
- index.ejs
- login.ejs
I have a current webpack.config.dev.js that I am using for static HTML/CSS/JS project that are building and compiling SCSS and JS into bundles.
const path = require('path');
const webpack = require('webpack');
const HTMLWebpackPlugin = require('html-webpack-plugin');
// const ExtractText = require('extract-text-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const devMode = process.env.NODE_ENV !== 'production'
const dirNodeModules = 'node_modules';
const dirAPP = path.join(__dirname, 'src/app');
const dirAssets = path.join(__dirname, 'src/assets');
const packageJson = require('./package.json')
var config = {
entry: {
bundle: path.join(dirAPP, 'index')
},
resolve: {
modules: [
dirNodeModules,
dirAPP,
dirAssets
]
},
plugins: [
new webpack.DefinePlugin({
devMode: devMode
}),
new HTMLWebpackPlugin({
template: path.join('src', 'index.html'),
inject: true
}),
new MiniCssExtractPlugin({
filename: packageJson.name + '.[chunkhash].min.css'
})
],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader', 'eslint-loader']
},
{
test: /\.(sa|sc|c)ss$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
sourceMap: true,
config: {
path: 'postcss.config.js'
}
},
loader: 'sass-loader',
options: {
sourceMap: true
}
}
]
},
{
test: /\.(eot|svg|ttf|woff|woff2)$/,
use: 'file?=name/fonts/[name].[ext]'
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
use: [{
loader: 'file-loader',
options: {
name: '[name]-[hash:8].[ext]',
pluginPath: dirAssets + '/images/',
outputPath: dirAssets + '/images/'
}
}]
}]
}
}
module.exports = config;
And a webpack.config.build.js
const path = require('path');
const merge = require('webpack-merge');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const webpackConfig = require('./webpack.config');
const packageJson = require('./package.json');
module.exports = merge(webpackConfig, {
devtool: 'source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: packageJson.name + '.[chunkhash].js'
},
plugins: [
new CleanWebpackPlugin(['dist'])
]
});
Which I call using
"dev": "cross-env NODE_ENV=dev webpack-dev-server --progress --mode development --config webpack.config.dev.js",
"build": "webpack -p --progress --mode production --config webpack.config.build.js"
I am a bit unsure how I can achieve this.
I have a webpack plugin as below, I want to user localhost secure , how can I do that ? I do not see any require('http') as in the nodejs server, how can I do that with this webpack configuration ?
Should I prepare some SSL certificate ? If so where should I use them ?
Here is webpack configuration for development
'use strict'
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const path = require('path')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')
const portfinder = require('portfinder')
const HOST = process.env.HOST
const PORT = process.env.PORT && Number(process.env.PORT)
const devWebpackConfig = merge(baseWebpackConfig, {
module: {
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
},
// cheap-module-eval-source-map is faster for development
devtool: config.dev.devtool,
// these devServer options should be customized in /config/index.js
devServer: {
clientLogLevel: 'warning',
historyApiFallback: {
rewrites: [
{ from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
],
},
hot: true,
contentBase: false, // since we use CopyWebpackPlugin.
compress: true,
host: HOST || config.dev.host,
port: PORT || config.dev.port,
open: config.dev.autoOpenBrowser,
overlay: config.dev.errorOverlay
? { warnings: false, errors: true }
: false,
publicPath: config.dev.assetsPublicPath,
proxy: config.dev.proxyTable,
quiet: true, // necessary for FriendlyErrorsPlugin
watchOptions: {
poll: config.dev.poll,
}
},
plugins: [
new webpack.DefinePlugin({
'process.env': require('../config/dev.env')
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
new webpack.NoEmitOnErrorsPlugin(),
// https://github.com/ampedandwired/html-webpack-plugin
new HtmlWebpackPlugin({
filename: 'index.html',
template: 'index.html',
inject: true
}),
// copy custom static assets
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.dev.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
module.exports = new Promise((resolve, reject) => {
portfinder.basePort = process.env.PORT || config.dev.port
portfinder.getPort((err, port) => {
if (err) {
reject(err)
} else {
// publish the new Port, necessary for e2e tests
process.env.PORT = port
// add port to devServer config
devWebpackConfig.devServer.port = port
// Add FriendlyErrorsPlugin
devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({
compilationSuccessInfo: {
messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`],
},
onErrors: config.dev.notifyOnErrors
? utils.createNotifierCallback()
: undefined
}))
resolve(devWebpackConfig)
}
})
})
devServer: {
https: true,
...
},
I have a React app, served via ExpressJS. I have configured Webpack to create .gz assets.
However HtmlWebpackPlugin creates the bundle in my index.html as a .js file.
I assume this is because in the output prop in my webpack.prod.js I have the filename with a .js extention.
How can I configure this to return the .gz extension when supported?
Express App
const express = require('express');
const path = require('path');
const app = express();
app.use(express.static(path.resolve(__dirname, '../dist')));
app.get('*.js', function(req, res, next) {
req.url = req.url + '.gz';
res.set('Content-Encoding', 'gzip');
next();
});
app.get('/healthz', (req, res) => res.send('OK'));
app.get('*', (req, res) =>
res.sendFile(path.resolve(__dirname, '../dist/index.html'))
);
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || '127.0.0.1';
app.listen(PORT);
console.log(`API started on ${HOST}:${PORT}`);
webpack.common.js
const commonPaths = require('../common-paths');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
module.exports = {
context: commonPaths.appPath,
entry: './index.jsx',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [
{ test: /\.(jsx?)$/, exclude: /node_modules/, use: ['babel-loader'] }
]
},
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: 'initial',
test: 'vendor',
name: 'vendor',
enforce: true
}
}
}
},
plugins: [
new CompressionPlugin({
algorithm: 'gzip',
test: /\.js$|\.css$|\.html$/,
threshold: 10240,
minRatio: 0.8
}),
new HtmlWebpackPlugin({
title: 'Web App',
template: commonPaths.projectRoot + '/public/index.html',
inject: 'body'
})
]
};
webpack.prod.js
const commonPaths = require('../common-paths');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
devtool: 'source-map',
mode: 'production',
output: {
filename: 'static/[name].[hash].min.js',
path: commonPaths.outputPath
},
plugins: [
new ExtractTextPlugin({
filename: 'static/styles.[hash].min.css',
allChunks: true
})
]
};
I have also tried the following in my Express App incase it was failing in serving the files...
const express = require('express');
const path = require('path');
const app = express();
app.use(
express.static(path.resolve(__dirname, '../dist'), {
index: false,
fallthrough: true,
setHeaders: (res) => {
res.set('Content-Encoding', 'gzip');
}
})
);
app.get('/healthz', (req, res) => res.send('OK'));
app.get('*', (req, res) =>
res.sendFile(path.resolve(__dirname, '../dist/index.html'))
);
const PORT = process.env.SERVER_PORT || 3000;
const HOST = process.env.SERVER_HOST || '127.0.0.1';
app.listen(PORT);
console.log(`API started on ${HOST}:${PORT}`);
I'm trying to set up HMR with my express sever. When I run node app, I see that webpack compiles, SQL seeds DB and node runs in my terminal . My app runs and seems to work, however when I make a change I don't see the change. I also don't see the change when I refresh the app either!
What am I missing? I think I'm close.
note: I'm following : http://andrewhfarmer.com/understanding-hmr/
index.js:
import React from 'react'
import ReactDOM from 'react-dom'
import routes from './config/routes'
ReactDOM.render(
routes,
document.getElementById('root')
);
if (module.hot) {
module.hot.accept();
}
webpack.config
var webpack = require('webpack')
var ExtractTextPlugin = require("extract-text-webpack-plugin")
var HtmlWebpackPlugin = require('html-webpack-plugin')
var HTMLWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/index.html',
filename: 'index_bundled.html',
inject: 'body',
})
module.exports = {
entry: {
"jquery": __dirname + '/public/js/lib/jquery/jquery-2.0.3.min.js',
"bootstrap": __dirname + '/public/bootstrap/js/bootstrap.min.js',
"index": [__dirname + '/app/index.js',
'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=2000&overlay=false'],
},
output: {
path: __dirname + '/public',
filename: '[name].js',
publicPath: '/',
},
module: {
loaders: [
{test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader'},
{test: /\.css$/, loader: 'style!css?sourceMap&modules&localIdentName=[name]__[local]___[hash:base64:5]'},
],
},
devtool: 'cheap-module-inline-source-map',
plugins: [
HTMLWebpackPluginConfig,
new ExtractTextPlugin("dist/[name].css"),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
}
app.js
var express = require('express');
var webpack = require('webpack');
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpackHotMiddleware = require("webpack-hot-middleware");
var compiler = webpack(require("./webpack.config.babel.js"));
/* Sequelize stuff */
var app = module.exports = express();
app.use(webpackDevMiddleware(compiler, {
hot: true,
filename: 'index.js',
publicPath: '/',
stats: {
colors: true,
},
historyApiFallback: true,
}));
//app.use(require("webpack-hot-middleware")(compiler));
app.use(webpackHotMiddleware(compiler, {
log: console.log,
path: '/__webpack_hmr',
heartbeat: 2000,
}));
/* APIs and routes */
// Starting express server
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port'));
});
IM pulling out hairs trying to get hot reloading working. My project loads when I run node server.js but files are not being hot reloaded.
server.js
// webpack stuff
var webpack = require("webpack");
var webpackDevMiddleware = require("webpack-dev-middleware");
var webpackHotMiddleware = require("webpack-hot-middleware");
var config = require("./webpack.config");
var compiler = webpack(config);
// email template
var emailTemplate = require("./emailTemplate");
// express
var express = require("express");
var app = express();
var crypto = require("crypto");
var bodyParser = require("body-parser");
var cookieParser = require("cookie-parser");
var port = 8000;
app.use(webpackDevMiddleware(compiler, { noInfo: true, publicPath: config.output.publicPath }));
app.use(webpackHotMiddleware(compiler));
app.use(express.static(__dirname + "/src"));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(cookieParser());
....... shorten for security
webpack.config.js
var webpack = require('webpack');
module.exports = {
entry: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'./src/index.js'
],
output: {
path: __dirname + '/src/build',
filename: 'bundle.js',
public: '/',
publicPath: 'http://localhost:8000/public/'
},
module: {
loaders: [
{
test: /\.jsx?$/,
loaders: ['babel'],
exclude: /node_modules/,
include: __dirname + '/src'
},
{
test: /\.json$/,
loader: 'json-loader'
},
{
test: /\.css$/,
loader: 'style-loader!css-loader!postcss-loader'
},
{
test: /\.(png|jpg|jpeg|gif|woff)$/,
loader: 'url-loader?limit=8192'
}
]
},
jest: {
moduleFileExtensions: ["js", "jsx"]
},
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
]
};
Please let me know if there are other files that would be useful to see.