My project has this structure:
\root
\webpack.config.js
\public
\ index.html
\ ...
\ css
\ directives
\ views
\ dist (webpack output)
\app.js
\ index.html
\ app.js.map
\ style.css
\ style.css.map
when i use webpack-dev-server I launch it from /root and it loads the app. But, when i change a sass file or html file it does not reload. What is wrong with the webpack config?
Command to launch webpack:
$ cd root
$ webpack-dev-server
Webpack.config.js
const path = require('path');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
const webConfig = {
entry: path.join(__dirname, 'public', 'js', 'app'),
output: {
path: path.join(__dirname, 'public', 'dist'),
filename: 'app.js'
},
resolve: {
modules: [__dirname, 'node_modules'],
extensions: ['.js'],
enforceExtension: false,
},
devtool: 'source-map',
devServer:{
contentBase: 'public/',
publicPath: 'public/'
},
module: {
loaders: [
{
test: /\.scss$/,
loader: ExtractTextPlugin.extract({
loader: 'css-loader?modules,localIdentName=[name]__[local]--[hash:base64:5]!sass-loader'
}),
exclude: /node_modules/
},
{
test: /\.html$/,
loader: "raw-loader" // loaders: ['raw-loader'] is also perfectly acceptable.
}
]
},
plugins: [
new ExtractTextPlugin({filename: 'style.css', allChunks: true}),
new HtmlWebpackPlugin({
template: './public/index.html'
})
]
};
module.exports = webConfig;
https://medium.com/#rajaraodv/webpack-the-confusing-parts-58712f8fcad9
“inline” option adds “Live reloading” for the entire page. “hot” option enables “Hot Module Reloading” that tries to reload just the component that’s changed (instead of the entire page). If we pass both options, then, when the source changes, the webpack-dev-server will try to HMR first. If that doesn’t work, then it will reload the entire page.
Try adding this to your webpack.config file:
devServer:{
contentBase: 'public/',
publicPath: 'public/',
inline: true,
hot: true,
},
If you want, you can also call a script from your package.json file. Some thing like that:
...
scripts: {
"watch": "webpack-dev-server --progress --colors --hot --inline",
}
...
https://webpack.js.org/blog/2020-10-10-webpack-5-release/
With webpack 5, you will want to use the option watchFiles:
devServer: {
watchFiles: ["./public/*"], // string [string] object [object]
port: 3000,
open: true,
hot: true,
},
View the official docs about the watchFiles option.
just add the option watchContentBase: true, in your devServer config
stop the current activity and reload the script
devServer: {
contentBase: path.join(__dirname, 'public'),
port: 9000,
open:true,
liveReload: true,
watchContentBase: true,
},
if you have HtmlWebpackPlugin, try to remove it, weback-dev-server/webpack serve can pick the html file under ./public automatically.
Related
I'm new to this webpack thing so I was looking through some Webpack 5 tutorials online and documentation but I don't know how to fix this issue
File Structure:
dist
node_modules
src
modules
js files
style
style.css
index.html
index.js
package.json
package-lock.json
webpack.config.js
Webpack Config:
const { appendFile } = require("fs");
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = {
mode: 'development',
entry: {
main: path.resolve(__dirname,'src/index.js'),
},
output: {
path:path.resolve(__dirname,'dist'),
filename: 'app.bundle.js',
hashFunction: 'xxhash64',
},
devtool: 'inline-source-map',
devServer: {
static: {
directory:path.resolve(__dirname,'dist'),
watch:true,
},
port: 8080,
open: true,
hot: true,
},
//loaders
module: {
rules: [
{test: /\.css$/, use:['style-loader','css-loader']}
]
},
//plugins
plugins: [new HtmlWebpackPlugin({
title: 'To Do List',
filename: 'index.html',
template: path.resolve(__dirname,"./src/index.html")
})]
}
When I run "npm run dev" my webpage opens with the HTML/CSS/JS but nothing changes (no recompiling happens) when I make a change to my code.
Also, another weird problem that occurs is that my import statements get deleted in the index.js file on save, not sure if thats related to this or just a VScode problem
You have a place to correct in your devServer.static.directory: it should be ./, not dist. Here is the set of devServer's settings, which worked out for me:
devServer: {
port: 8080,
hot: "only",
static: {
directory: path.join(__dirname, './'),
serveIndex: true,
},
},
I was struggling with HMR aswell and it is really disappointing to end up with almost nothing, except i got it working with this approach:
devServer: {
port: 8080,
hot: false,
liveReload: true,
watchFiles: ['dist/**/*'],
open: ['http://localhost:8080/html/index.html']
}
basically i switched to liveReload to achieve same result and it works now.
P.S. you don't need to use 'open' but my html is located in dist/html/index.html and i used a link to open window with that html
Im trying to get some server side rendering to work for my react project with yarn, webpack and babel. When I type in yarn watch in the terminal the program compiles correctly and then the localhost window appears, It says "Can not get /". This is because I need a output(I think), but I am unsure as in how to create one correctly.
here below is the code inside my webpack.config.js file:
const path = require("path");
module.exports = {
devServer: {
contentBase: path.resolve(__dirname, "./src" ),
historyApiFallback: true,
writeToDisk: true,
},
entry: path.resolve(__dirname, "./src/index.js" ),
module: {
rules: [
{
test: /\.js$/, exclude: /node_modules/, use:"babel-loader"
},
{
test: /\.css$/i,
use: ["css-loader"]
},
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
use: ["url-loader"]
},
]
},
output: {
path: __dirname + '/dist',
filename: "bundle.js"
},
};
The Bundle.js filename in the output was made in the public folder inside the index.html.
<script src="bundle.js"></script>
Sorry if this made no sense but I dont understand how this does not work correctly.
When I run webpack server, Below config by default opens index.html available in public folder.
so, Instead of index.html, I want to create another.html or may be like a folder inside which an html eg. public/someFolder/another.html and want to open it, when webpack server is run.
how to run a different html file instead of index.html when webpack server runs?
webpack.config.js
const path = require("path");
module.exports = {
entry: "./myFile.js",
output: {
path: path.join(__dirname, "public"),
filename: "bundle.js",
},
module: {
rules: [
{
loader: "babel-loader",
test: /\.js$/,
exclude: /node_modules/,
},
{
test: /\.s?css$/,
use: ["style-loader", "css-loader", "sass-loader"],
},
],
},
devtool: "cheap-module-eval-source-map",
devServer: {
contentBase: path.join(__dirname, "public"),
historyApiFallback: true,
},
};
Have a look at HtmlWebpackPlugin
You can specify a custom path and a custom .html file.
output: {
filename: './dist/subdirectory/myindex.html'
},
plugins: [new HtmlWebpackPlugin()]
The default is of course index.html
I recently changed the name of my root directory (where package.json and webpack.config.js sits) and now webpack-dev-server is not updating anytime I change my files.
Here's my webpack config:
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
var path = require('path');
module.exports = {
context: path.join(__dirname, "src"),
devtool: debug ? "inline-sourcemap" : null,
entry: "./js/init.js",
module: {
loaders: [
{
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'],
}
}
]
},
output: {
path: __dirname + "/src/",
filename: "app.js"
},
plugins: debug ? [] : [
new webpack.optimize.DedupePlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin({ mangle: false, sourcemap: false }),
],
devServer: {
port: 3000,
hot: true,
historyApiFallback: {
index: 'index.html'
}
}
};
And my directory looks like this (Client React is the folder that had its name changed):
Let me clarify that this worked fine before, so I really have no idea why this isn't working now.
Edit: Scripts in package.json
"scripts": {
"dev": "./node_modules/.bin/webpack-dev-server --content-base src --inline --hot",
"build": "webpack"
},
You have to remove the brackets. Probably because they are not properly escaped by the watch module that webpack uses (watchpack) or the part that does the final watching in the System itself. I recommend you don't use any special characters inside directory- or filenames because of such bugs.
So I am using webpack-dev-server and its live reload ability. I am on a windows machine. When I change a js file it seems to be reloading the browser but it doesn't rebuild the bundle. Here is my webpack config file
var webpack = require("webpack");
var path = require('path');
module.exports = {
entry: ['./app/thirdparty', "./app/app.js"],
output: {
filename: "./build/bundle.js",
publicPath: "/assets/"
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.js$/,
exclude: /node_modules/,
loader: "babel-loader"
}]
},
resolve: {
extensions: ['', '.js', '.es6']
},
include: path.join(__dirname, 'app')
}
I've tried to run it with
webpack-dev-server
and
webpack-dev-server --hot
But the bundle is not rebuilt
So I solved my own question.
I had a file looking like :
output: {
filename: "./build/bundle.js",
publicPath: "/assets/"
}
I changed it to
output : {
path: path.resolve('build/js'),
publicPath: "/public/js/",
filename : "bundle.js",
}
Which means it will create a bundle.js that will end up in /build/js/bundle.js
BUT it needs to be referred to in index.html as public/js/bundle.js because of how the publicPath is specified. Also running
webpack-dev-server --inline
Made everything work. Its obvious once you understand web pack I guess...