webpack-dev-server doesn't update HTML auto? - javascript

I'm using webpack-dev-server with webpack v5 and for a reason when I made changes in my CSS and js it updated on time as expected but for HTML files I have to refresh my browser manually to see the new complied version .
src
|-index.html
|-index.js
webpack.config.js
const path = require("path");
const htmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: "development",
output: {
clean: true,
filename: "bundel.js",
path: path.resolve(__dirname, "dist"),
},
plugins: [
new htmlWebpackPlugin({
filename: "index.html",
template: path.resolve(__dirname, "src", "index.html"),
}),
],
};
my package.json devDependencies
"devDependencies": {
"html-webpack-plugin": "^5.5.0",
"webpack": "^5.70.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.4"
}
I start my server with npx webpack serve --open
I added CSS file and its relative CSS loaders for testing and removed it after I make sure it work and just HTML is the problem
you can replicate the problem when you change the index.html content

The problem is webpack-dev-server doesn't watch HTML files by default
so I found two solutions for this :
The first solution is built-in throw devServer by adding watchFiles:
devServer: {
watchFiles: ["src/*.html"],
hot: true,
},
The second solution using an external plugin called browser-sync-webpack-plugin

Try to use the DevServer option to reload the page and compress all.
Instead of running npx webpack serve --open run npm run start using this script config:
"scripts": {
"start": "webpack-dev-server",
"build": "webpack",
"test": "echo \"Error: no test specified\" && exit 1"
},
And try to use this base config for your webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
// Default settings
mode:'development',
devtool:'inline-source-map',
entry:{
main: path.join(__dirname,'src','index.js')
},
output:{
filename:'index.js',
path: path.resolve(__dirname,'dist'),
clean:true,
},
// Loaders
module:{
// JavaScript
rules:[
{
test: /\.js$/i,
use:{
loader:'babel-loader',
options:{
"presets":['#babel/preset-react']
}}
},
// Css
{
test: /\.css$/i, use:['style-loader','css-loader']
}
]
},
// Plugins
plugins:[
new HtmlWebpackPlugin({
template: path.join(__dirname,'public','index.html') ,
filename:'index.html'
})
],
// DevServer
devServer:{
port:8080,
open:true,
compress:true,
hot:true,
liveReload:true,
}
};

Related

Remove console on browser when loading react app with npm start via webpack-dev-server

