Webpack 2 beta + history API fallback not working - javascript

Today, after removing my node_modules and reinstalling them using npm install, my project doesn't seem to work.
Here's my webpack config
const webpack = require('webpack');
const path = require('path');
const srcPath = path.join(__dirname, './client');
const nodeEnv = process.env.NODE_ENV || 'development';
const isProd = nodeEnv === 'production';
module.exports = {
devtool: isProd ? 'hidden-source-map' : 'cheap-module-eval-source-map',
context: path.join(__dirname, './client'),
entry: {
js: './index.js',
vendor: ['react']
},
output: {
path: path.join(__dirname, './static'),
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /\.html$/,
loader: 'file',
query: {
name: '[name].[ext]'
}
},
{
test: /\.scss$/,
loaders: ['style', 'css', 'sass']
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loaders: ['babel-loader']
},
{
test: /\.(png|jpg|gif|otf|eot|svg|ttf|woff|woff2)/,
loader: 'url-loader'
},
{
test: /\.(txt|json)/,
loader: 'raw-loader'
}
],
},
resolve: {
extensions: ['', '.js', '.jsx'],
modules: [
path.resolve('./client'),
'node_modules'
],
alias: {
stores: `${srcPath}/stores/`,
components: `${srcPath}/components/`,
services: `${srcPath}/services`,
models: `${srcPath}/models`,
constants: `${srcPath}/constants`,
sources: `${srcPath}/sources`,
images: `${srcPath}/assets/images`,
appConstants: isProd ? `${srcPath}/constants/_prod` : `${srcPath}/constants/_dev`
}
},
plugins: [
new webpack.IgnorePlugin(/regenerator|nodent|js\-beautify/, /ajv/),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks: Infinity,
filename: 'vendor.bundle.js'
}),
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: isProd
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: !isProd
},
output: {
comments: !isProd
},
sourceMap: !isProd
}),
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify(nodeEnv) }
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.OccurrenceOrderPlugin()
],
devServer: {
contentBase: './client',
hot: true,
port: 3000,
historyApiFallback: true
}
};
My "client" folder with index.html and the rest of my code are in the same folder as webpack config.
Webpack does succesfully build, but going to localhost:3000, I get error message: "Cannot GET /"
Going to localhost:3000/client/index.html does serve my index.html, but my built files inserted using
<script src="./vendor.bundle.js"></script>
<script src="./bundle.js"></script>
doesn't load (GET to "http://localhost:3000/client/bundle.js" results in 404)
Anyone knows what's going on? I can't fix this issue, and I think I've tried everything, from changing path, publicPath to changing contentBase and moving my static files to different folder.
It's very strange, since this issue appeared only after reinstalling my project dependencies.
Every bit of help is much appreciated. Thanks.

There was an issue in webpack-dev-server#2.1.0-beta.3, which caused the contentBase option to be ignored. Could you try upgrading to 2.1.0-beta.4? It was just released.

Related

How to make webpack-dev-server pick up latest changes

I'm using Webpack 5 and cannot set dev-server to pick up the latest changes immediately. That's why when I have any changes in my project I should do yarn build first and then yarn dev every time. I've already seen the same question here Webpack-dev-server doesn't pick up latest changes, but writeToDisk: true shows an error in the console. I've attached my webpack.config.js file.
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const miniCss = require('mini-css-extract-plugin');
module.exports = {
entry: { main: './src/index.js' },
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
publicPath: ''
},
mode: 'development',
devServer: {
static: {
directory: path.join(__dirname, "dist")
},
compress: true,
port: 8080,
devMiddleware: {
publicPath: "//localhost:8080",
},
hot: "only",
open: true
},
module: {
rules: [
{
test: /\.js$/,
use: 'babel-loader',
exclude: '/node_modules/'
},
{
test: /\.pug$/,
loader: 'pug-loader',
options: {
pretty: true
}
},
{
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, {
loader: 'css-loader'
}]
},
{
test: /\.(s*)css$/,
use: [
miniCss.loader,
'css-loader',
'sass-loader',
]
},
{
test: /\.(png|svg|jpg|gif|woff(2)?|eot|ttf|otf)$/,
type: 'asset/resource'
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/pages/page/page.pug',
filename: 'index.html'
}),
new MiniCssExtractPlugin(),
new miniCss(),
]
}
Your issue is most likely with hot: "only". According to https://webpack.js.org/configuration/dev-server/ you will not see a page refresh on build failures if it's not hot: true.
Other than that I don't see anything obviously wrong with your code. I suspect that if you change it to hot: true it should refresh the page and that you have some other build failure.

