Browser downloads the HTML contents instead of showing it with webpack-dev-server - reactjs

When I use webpack-dev-server with historyApiFallback replacing its index with index.php instead of index.html, A browser specifically Chrome will download its HTML contents instead of showing it.
How can I fix this issue?
My webpack.config.js is below.
webpack.config.js
const webpack = require('webpack');
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// const StyleLintPlugin = require('stylelint-webpack-plugin');
const fs = require('fs');
const entries = [
'./src/index.js',
];
module.exports = {
stats: {
assets: false,
colors: true,
version: false,
hash: true,
timings: true,
chunks: true,
chunkModules: true,
},
entry: entries,
output: {
path: path.resolve(__dirname, 'dist', 'assets'),
filename: '[name].js',
},
devtool: 'source-map',
devServer: {
port: 8000,
host: 'foobar.example.dev',
historyApiFallback: {
index: 'index.php',
},
noInfo: false,
stats: 'minimal',
contentBase: 'src',
hot: true,
inline: true,
https: true,
open: false,
cert: fs.readFileSync(path.resolve(__dirname, '..', 'shared', 'certs', 'foobar.example.dev.crt')),
key: fs.readFileSync(path.resolve(__dirname, '..', 'shared', 'certs', 'foobar.example.dev.key')),
proxy: {
'/wp-json/*': {
target: 'https://foobar.example.dev/wp-json',
port: 443,
secure: false,
changeOrigin: true,
},
},
},
module: {
rules: [
{
enforce: 'pre',
test: /\.js?$/,
loader: 'eslint-loader',
options: {
configFile: '.eslintrc',
},
exclude: /(node_modules)/,
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'postcss-loader',
'sass-loader',
],
}),
},
{
test: /\.(js|jsx)$/,
loaders: 'babel-loader',
exclude: /node_modules/,
query: {
presets: ['es2015', 'stage-1', 'react', 'react-hmre'],
},
},
// Images
// First use Base64 Encoded images if it is smaller than 10kb
// Otherwise use hashed images and optimize the image
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'url-loader?limit=10000&name=images/[name].[hash].[ext]',
],
},
// Fonts
{
test: /\.(eot|ttf|woff|woff2)$/,
loader: 'file-loader?name=fonts/[name].[ext]',
},
],
},
resolve: {
extensions: ['.js', '.scss', '.css'],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NamedModulesPlugin(),
new StyleLintPlugin({
configFile: '.stylelintrc',
context: './src/styles',
files: '**/*.scss',
}),
new webpack.ProvidePlugin({
"React": "react",
}),
new ExtractTextPlugin({
filename: '/assets/main.css',
disable: process.env.NODE_ENV !== 'production',
allChunks: true,
}),
],
};
Here is the result of curl command
curl -I https://foobar.example.dev --insecure
HTTP/2 200
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 9577

Related

Webpack React Default URL

I am trying to figure out how to set the config up to by default load a different url as the base. Currently it is loading localhost:3000 - I need it to load localhost:3000/market. Client doesn't want the base path to work. For example if this was google, http://google.com wouldn't work and only http://google.com/market would.
I have checked quite a few stacks and this React with webpack was the closest I could find, however I can't use flags for the different environments, so I need it in the config, and I cannot for the life of me figure that out.
This is what I have in my webpack so far:
const appConfig = {
version: pkg.version,
basePath: process.env.BASE_URL,
api: {
baseUrl: `${process.env.BASE_URL}/api`,
},
auth: {
name: "ping",
config: {
clientId: process.env.CLIENT_ID,
authorizationUri: "redacted",
scopes: process.env.SCOPES,
},
},
};
module.exports = {
entry: './src/index.tsx',
output: {
path: path.join(__dirname, 'build/'),
filename: 'marketplace2.js',
globalObject: 'this',
publicPath: '/',
},
mode: nodeEnv,
resolve: {
plugins: [newTsConfigPathsPlugin],
extensions: ['.tsx', '.ts', '.js'],
},
target: 'web',
devServer: {
static: path.join(__dirname, './src'),
open: true,
port: 3000,
},
module: {
rules: [
{
test: /\.(js|jsx|json)$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: ['ts-loader'],
},
{
test: /\.(css|scss)$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
},
{
test: /\.(jpg|jpeg|png|gif|mp3|svg|webp|ico)$/,
exclude: /node_modules/,
use: ['file-loader?name=[name].[ext]'],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, './public', 'index.html'),
favicon: path.join(__dirname, './public', 'favicon.ico'),
manifest: path.join(__dirname, './public', 'manifest.json'),
}),
new Dotenv(),
new webpack.DefinePlugin({
"process.env.NODE_ENV": JSON.stringify(nodeEnv),
"process.env.SERVER": "false",
"process.env.RUN_CONFIG": JSON.stringify(appConfig),
}),
new CopyWebpackPlugin({
patterns: [
{ from: 'public', to: 'public' },
]
}),
],
};