So after npm build and npm run , why does my react application open with console on the screen? It was not happening when my packages were "webpack-cli": "^4.2.0" and "webpack-dev-server": "^3.11.1". Upgrading them is causing this issue. How can we fix this?
My package.json contains (devDependencies)
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^7.0.0",
"webpack": "^5.11.0",
"webpack-bundle-analyzer": "^4.3.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.7.3",
"webpack-manifest-plugin": "2.2.0",
"webpack-merge": "^5.7.2"
"eslint-webpack-plugin": "^2.1.0",
"html-webpack-plugin": "5.3.2",
"scripts": {
"start": "webpack serve --config config/webpack.config.js --env TARGET_ENV=development --env app=web --port 3000",
"build": "webpack --config config/webpack.config.js --env TARGET_ENV=production",
"build:staging": "webpack --config config/webpack.config.js --env TARGET_ENV=staging"
}
webpack.config.js
const { merge } = require("webpack-merge");
//const commonConfig = require("./webpack.common.js");
const paths = require("./paths");
const webpack = require("webpack");
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ESLintPlugin = require("eslint-webpack-plugin");
const getClientEnvironment = require("./env");
module.exports = (env) => {
const targetEnv = env.TARGET_ENV;
const mode = targetEnv === "development" ? "development" : "production";
process.env.NODE_ENV = mode;
// Source maps are resource heavy and can cause out of memory issue for large source files.
// const shouldUseSourceMap = webpackEnv === "development";
const commonConfig = {
mode: mode,
// Where webpack looks to start building the bundle
entry: {
web: paths.src + "/web.tsx",
},
// Where webpack outputs the assets and bundles
resolve: {
extensions: [".tsx", ".ts", ".js"],
fallback: {
util: require.resolve("util/"),
},
modules: ["node_modules", "./src"],
},
// Customize the webpack build process
plugins: [
new webpack.ProvidePlugin({
process: "process/browser",
}),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV is set to production
// during a production build.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(getClientEnvironment(targetEnv).stringified),
new webpack.IgnorePlugin({
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
// Removes/cleans build folders and unused assets when rebuilding
new CleanWebpackPlugin(),
// Copies files from target to destination folder
new CopyWebpackPlugin({
patterns: [
{
from: paths.public,
to: paths.build,
globOptions: {
ignore: ["**/*.html"],
},
},
{
from: paths.appPath + "/web.config",
to: paths.build,
},
],
}),
// Generates an HTML file from a template
// Generates deprecation warning: https://github.com/jantimon/html-webpack-plugin/issues/1501
new HtmlWebpackPlugin({
//favicon: paths.src + "/images/favicon.png",
template: paths.public + "/web.html", // template file
chunks: ["vendor", "web"],
filename: "web.html", // output file
inject: true,
}),
new HtmlWebpackPlugin({
template: paths.public + "/crossplatform.html", // template file
chunks: ["vendor", "crossplatform"],
filename: "crossplatform.html", // output file
inject: true,
}),
new ESLintPlugin({
// Plugin options
extensions: ["js", "jsx", "ts", "tsx"],
}),
],
// Determine how modules within the project are treated
module: {
rules: [
// JavaScript: Use Babel to transpile JavaScript files
{
test: /\.(ts|js)x?$/,
include: paths.src,
//exclude: /node_modules/,
loader: "babel-loader",
options: {
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
// Babel sourcemaps are needed for debugging into node_modules
// code. Without the options below, debuggers like VSCode
// show incorrect code and set breakpoints on the wrong lines.
//sourceMaps: shouldUseSourceMap,
//inputSourceMap: shouldUseSourceMap,
},
},
// Images: Copy image files to build folder
{ test: /\.(?:ico|gif|png|jpg|jpeg)$/i, type: "asset/resource" },
// Fonts and SVGs: Inline files
{ test: /\.(woff(2)?|eot|ttf|otf|svg|)$/, type: "asset/inline" },
],
},
};
const envConfig = require(`./webpack.${mode}.js`)({ app: env.app });
return merge(commonConfig, envConfig);
};
webpack.development.js
const webpack = require("webpack");
const paths = require("./paths");
module.exports = (args) => {
return {
// Control how source maps are generated
devtool: "cheap-module-source-map",
output: {
//path: paths.build,
publicPath: "./",
filename: "[name].js",
},
// Needed because of an issue with webpack dev server HMR with Webpack https://github.com/webpack/webpack-dev-server/issues/2758
target: "web",
// Spin up a server for quick development
devServer: {
historyApiFallback: {
index: "/" + args.app + ".html",
},
open: true,
devMiddleware: {
publicPath: "/",
},
hot: true,
// By default files from `contentBase` will not trigger a page reload.
// watchContentBase: true,
},
module: {
rules: [
// Styles: Inject CSS into the head with source maps
{
test: /\.(css)$/,
use: [
"style-loader",
{
loader: "css-loader",
//options: { sourceMap: true },
},
],
},
],
},
};
};

Cannot resolve module in sibling directory

Good day all!
I am trying to setup a javascript workspace including the posibility to run test script using npm, webpack (and mocha for tests).
So my project structure looks someting like (npm generated files are omitted):
root
|- src
| |- main.js
| |- MyClass.js
|- test
| |- test.js
|- package.json
|- webpack.config.js
The main.js script is building and debugging fine. But the test script is giving me problems.
In short, I import classes from the project (from the src directory) for testing. But it cannot resolve it (eventhough intellisense of vscode is having no issues at all). So if my test-script looked something like:
import { MyClass } from 'MyClass'
/* testing stuff */
Intellisense is perfectly capable of resolving the location (as configured in the jsconfig.json), but eventhough I set the src directory as include-rule or as alias, webpack is not able to resolve it and tries to search in the /test directory instead (and in recursive order all its parent-directories, failing in the same manner).
So the question is how to let webpack resolve for 'nephew' directories?
(If there is an easier way to use mocha than with the current combined scripts, it would suffice in this case as well. So feedback on that is also welcome, but I defenitly would love to find the answer to the original question)
Here is the webpack.config.js content
const path = require('path');
{
name: "myProject_test",
mode: "development",
entry: path.resolve(__dirname, "./test/test.js"),
devtool: 'source-map' : '',
output:
{
clean: { dry: true },
path: path.resolve(__dirname, root, source.outputDir),
filename: "[id]/[name].js",
},
module:
{
rules:
[
{
test: /.jsx?$/,
include: [path.resolve(__dirname, "./test"), path.resolve(__dirname, "./src")],
exclude: [path.resolve(__dirname, "./dist"), path.resolve(__dirname, "./test/test-dist"), path.resolve(__dirname, "./node_modules")],
loader: 'loader-type',
options: { /* All loader types follow this pattern; so the rest is omited for brevety, but basically this includes all the loaders required for correct compiling */ }
}
],
},
resolve:
{
alias:
{
"*": [path.resolve(__dirname, "./src/*"), path.resolve(__dirname, "./test/*")],
},
extensions: ['.json', '.js', '.jsx', '.scss', '.sass', '.html', '.htm']
},
devServer:
{
contentBase: [path.resolve(__dirname, "./test"), path.resolve(__dirname, "./test/test-dist")],
/* Other server properties to make this work with server utility */
}
}
And here the package.json file content
{
"name": "MyProject",
"version": "0.0.1",
"description": "some description",
"dependencies": {},
"scripts": {
"test": "webpack && mocha test/test-dist --require source-map-support/register --reporter spec --check-leaks --recursive && rm -rf test/test-dist",
"debug": "webpack serve",
"start": "webpack --watch",
"build": "webpack"
},
"devDependencies": {
"#babel/core": ">=7.x",
"#babel/preset-env": ">=7.x",
"babel-loader": ">=8.x",
"cross-env": ">=7.x",
"css-loader": ">=6.x",
"html-loader": ">=2.x",
"resolve-url-loader": ">=4.x",
"style-loader": ">=3.x",
"sass-loader": ">=12.x",
"sass": ">=1.x",
"mini-css-extract-plugin": ">=2.x",
"extract-loader": ">=5.x",
"webpack": ">=5.x",
"webpack-cli": ">=4.x",
"webpack-dev-server": ">=3.x",
"worker-loader": ">=3.x",
"source-map-support": ">=0.x",
"mocha": ">=8.x",
"should": ">=13.x"
}
}

How to auto-rebuild bundle with webpack-dev-server without run command again?

I'm a newbie in webpack and I'm using webpack 4 for my project. But I have a problem, I have some file scripts. In the first time to build with webpack dev server, it's run okay. But when server running, I continue create a new file script(example: c.js), rename or delete the exist file the server not auto build this script to main.js. How can automatic webpack rebuild my new file(c.js) to main.js without run command again?
This is my repo on github:
https://github.com/aiduc93/webpack4-scss-pug-es6
You can follow this step to reproduce my problem:
Step 1: start server with 'npm run dev' and run localhost:3000 in browser.
Step 2: when server running, we create new file(c.js), you can copy my code in hide.js or show.js and change the pluginName to 'anything'(ie: pluginName='clickable')
Step 3: go to index.pug, create new p tag with data-clickable(ie: p(data-clickable) clickable)
Step 4: refresh page in browser and click to text clickable. Js will not run because it not recompile.
This is my structure
//folder javascript in project
javascript
| hide.js
| show.js
| server.js
//folder dist after build
dist
| main.js
This is script in package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "webpack-dev-server --inline --hot",
"build": "webpack --mode production"},
This is webpack.config.js
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const WebpackMd5Hash = require('webpack-md5-hash');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
module.exports = {
entry: { main: glob.sync('./src/**/*.js*')} ,
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
},
devtool: 'inline-source-map',
watch: true,
module: {
rules: [
{
test: /\.pug$/,
use: ["html-loader", "pug-html-loader"]
},
{
test: /\.js$/,
exclude: /node_modules/,
use: ["babel-loader"]
},
{
test: /\.scss$/,
use: ExtractTextPlugin.extract(
{
fallback: 'style-loader',
use: [ 'css-loader', 'sass-loader']
})
},
{
type: 'javascript/auto',
test: /\.json$/,
use: [
{
loader: 'file-loader',
options: {
name: "./plugin-config/[name].[ext]"
}
}
]
}
]
},
devServer: {
contentBase: path.join(__dirname, "dist"),
compress: true,
inline: true,
port: 3000,
// historyApiFallback: true,
hot: true
},
plugins: [
new ExtractTextPlugin(
{ filename: 'style.css'}
),
new CleanWebpackPlugin('dist', { watch: true,
}),
new HtmlWebpackPlugin({
inject: false,
hash: true,
template: './src/index.html',
}),
new WebpackMd5Hash(),
]
};
In webpack 4 only real entry-points are entry-points, this means, no vendor-scripts, plugins...in entry.
You cannot use glob here beause it creates an array of all js-files and only server.js is your real entry-point for your application!
Adding a js-file to your wp project doesn't mean it will be compiled as you don't reference it anywhere, so wp cannot know that it is needed.
WP creates a dependency graph starting from the dependencies of your entry-point(s) and creates the bundle(s).
Your server.js is your entry-point and should look like this:
import "../stylesheets/style.scss";
import $ from 'jquery';
import "./clickable" // without import no recompile!
import "./hide"
import "./show"
console.log("his");
console.log("hello, world23");
The entry-point in your webpack.config.js:
module.exports = {
entry: {
main: path.resolve(__dirname, "./src/javascripts/server.js")
},

How to put React in production mode?

I tried using the solution from here but the icon is still read indicating dev mode.
Here is my current file with updates from the answer below:
const path = require('path');
const SRC_DIR = path.join(__dirname, '/client-react/src');
const DIST_DIR = path.join(__dirname, '/client-react/dist');
const webpack = require('webpack')
module.exports = {
entry: `${SRC_DIR}/index.jsx`,
output: {
filename: 'bundle.js',
path: DIST_DIR
},
plugins: [
new webpack.DefinePlugin({'process.env': {NODE_ENV: JSON.stringify('production')} })
],
module: {
loaders: [
{
test: /\.jsx?/,
include: SRC_DIR,
loader: 'babel-loader',
query: {
plugins: ["transform-object-rest-spread", "transform-class-properties"],
presets: ['react', 'es2015']
}
}
]
}
};
If you use Webpack 4, you don't need to change webpack.config.js. It remains the same in both development and production modes.
The only thing needed is in your package.json:
"scripts": {
"dev": "webpack --mode development",
"build": "webpack --mode production"
}
Having this, to create a development bundle:
npm run dev
Production bundle:
npm run build
When you want to build your app in production mode, you should use webpack production shortcut. Like this:
webpack -p
This will enable webpack optimize options to minify your JS. See more detailed explanation of webpack flags on this SO answer.
Webpack plugins need to be put under the plugins key in module.exports.
https://webpack.github.io/docs/using-plugins.html#built-in-plugins
Try this:
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': { NODE_ENV: JSON.stringify('production') }
}),
]
}
Had the same error so to fix it I did this:
package.json
"scripts": {
"build": "NODE_ENV=production webpack --progress --colors",
"start": "NODE_ENV=development webpack-dev-server --progress --colors"
}
webpack.config.js
const env = process.env.NODE_ENV
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(env)
})
]
}
It should work for sure.
Here I have some configuration that you can try to optimize your build.
This worked for me: run npm run build followed by npm install -g serve and serve -s build

