I have been struggling with an issue with hot reloading where making edits in certain files would reload the app without those changes.
My initial solution was to update webpack and related modules. The first module I updated was webpack-dev-server. I went from v3 to v4 which immediately broke the app. All images and json files were getting 404'd when running the dev server.
Here is the original package.json:
{
...
"scripts": {
"dev": "set NODE_ENV=development && webpack serve --config config/webpack.dev.js --open",
"build": "set NODE_ENV=production && webpack --config config/webpack.prod.js",
"beatmarkers": "babel-node fetchAndFormatData/fetchAndFormatBeatMarkers.js"
},
"devDependencies": {
"#babel/cli": "^7.14.3",
"#babel/core": "^7.14.3",
"#babel/node": "^7.14.2",
"#babel/preset-env": "^7.14.4",
"clean-webpack-plugin": "^4.0.0-alpha.0",
"css-loader": "^5.2.6",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.3.1",
"lodash.clonedeep": "^4.5.0",
"node-fetch": "^2.6.1",
"node-sass": "^6.0.0",
"sass-loader": "^11.1.1",
"style-loader": "^2.0.0",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^3.11.2",
"webpack-merge": "^5.7.3"
},
"dependencies": {
"bezier-easing": "^2.1.0",
"howler": "^2.2.3",
"pixi.js": "^6.2.0"
}
}
Here are the original webpack config files:
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/app.js',
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../src/template.html')
})
],
module: {
rules: [
{
test: /\.(png|jpe?g|gif|svg|ico|pvr|mp3|fnt)$/,
type: 'asset/resource'
},
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader']
}
]
}
};
const { merge } = require('webpack-merge');
const common = require('./webpack.common');
module.exports = merge(common, {
mode: 'development',
devServer: {
historyApiFallback: true,
},
output: {
publicPath: '/'
},
devtool: "source-map"
});
This configuration produces a sources structure in chrome that looks like this:
localhost:8080
main.js
(index)
assets/images
animations
fonts
interface
When I updated webpack-dev-server to the latest version, 4.11.1, the assets/images folder no longer exists. I haven't be able to figure out how to get it back. Any help would be deeply appreciated.
Related
Below is the repo, I used to load a React Application
https://github.com/kannanagasamy/react-app-without-cra
Is there a way to change the way, webpack uses ./index.js to some path like './src/index.js'?
I tried using Entry point and pointed it to './src/index.js', but it's not working and webpack is still considering index.js on root folder instead of ./src/index.js
Can somebody help me, where I am going wrong in letting webpack consider index.js inside src folder as base file.
My Current Package.Json
"scripts": {
"build": "Webpack ."
},
"devDependencies": {
"#babel/cli": "^7.18.10",
"#babel/core": "^7.19.1",
"#babel/eslint-parser": "^7.19.1",
"#babel/plugin-transform-runtime": "^7.19.1",
"#babel/preset-env": "^7.19.1",
"#babel/preset-react": "^7.18.6",
"#babel/runtime": "^7.19.0",
"babel-loader": "^8.2.5",
"eslint": "^8.23.1",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-jest": "^27.0.4",
"path": "^0.12.7",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
},
"dependencies": {
"path": "^0.12.7",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"#babel/cli": "^7.17.0"
}
My Current Webpack.config.file
module.exports={
mode: "development",
entry: "./index.js",
output: {
path: path.resolve(__dirname, "public"),
filename: "main.js"
},
target: "web",
resolve: {
extensions: ['.js','.jsx','.json']
},
module:{
rules: [
{
test: /\.(js|jsx)$/, //kind of file extension this rule should look for and apply in test
exclude: /node_modules/, //folder to be excluded
use: 'babel-loader' //loader which we are going to use
}
]
}
}
After updating entry point as mentioned below also, I couldn't able to move webpack to drive based on src/index.js
Codes Used
entry: path.resolve(__dirname, "src/index"),
entry: "src/index",
entry: path.resolve(__dirname, "src/index.js"),
entry: "src/index.js"
Thanks in Advance..
It seems like the issue around the command build you use which is webpack ., the option . is likely to mention the entry point at current dir ./index.js and then override the one in the configuration file so what you need to move index.js back to src/index.js and resolve the import accordingly again. Finally update the entry as you did ./src/index.js and remove . on as webpack cli.
{
build: 'webpack' // don't need to take any more extra arg
}
Forgive me for getting long content to explain my problem.
I made a simple npm vue3-helloword-webpack plugin. This plugin consoles the simple text from inside the onMounted method.
If I bundle this helloworld plugin using vue-cli tool, the callback of onMounted from plugin would be triggered. But same does not happen while bundling by webpack.
I think the problem is occurred because of currenIntance(I guess it’s a vue instance) is null as shown in below image.
Content: when the plugin is bundled by webpack
Webpack.config.babel.js
const TerserPlugin = require("terser-webpack-plugin")
const libraryNamePlugin = 'vue3-helloworld-webpack';
const appConfig = {
entry: {
'vue3-helloworld-webpack': __dirname + '/src/index.js',
'vue3-helloworld-webpack.min': __dirname + '/src/index.js'
},
devtool: 'source-map',
output: {
path: __dirname + '/dist',
filename: '[name].js',
library: libraryNamePlugin,
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /(\.jsx|\.js)$/,
loader: 'babel-loader',
exclude: /(node_modules|bower_components)/
},
{
test: /(\.jsx|\.js)$/,
loader: 'eslint-loader',
exclude: /node_modules/
}
]
},
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
include: 'vue3-helloworld-webpack.min.js',
}),
],
},
};
module.exports = [appConfig];
package.json
....
"main": "dist/vue3-helloworld-webpack.js",
"scripts": {
"build": "webpack --config webpack.config.babel.js"
},
"dependencies": {
"core-js": "^3.6.5"
},
"devDependencies": {
"#babel/core": "^7.14.3",
"#babel/preset-env": "^7.14.4",
"#babel/register": "^7.13.16",
"babel-eslint": "^10.1.0",
"babel-loader": "^8.2.2",
"babel-plugin-add-module-exports": "^1.0.4",
"babel-preset-es2015": "^6.24.1",
"chai": "^4.3.4",
"eslint": "^7.27.0",
"eslint-loader": "^4.0.2",
"lodash": "^4.17.21",
"mocha": "^8.4.0",
"terser-webpack-plugin": "^5.1.3",
"vue": "^3.0.0",
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0",
"webpack-dev-server": "^3.11.2",
"yards": "^0.1.4"
}
....
vue3-helloworld-webpack.js
import {onMounted, h} from 'vue'
const config = { msg: String }
export default {
name: 'vue3-helloworld-webpack',
props : config,
setup(props) {
console.log("setup() is invoked")
console.log(props.msg);
onMounted(function () {
console.log("Hooray!!! Onmounted() is triggered")
});
},
render() {
return h('div', {
id: 'helloworld-1'
});
}
}
src/index.js
import vue3helloworldwebpack from './vue3-helloworld-vuewebpack';
const install = (app) => {
app.component(vue3helloworldwebpack.name, vue3helloworldwebpack);
};
export default install;
Result: when the plugin is used by other very simple vue app
Content when the plugin bundled by Vue-cli
package.json
....
"main": "dist/vue3-helloworld-vuecli.umd.js",
"scripts": {
"build": "vue-cli-service build --formats umd --target lib ./src/index.js"
},
"dependencies": {
"core-js": "^3.6.5"
},
"devDependencies": {
"#vue/cli-plugin-babel": "^4.5.6",
"#vue/cli-plugin-eslint": "^4.5.6",
"#vue/cli-plugin-unit-jest": "^4.5.6",
"#vue/cli-service": "^4.5.6",
"#vue/compiler-sfc": "^3.0.0-rc.10",
"#vue/test-utils": "^2.0.0-beta.5",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.3.0",
"eslint": "^7.9.0",
"eslint-config-prettier": "^8.1.0",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-vue": "^7.0.0-0",
"husky": "^6.0.0",
"prettier": "^2.1.1",
"typescript": "^4.0.2",
"vue": "^3.0.0",
"vue-jest": "^5.0.0-alpha.4"
}
....
Other codes are similar to webpack version except name and webpack config file.
Result
The other simple vue3 app which is using the created plugin(vue3-helloworld-webpack)
Main.js
import { createApp } from 'vue'
import App from './App.vue'
import Vue3HelloworldWebpack from 'vue3-helloworld-webpack'
createApp(App).use(Vue3HelloworldWebpack).mount('#app')
App.vue
<template> <vue3-helloworld-webpack msg="Welcome!!!!" /></template>
We can get created plugins: webpack and vue-cli versions on GitHub.
My question
Vue cli version does work. One interesting thing, the same webpack file configuration is working for vue2 plugin also.
But it does not work for vue 3 plugin, How can I do this without using vue-cli but using webpack version ?
I am learning to use webpack to develop a react project, but I cannot start local services locally. It reports the following error.
ERROR in ./src/index.js 5:16
Module parse failed: Unexpected token (5:16)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| import App from './App';
|
> ReactDOM.render(<App />, document.getElementById('root'));
|
I suspect this is a babel compilation problem, but I have configured babel-loader, but it does not work. I Googled this issue for a long time, but I still didn't find the problem. Can you help me? Thanks!
And this is my configuration files.
// webpack.common.js
const path = require('path');
const commonConfig = {
entry: [
'babel-polyfill',
'../src/index.js'
],
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, 'dist/index.html')
})
],
module: {
rules: [{
test: /\.(jsx?|tsx?)$/,
loader: 'babel-loader',
exclude: /node_modules/,
}]
}
};
module.exports = commonConfig;
// webpack.dev.js
const merge = require('webpack-merge');
const commonConfig = require('./webpack.common.js');
const path = require('path');
const devConfig = merge(commonConfig, {
mode: 'development',
devServer: {
contentBase: path.join(__dirname, 'dist'),
compress: true,
port: 3000
}
})
module.exports = devConfig;
// package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server",
},
"devDependencies": {
"#babel/core": "^7.11.4",
"#babel/preset-env": "^7.11.0",
"#babel/preset-react": "^7.10.4",
"babel-core": "^6.26.3",
"babel-loader": "^8.1.0",
"babel-polyfill": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"html-webpack-plugin": "^4.3.0",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
// .babelrc
{
"presets": ["env", "react"]
}
I found out where the problem was. I didn’t specify the webpack.dev.js file for the npm run start command in the scripts of package.json, and it worked after making the following changes.
"scripts": {
"start": "webpack-dev-server --config webpack/webpack.dev.js",
},
Here is some example render code in a child component of a small react app:
<React.Fragment>
<h1>From Tab Section</h1>
<h2>update 2</h2> // doesn't display in the browser
<p>update 3</p> // also doesn't display
</React.Fragment>
The difference is that after writing the h1 tag I rebuilt Webpack.
Further testing confirmed that rebuilding bundle.js and refreshing the browser on the index.html page it injects into, is the only way to see updates.
I think I have hot reload setup as shown in the docs. And per another SO post I added --inline to the start command. But a manual build and dev server restart is still required.
What else is needed here?
// package.json
"scripts": {
"test": "jest --watch",
"watch": "webpack --watch",
"start": "webpack-dev-server --open --inline",
"build": "webpack"
},
"devDependencies": {
"#babel/core": "^7.4.5",
"#babel/preset-env": "^7.4.5",
"#babel/preset-react": "^7.0.0",
"babel-jest": "^24.8.0",
"babel-loader": "^8.0.6",
"jest": "^24.8.0",
"webpack": "^4.35.0",
"webpack-cli": "^3.3.5",
"webpack-php-loader": "^0.5.0"
},
"dependencies": {
"dotenv": "^8.0.0",
"dotenv-webpack": "^1.7.0",
"history": "^4.9.0",
"lodash": "^4.17.11",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-redux": "^7.1.0",
"react-router-dom": "^5.0.1",
"redux": "^4.0.1",
"save-dev": "^2.0.0",
"webpack-dev-server": "^3.7.2"
}
// webpack.config.js
const webpack = require("webpack");
const dotenvWebpack = require("dotenv-webpack");
const path = require("path");
module.exports = {
entry : {
'./adminSettingsArea' :
'./adminSettingsArea/src/index.jsx'
},
output : {
filename : '[name]/bundle.js',
path : path.resolve(__dirname),
},
devtool: 'inline-source-map',
devServer : {
contentBase : './adminSettingsArea',
hot : true
},
plugins : [
new webpack.HotModuleReplacementPlugin(),
new dotenvWebpack()
],
module : {
rules : [
{
test : /\.(js|jsx)$/,
exclude : [/node_modules/, /vendor/],
use : {
loader : "babel-loader",
options : {
presets : [
'#babel/preset-env',
"#babel/preset-react"
]
},
}
}
],
},
};
Solved by moving the index.html file into the same folder ( ./adminSettingsArea/src ) as the rest of the content webpack updates in memory.
Previously this index file was one level below as was the contentBase value. As a result, webpack was able to load the index.html file initially but not the jsx files in the /src subfolder.
Also, please see the example below for another quirk I ran into with the output path.
entry : {
'adminArea' :
'./adminSettingsArea/src/index.jsx'
},
output : {
filename : 'shared/[name].bundle.js', // for some reason I need to assign the subfolder here instead of arg 2 in the next line
path : path.resolve(__dirname, ''),
},
devtool: 'inline-source-map',
devServer : {
contentBase : './adminSettingsArea/src',
hot : true
},
With my current configuration of node and webpack, I am able to run the dev-server and develop my application.
I am however unable to create the static bundle.js that i could use for a deployment on my website.
How can I configure my webpack.js files and package.json command to make it build the required bundle file ?
When I run npm build, nothing happens
When I run npm deploy, i get the following error message :
Usage: npm <command>
where <command> is one of:
access, add-user, adduser, apihelp, author, bin, bugs, c,
cache, completion, config, ddp, dedupe, deprecate, dist-tag,
dist-tags, docs, edit, explore, faq, find, find-dupes, get,
help, help-search, home, i, info, init, install, issues, la,
link, list, ll, ln, login, logout, ls, outdated, owner,
pack, ping, prefix, prune, publish, r, rb, rebuild, remove,
repo, restart, rm, root, run-script, s, se, search, set,
show, shrinkwrap, star, stars, start, stop, t, tag, team,
test, tst, un, uninstall, unlink, unpublish, unstar, up,
update, upgrade, v, verison, version, view, whoami
npm <cmd> -h quick help on <cmd>
npm -l display full usage info
npm faq commonly asked questions
npm help <term> search for help on <term>
npm help npm involved overview
Specify configs in the ini-formatted file:
C:\Users\Sébastien\.npmrc
or on the command line via: npm <command> --key value
Config info can be viewed via: npm help config
Following is my configuration :
package.json
{
"license": "UNLICENSED",
"private": true,
"version": "1.0.0",
"webPath": "web/",
"nodePath": "node_modules/",
"devDependencies": {
"autoprefixer": "^6.3.1",
"exports-loader": "^0.6.2",
"grunt": "^0.4.5",
"grunt-autoprefixer": "^3.0.3",
"grunt-contrib-concat": "^0.5.1",
"grunt-contrib-cssmin": "^0.14.0",
"grunt-contrib-less": "^1.1.0",
"grunt-contrib-uglify": "^0.11.0",
"grunt-contrib-watch": "^0.6.1",
"grunt-css-url-rewrite": "^0.3.5",
"grunt-cssjoin": "^0.3.0",
"grunt-postcss": "^0.7.1",
"imports-loader": "^0.6.5",
"matchdep": "^1.0.0",
"redux-devtools": "^3.0.2",
"redux-devtools-dock-monitor": "^1.0.1",
"redux-devtools-log-monitor": "^1.0.4",
"webpack-shell-plugin": "^0.4.2"
},
"repository": {
"type": "git",
"url": ""
},
"dependencies": {
"babel-core": "^6.4.0",
"babel-loader": "^6.2.1",
"babel-plugin-transform-runtime": "^6.4.3",
"babel-polyfill": "^6.3.14",
"babel-preset-es2015": "^6.3.13",
"babel-preset-react": "^6.3.13",
"babel-preset-stage-0": "^6.3.13",
"babel-runtime": "^6.3.19",
"grunt-postcss": "^0.7.1",
"history": "^1.17.0",
"i18next": "^2.5.1",
"isomorphic-fetch": "^2.2.1",
"lodash": "^4.11.1",
"radium": "^0.16.2",
"rc-switch": "^1.4.2",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"react-hot-loader": "^1.3.0",
"react-redux": "^4.1.2",
"react-router": "^1.0.3",
"react-router-redux": "^3.0.0",
"redux": "^3.1.6",
"redux-thunk": "^2.1.0",
"selfupdate": "^1.1.0",
"webpack": "^1.12.11",
"webpack-dev-server": "^1.14.1",
"whatwg-fetch": "^0.11.0"
},
"scripts": {
"start": "node webpack.dev-server.js",
"build": "webpack",
"deploy": "NODE_ENV=production webpack -p --config webpack.production.config.js"
}
}
webpack.config.js
var path = require('path');
var webpack = require('webpack');
var node_modules_dir = path.join(__dirname, 'node_modules');
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
console.log(__dirname);
var config = {
entry: [
'babel-polyfill',
'webpack-dev-server/client?http://127.0.0.1:3000',
'webpack/hot/only-dev-server',
'./app/Resources/react/app.js'
],
output: {
path: path.join(__dirname, 'web/js'),
filename: 'bundle.js',
publicPath: 'http://127.0.0.1:3000/static/'
},
debug: true,
devtool: 'eval',
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
devFlagPlugin
],
module: {
loaders: [
{
loaders: ["react-hot","babel-loader?plugins=transform-runtime&presets[]=es2015&presets[]=stage-0&presets[]=react"],
test: /\.js$/,
include: path.join(__dirname, 'app/Resources/react')
}
]
}
};
module.exports = config;
/*
new webpack.ProvidePlugin({
'fetch': 'imports?this=>global!exports?global.fetch!whatwg-fetch'
})
*/
webpack.dev-server.js
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: true,
quiet: false,
noInfo: false,
contentBase: "./assets"
}).listen(3000, 'localhost', function (err, result) {
if (err) {
console.log(err);
}
console.log('Listening at localhost:3000');
});
webpack.production.config.js
var path = require('path');
var node_modules_dir = path.resolve(__dirname, 'node_modules');
var config = {
entry: [
'babel-polyfill',
'./app/Resources/react/app.js'
],
output: {
path: path.join(__dirname, 'web/js'),
filename: 'bundle.js'
},
module: {
loaders: [
{
loaders: ["babel-loader?plugins=transform-runtime&presets[]=es2015&presets[]=stage-0&presets[]=react"],
test: /\.js$/,
include: path.join(__dirname, 'src/react')
}
]
}
};
module.exports = config;
you missed run
npm run deploy
run is required for all scripts. To help with common tasks npm knows how to use several preconfigured scripts such as start and test which is why npm start is an equivalent of npm run start.