Webpack hot module replacement stuck at [HMR] Waiting for update signal from WDS

I'm using webpack hot module replacement in my react project.
configuration looks like below.
let compilerConfig = {
entry: [
'babel-polyfill',
'webpack-dev-server/client?http://0.0.0.0:9000/',
'webpack/hot/only-dev-server',
path.join(ws.srcDir, 'client', 'src', 'index.js'),
],
devtool: 'source-map',
output: {
path: path.resolve(ws.srcDir, 'public'),
filename: 'main.js',
publicPath: '/'
},
module: {
rules: [
{
test: /\.(?:p|s)?css$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
{
loader: 'css-loader',
options: {
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: { config: { path: path.join(__dirname, "postcss.config.js") } }
},
],
}),
},
{
test: /\.(png|woff|woff2|eot|ttf)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
loader: 'url-loader',
},
{
test: /\.(js|jsx)?$/,
include: [
path.resolve(__dirname, 'src'),
path.resolve(__dirname, 'node_modules', 'astro'),
],
loader: 'babel-loader',
options: {
babelrc: false,
presets: [
'react',
'es2015',
'stage-2'
]
},
},
{
test: /\.svg$/i,
use: [
{
loader: "babel-loader",
},
{
loader: "svg-react-loader",
query: {
classIdPrefix: '[name]-[hash:8]__',
propsMap: {
fillRule: 'fill-rule',
foo: 'bar'
},
xmlnsTest: /^xmlns.*$/
}
}
],
},
],
},
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': `"${NODE_ENV}"`,
}),
new ExtractTextPlugin('styles.css'),
new HTMLWebpackPlugin({
template: path.join(ws.srcDir, 'client', 'src', "index.html"),
}),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
};
const serverConfig = {
contentBase: path.resolve(ws.srcDir, 'client', 'src'),
port: process.env.PORT || '9000',
inline: true,
host: '0.0.0.0',
historyApiFallback: true,
stats: {
colors: true,
},
headers: {
'Access-Control-Allow-Origin': '*'
},
};
And i'm starting webpack dev server through gulp as below.
gulp.task('webpack-dev', function() {
WebpackDevServer.addDevServerEntrypoints(compilerConfig, serverConfig);
const webpackConf = webpack(compilerConfig);
new WebpackDevServer(webpackConf, serverConfig)
.listen('9000', '0.0.0.0', function(err) {
if (err)
throw new Error("webpack-dev-server", err);
// Server listening
console.info("[webpack-dev-server]", "http://localhost:9000");
})
})
Getting [WDS] Disconnected! error after some time. And also i'm not seeing [WDS] Hot Module Replacement enabled. log in the console.
when i do a code change webpack is recompiling, but don't see it reflecting in the browser.
Using below version.
webpack = 2.3.x
webpack-dev-server = 2.4.x
Found the problem. I was loading a script in my index.html. That got failed(404). This is causing Hot Module Replacement to fail.