index.html using webpack-dev-server not reload

When I change my app.js and main.css while webpack-dev-server is running, the bundle is updated.
But when i change the index.html the content is not refreshed; if I add a line to the HTML, the webpack-dev-server does not refresh anything on the page.
Here are my webpack.config.js and package.json files.
I hope you can help me.
webpack.config.js:
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var CleanWebpackPlugin = require('clean-webpack-plugin');
var chalk = require('chalk');
var env = process.env.WEBPACK_ENV;
var host = 'localhost';
var port = '8080';
var config = {
devtool: 'source-map',
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://' + host + ':' + port +'/',
'./src/app.js'
],
output: {
path: __dirname + '/dist',
filename: 'bundle.js'
},
module : {
loaders: [
{ test: /\.css$/, loader: 'style-loader!css-loader' },
{ test: /\.html$/,loader: 'file?name=[name].[ext]' }
]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new CleanWebpackPlugin(['dist'], {
root: __dirname,
verbose: true,
dry: false
})
]
};
if (env === 'dev') {
new WebpackDevServer(webpack(config), {
contentBase: './dist/',
stats: {colors: true},
hot: true,
debug: true
}).listen(port, host, function (err, result) {
if (err) {
console.log(err);
}
});
console.log('-------------------------');
console.log(chalk.bold.white('Local web server runs at ') + chalk.green('http://' + host + ':' + port));
console.log('-------------------------\n\n');
}
module.exports = config;
package.json:
{
"name": "webpack-skeleton",
"version": "1.0.0",
"description": "webpack skeleton",
"main": "bundle.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "WEBPACK_ENV=dev ./node_modules/.bin/webpack --watch --inline"
},
"author": "Jose Roa",
"license": "ISC",
"devDependencies": {
"chalk": "^1.1.3",
"clean-webpack-plugin": "^0.1.9",
"css-loader": "^0.23.1",
"file-loader": "^0.8.5",
"style-loader": "^0.13.1",
"webpack": "^1.13.0",
"webpack-dev-server": "^1.14.1"
}
}
My directory structure:
css
main.css
dist
bundle.js
bundle.js.map
index.html
node_modules
src
app.js
sum.js
package.json
index.html
node_modules
webpack.config.js
Every file inside the dist directory is generated by webpack.
add the HtmlWebpackPlugin
link: https://www.npmjs.com/package/html-webpack-plugin
add
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './index.html'
})
]
};
It can be due to your IDE -- see webpack dev server
Working with editors/IDEs supporting “safe write”... This behaviour causes file watcher to lose the track because the original file is removed. In order to prevent this issue, you have to disable “safe write” feature in your editor.
You can try this workaround for auto reloading while developing an app. Add to your entry point ('./src/app.js'):
require('../index.html'); //workround to reload page on index.html changes

Categories

Resources