Webpack 5 Dev server not serving CSS

I have setup a simple webpack 5 config file with a dev server that seems to be working but when I add
<link href="/style.css" rel="stylesheet" />
to the index.html file I get no CSS loading. Currently in dev mode I am choosing to use 'style-loader' over the 'MiniCssExtractPlugin' to enable hot module reloading natively.
any help would be greatly appreciated. There are no errors in the webpack console output just no CSS to call from the HTML file.
Webpack file:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin");
module.exports = (env, options) => {
const mode = options.mode;
return {
context: __dirname,
entry: {
script: './src/index.bundle.ts',
style: './src/index.bundle.less',
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './src/dist')
},
devServer: {
watchFiles: ['src/**/*.less'],
static: {
directory: path.join(__dirname, 'src'),
watch: true,
},
compress: true,
port: 9000,
hot: true,
},
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.tsx', '.js', '.css', '.less']
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css',
ignoreOrder: false,
}),
],
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
target: 'browserslist'
}
}
},
{
test: /\.ts(x)?$/,
loader: 'ts-loader',
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
mode === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
{
loader: 'css-loader',
},
{
loader: 'postcss-loader', // Run postcss actions
options: {
postcssOptions: {
config: path.resolve(__dirname, "postcss.config.js"),
}
}
},
]
},
{
test: /\.less$/,
use: [
mode === 'production' ? MiniCssExtractPlugin.loader : 'style-loader',
'css-loader',
'less-loader'
]
},
]
},
optimization: {
minimize: true,
minimizer: [new TerserPlugin(), new CssMinimizerPlugin()]
},
target: 'web',
}
};
It appears you've misconfigured
static: {
directory: path.join(__dirname, 'src'),
Your output points to src/dist so it looks like it should be this instead
static: {
directory: path.join(__dirname, 'src/dist'),
On a side note, it's an anti-pattern to have compiled files within your source folder. Generally this structure is recommended.
[repo_root]/
dist/
src/

React Toolbox finding ~react-toolbox/lib/colors

Im having some issue trying to setting up the webpack with toolbox.
For some reason i dont know why its not working.
My webpack file looks like:
const path = require('path');
const webpack = require('webpack');
const autoprefixer = require('autoprefixer');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
context: __dirname,
devtool: 'inline-source-map',
entry: {
factigisVE: './static/js/bundles/factigisVE.js',
vendor: [
'webpack-hot-middleware/client'
]
},
output: {
path: path.join(path.join(__dirname, 'dist'), 'js'),
filename: '[name].js',
libraryTarget: "amd",
publicPath: '/'
},
resolve: {
extensions: ['', '.scss', '.css', '.js', '.json','.webpack.js', '.web.js', '.js', '.jsx'],
modulesDirectories: [
'node_modules',
path.resolve(__dirname, './node_modules')
]
},
module: {
loaders: [
{
test: /(\.js|\.jsx)$/,
exclude: /(node_modules)/,
loader: 'babel',
query: { presets: ['es2015', 'stage-0', 'react','stage-2'] }
}, {
test: /(\.scss|\.css)$/,
loader: ExtractTextPlugin.extract('style', 'css?sourceMap&modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass')
}
]
},
externals: [
function(context, request, callback) {
if (/^dojo/.test(request) ||
/^dojox/.test(request) ||
/^dijit/.test(request) ||
/^esri/.test(request)
) {
return callback(null, "amd " + request);
}
callback();
}
],
devServer: {
inline: true,
port: 443,
host: "127.0.0.1",
historyApiFallback: true
},
devtool: 'source-map',
postcss: [autoprefixer],
sassLoader: {
data: '#import "css/index.scss";',
includePaths: [path.resolve(__dirname, './static')]
},
plugins: [
new ExtractTextPlugin('../css/style.css', { allChunks: true }),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production')
})
]
};
And then my index.scss looks like:
#import "~react-toolbox/lib/colors";
$color-primary: $palette-blue-500;
$color-primary-dark: $palette-blue-700;
The errors that im having are:
Error: File to import not found or unreadable: ~react-toolbox/lib/colors
parent style sheet: I:/proyect/ve/static/css/index.scss on line 1 of static/css/index.scss
> #import "~react-toolbox/lib/colors";
Also my directory looks like: my directory
Any help on whats going on will be really appreciate.
Thanks !
I was able to resolve this problem by removing the ~ from the start of the import.
#import "react-toolbox/lib/colors";
The postcss-import plugin appears to have the same behvaior.