Enable source maps in Webpack

I have a problems with souce maps. They are generated but apparently not used.
I use webpack-dev-server, react hot module replacement and Webpack v3.x if that is important.
Inside of my webpack-config i use devtool: 'source-map' and I run my script like this:
"webpack": "cross-env NODE_ENV=development webpack-dev-server -d --config webpack.config.js"
Example of error that I get
When I click on this client?e36c:157 it doesn't take me to source code but:
If I remove devtools from webpack.config and -d tag from script I get the same output
**webpack.config.js**
const path = require('path')
const webpack = require('webpack')
const publicPath = path.resolve(__dirname, './src/client')
const buildPath = path.resolve(__dirname, './src')
// const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
const Write = require('write-file-webpack-plugin')
process.noDeprecation = true
module.exports = {
devtool: 'source-map',
performance: {
hints: false,
},
devServer: {
hot: true,
port: 3001,
host: 'localhost',
/* Needed only if using Browsersync */
headers: { 'Access-Control-Allow-Origin': '*', },
proxy: {
'**': {
target: 'http://localhost:3000',
secure: false,
changeOrigin: true,
},
},
},
context: publicPath,
entry: {
bundle: [
'react-hot-loader/patch',
'webpack-dev-server/client?http://localhost:3001',
'webpack/hot/only-dev-server',
'script-loader!jquery/dist/jquery.min.js',
'script-loader!tether/dist/js/tether.min.js',
'script-loader!bootstrap/dist/js/bootstrap.min.js',
'./app.js',
],
},
output: {
path: path.join(buildPath, 'dist'),
filename: '[name].js',
publicPath: 'http://localhost:3001/',
},
resolve: {
extensions: [ '.js', '.jsx', ],
alias: {
// Container
Container: path.resolve(__dirname, 'src/client/scenes/Container.jsx'),
// Components
FormComponent: path.resolve(
__dirname,
'src/client/scenes/feature/components/FormComponent.jsx'
),
Feature: path.resolve(__dirname, 'src/client/scenes/feature/Feature.jsx'),
TitleComponent: path.resolve(
__dirname,
'src/client/scenes/home/components/TitleComponent.jsx'
),
Home: path.resolve(__dirname, 'src/client/scenes/home/Home.jsx'),
Navigation: path.resolve(__dirname, 'src/client/scenes/shared/navigation/Navigation.jsx'),
},
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules|dist|build/,
loader: 'babel-loader',
options: {
babelrc: true,
},
},
{
test: /\.local\.(css|scss)$/,
use: [
'style-loader',
'css-loader?sourceMap&modules&importLoaders=1&localIdentName=[path]___[name]__[local]___[hash:base64:5]',
'postcss-loader?sourceMap',
'sass-loader?sourceMap',
{
loader: 'sass-resources-loader',
options: {
resources: [
path.resolve(__dirname, './src/client/styles/scss/variables.scss'),
],
},
},
],
},
{
test: /^((?!\.local).)+\.(css|scss)$/,
use: [
'style-loader',
'css-loader?sourceMap',
'postcss-loader?sourceMap',
'sass-loader?sourceMap',
],
},
{
test: /\.(gif|png|jpg)$/,
/* We can specify custom publicPath if needed */
loader: 'url-loader',
},
],
},
plugins: [
new Write(),
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery',
jquery: 'jquery',
}),
],
}

Migrating from web pack v1.15 config to v2.6.1

Updated webpack to the latest version(2.6.1), so the webpack config file, that came with the boilerplate, became outdated...
Looked at the official documentation on migration, but still a bit lost regarding how exactly i need to update my config file:
'use strict';
const path = require('path');
const webpack = require('webpack');
const NODE_ENV = process.env.NODE_ENV;
const SaveAssetsJson = require('assets-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
module.exports = {
devtool: '#source-map',
// Capture timing information for each module
profile: false,
// Switch loaders to debug mode
debug: false,
// Report the first error as a hard error instead of tolerating it
bail: true,
entry: [
'babel-polyfill',
'./assets/main.jsx',
],
output: {
path: 'public/dist/',
pathInfo: true,
publicPath: '/dist/',
filename: 'bundle.[hash].min.js',
},
resolve: {
root: path.join(__dirname, ''),
modulesDirectories: [
'web_modules',
'node_modules',
'assets',
'assets/components',
],
extensions: ['', '.webpack.js', '.web.js', '.js', '.jsx'],
},
resolveLoader: {
},
plugins: [
new CleanWebpackPlugin(['public/dist'], {
verbose: true,
dry: false,
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
output: {
comments: false,
},
compress: {
warnings: false,
screw_ie8: true,
},
}),
new SaveAssetsJson({
path: process.cwd(),
filename: 'assets.json',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
],
query: {presets: ['es2015', 'react'] },
module: {
rules: [
{
use: [
"style-loader",
"css-loader",
"autoprefixer-loader",
]
},
{
test: /\.scss$/, // sass files
loader: 'style!css!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded',
},
{
test: /\.(ttf|eot|svg|woff)(\?[a-z0-9]+)?$/, // fonts files
loader: 'file-loader?name=[path][name].[ext]',
},
{
test: /\.jsx?$/, // react files
exclude: /node_modules/,
loaders: ['babel?presets[]=es2015,presets[]=stage-0,presets[]=react'],
include: path.join(__dirname, 'assets'),
},
],
noParse: /\.min\.js/,
}
};
In the end there were few deletion of the deprecated plugin calls and restructuring some of the fields. Here is the 2.6.1 compatible version, the parts of the file that were changed:
'use strict';
module.exports = {
devtool: '#source-map',
// Capture timing information for each module
profile: false,
// Switch loaders to debug mode
//debug: false,
// Report the first error as a hard error instead of tolerating it
bail: true,
entry: [
'babel-polyfill',
'./assets/main.jsx',
],
output: {
path: '/public/dist/', //This has to be an absolute path
publicPath: '/dist/',
filename: 'bundle.[hash].min.js',
},
resolve: {
//merging root and modules
modules: [
path.join(__dirname, ''),
'web_modules',
'node_modules',
'assets',
'assets/components',
],
extensions: [ '.webpack.js', '.web.js', '.js', '.jsx'], //Removed empty entry
},
resolveLoader: {
},
plugins: [
new CleanWebpackPlugin(['public/dist'], {
verbose: true,
dry: false,
}),
new webpack.optimize.UglifyJsPlugin({
minimize: true,
sourceMap: true, //added this
output: {
comments: false,
},
compress: {
warnings: false,
screw_ie8: true,
},
}),
new SaveAssetsJson({
path: process.cwd(),
filename: 'assets.json',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production'),
},
}),
],
module: {
//Modules are slightly differently listed now
rules: [
{
test: /\.(css|scss)$/,
use: [{
loader: "style-loader" // creates style nodes from JS strings
}, {
loader: "css-loader" // translates CSS into CommonJS
}, {
loader: "sass-loader" // compiles Sass to CSS
}]
},
{
test: /\.(js|jsx)$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015', "stage-0", 'react']
}
}
}
],
noParse: /\.min\.js/,
}
};

Add loader for React-Flexbox-Grid into Webpack2 config