Optimize Webpack React Babel - Does it make sense to include only selected plugins for Babel?

This question has two parts:
1.
Is there anything I can do in webpack config file to make my .js file even more compressed? Currently it is 984 kB.
I noticed that adding following plugins, doesn't change anything.
Are they included properly?
plugins: [
'transform-react-remove-prop-types',
'transform-react-constant-elements',
'transform-react-inline-elements'
]
My production config file:
const webpack = require('webpack');
const path = require('path')
const nodeModulesPath = path.resolve(__dirname, 'node_modules');
module.exports = {
context: __dirname,
devtool: 'cheap-module-source-map',
entry: './js/app/index.js',
output: {
path: path.join(__dirname, '/dist/js'),
filename: 'app.js'
},
cache: false,
debug: false,
plugins: [
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('production')
}
}),
new webpack.optimize.DedupePlugin(),
new webpack.optimize.UglifyJsPlugin({
compressor: {
warnings: false
}
})
],
resolve: {
alias: {
components: path.resolve(__dirname, './js/components/'),
app: path.resolve(__dirname, './js/app/'),
Auth: path.resolve(__dirname, './js/features/Auth/'),
DataDisplay: path.resolve(__dirname, './js/features/DataDisplay/'),
Forms: path.resolve(__dirname, './js/features/Forms/'),
},
extensions: ['', '.js', '.jsx', '.es6', '.json'],
},
stats: {
colors: true,
reasons: true,
chunks: false
},
module: {
loaders: [{
test: /\.(jsx|js|es6)?$/,
loader: 'babel-loader',
exclude: [nodeModulesPath],
query: {
presets: ['react', 'es2015'],
plugins: ['transform-react-remove-prop-types',
'transform-react-constant-elements',
'transform-react-inline-elements'
]
}
}, {
test: /\.json$/,
loader: 'json-loader'
}]
}
}
Second question is regarding babel, currently I am using just following ES2015 preset:
{
"presets": ["react", "es2015"],
}
However during "Complete Introduction to React (feat. Redux and React Router)" on Frontend Masters, Brian Holt pointed out that this preset contains a lot of stuff which is not really needed. Does it make sense to include only plugins I know I used?
For example I know I haven't used transform-regenerator (which according to him is a specially big) or transform-es2015-classes. And if it makes sense what is the easiest way to configure babel, without installing all of them separately...

How to handle static assets with webpack server side?

I'm trying to create an universal react app (using webpack both on server and on the client) and struggle with images import. I want to write this :
import someImage from './someImage.png'
const SomeImage = () => <img src={someImage}/>
Here's my webpack config file:
var path = require('path');
var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: [
'webpack-dev-server/client?http://127.0.0.1:8080/',
'webpack/hot/only-dev-server',
'./client',
'babel-polyfill'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
resolve: {
modulesDirectories: ['node_modules', 'shared'],
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loaders: ['babel']
},
{
test: /\.css/,
exclude: /node_modules/,
loader: ExtractTextPlugin.extract('style', 'css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]')
},
{
test: /\.(jpe?g|png|gif|svg)$/i,
loaders: [
'file?emitFile=false',
]
}
]
},
plugins: [
new ExtractTextPlugin('styles.css', { allChunks: true }),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
devtool: 'inline-source-map',
devServer: {
hot: true,
proxy: {
'*': 'http://127.0.0.1:' + (process.env.PORT || 3000)
},
host: '127.0.0.1'
}
};
Obviously it's not working server side because node try to read the content of the ./someImage.png file, resulting in an error.
How can I handle this ? I know there are packages such as webpack-isomorphic-tools or universal-webpack or even the file-loader package that can emit or not the file, but I don't understand of to use it in my universal app.
I'm using file-loader with emitFile: false to exclude assets from bundling on server side. Works as expected.
const imageRules = (emit = true) => ({
test: /\.(png|svg|jpeg|jpg|gif|ico)$/,
type: "asset",
generator: {
emit: emit,
},
});
Then use it in webpack client config:
module: {
rules: [imageRules()],
},
And in server config
module: {
rules: [imageRules(false)],
},

Categories