I have tried endlessly to integrate a loader for React-Flexbox-Grid into my web pack config (shown below), but I receive error:
errors — client:119./~/flexboxgrid/dist/flexboxgrid.css
Module parse failed: /Users/---project-path---/node_modules/flexboxgrid/dist/flexboxgrid.css Unexpected token (1:0)
You may need an appropriate loader to handle this file type.
This is the first time I have had to add in something like this, so I am not sure if I have been adding the 'include: /flexboxgrid/' in the correct place (I added it under the development/production rules), but it just returns the same error! Clearly what I am doing is wrong.
ps. I am using react-redux-webpack2-boilerplate
const webpack = require('webpack');
const path = require('path');
const DashboardPlugin = require('webpack-dashboard/plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const autoprefixer = require('autoprefixer');
const nodeEnv = process.env.NODE_ENV || 'development';
const isProduction = nodeEnv === 'production';
const jsSourcePath = path.join(__dirname, './source');
const buildPath = path.join(__dirname, './build');
const imgPath = path.join(__dirname, './source/assets/img');
const sourcePath = path.join(__dirname, './source');
if (process.env.NODE_ENV == "production") {
var env = JSON.stringify(require("./production-env.js"));
} else {
var env = JSON.stringify(require("./development-env.js"));
}
// Common plugins
const plugins = [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor-[hash].js',
}),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(nodeEnv),
APPDATA: env,
},
}),
new webpack.NamedModulesPlugin(),
new HtmlWebpackPlugin({
template: path.join(sourcePath, 'index.html'),
path: buildPath,
filename: 'index.html',
}),
new webpack.LoaderOptionsPlugin({
options: {
postcss: [
autoprefixer({
browsers: [
'last 3 version',
'ie >= 10',
],
}),
],
context: sourcePath,
},
}),
];
// Common rules
const rules = [{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
'babel-loader',
],
},
{
test: /\.(png|gif|jpg|svg)$/,
include: imgPath,
use: 'url-loader?limit=20480&name=assets/[name]-[hash].[ext]',
},
];
if (isProduction) {
// Production plugins
plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
conditionals: true,
unused: true,
comparisons: true,
sequences: true,
dead_code: true,
evaluate: true,
if_return: true,
join_vars: true,
},
output: {
comments: false,
},
}),
new ExtractTextPlugin('style-[hash].css')
);
// Production rules
rules.push({
test: /\.scss$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: 'css-loader!postcss-loader!sass-loader',
}),
});
} else {
// Development plugins
plugins.push(
new webpack.HotModuleReplacementPlugin(),
new DashboardPlugin()
);
// Development rules
rules.push({
test: /\.scss$/,
exclude: /node_modules/,
use: [
'style-loader',
// Using source maps breaks urls in the CSS loader
// https://github.com/webpack/css-loader/issues/232
// This comment solves it, but breaks testing from a local network
// https://github.com/webpack/css-loader/issues/232#issuecomment-240449998
// 'css-loader?sourceMap',
'css-loader',
'postcss-loader',
'sass-loader?sourceMap',
],
});
}
module.exports = {
devtool: isProduction ? 'eval' : 'source-map',
context: jsSourcePath,
entry: {
js: './index.js',
vendor: [
'babel-polyfill',
'es6-promise',
'immutable',
'isomorphic-fetch',
'react-dom',
'react-redux',
'react-router',
'react',
'redux-thunk',
'redux',
],
},
output: {
path: buildPath,
publicPath: '/',
filename: 'app-[hash].js',
},
module: {
rules,
},
resolve: {
extensions: ['.webpack-loader.js', '.web-loader.js', '.loader.js', '.js', '.jsx'],
modules: [
path.resolve(__dirname, 'node_modules'),
jsSourcePath,
],
},
plugins,
devServer: {
contentBase: isProduction ? './build' : './source',
historyApiFallback: true,
port: 3000,
compress: isProduction,
inline: !isProduction,
hot: !isProduction,
host: '0.0.0.0',
stats: {
assets: true,
children: false,
chunks: false,
hash: false,
modules: false,
publicPath: false,
timings: true,
version: false,
warnings: true,
colors: {
green: '\u001b[32m',
},
},
},
};
Its better to transform class properties.This kind of loader will help to solve this
{
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
loader: 'babel-loader',
query: {
presets: ['react', 'es2015', 'stage-0'],
plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy'],
}
}

Resources