I have been migrating a project from Webpack 4 up to 5 and have hit a snag. The --watch option is no longer working with my configuration, and I've tried everything I can find.
const webpack = require('webpack');
const path = require('path');
const PATHS = {
build: path.join(__dirname, "dist")
}
const baseConfig = {
entry: {
main: './js/router.js',
},
output: {
path: PATHS.build,
filename: `[name].[chunkhash].js`,
chunkFilename:`[name].[chunkhash].js`,
publicPath: '/dist'
}
//loaders and stuff
}
module.exports = baseConfig;
webpack --watch --progress --mode development
This is what the config can be boiled down to cause the issue. Webpack builds initially fine and I can view the page locally.
But any further changes to the entry point or any modules it imports does not recompile. The progress option I added to the start command has no effect.
I suspect the issue lies with WSL. When I upgraded to webpack 5, I encountered this issue
For some reason webpack 5 tries to scan system files if it is located in /mnt/c and gets locking errors. I ended up settling on this answer and moving where my project was located from /mnt/c/dev to /usr/local/dev. This solved the locking issue, and here I am now.
I have also tried adding to my webpack config:
watchOptions: {
poll: true
}
and also tried playing around with different polling times. Nothing gave me different results.
Related
I have created a simple github repo to reproduce my scenario.
I have 2 config files: dev.vue.config.js and prod.vue.config.js that are used depending on NODE_ENV value
For prod my webpack entry point is set as
configureWebpack: {
entry: {
activitySubmit: './src/as-setup.js'
}
}
and I also use SplitChunks plugin to bundle node_modules into vendors.js so I expect webpack to produce 2 files: activitySubmit.js and vendors.js
However I'm also getting 3rd file app.js which has contents of src/main.js but why ? I'm not specifying it as my entry point and no other file is importing anything from main.js so why is it getting bundled anyway ? I don't need it in prod.
Now, if I change the entry point to
configureWebpack: {
entry: {
app: './src/as-setup.js'
}
}
I get 2 files: app.js and vendors.js
and if I inspect app.js I can see that it now does not contain code from src/main.js (as expected).
I'm confused, please help explain the logic
This question got answered on Vue Forum so I'm posting the answer here as well
Running
vue inspect --mode production
will show the Webpack configuration that Vue CLI is generating. It ends up with:
entry: {
app: [
'./src/main.js'
],
activitySubmit: './src/as-setup.js'
}
because as explained in vue docs, the configuration you provide in configureWebpack is merged using webpack-merge, so the default entry is still present.
I've been using webpack for my latest projects, but I have legacy projects using grunt or gulp or other.
In those cases, I'd still love a bundler like webpack with ultra minimal configs to use ES6 imports and such.
How do I execute a single webpack bundle command from within say gulp or longrunning node script?
I can spawn a subprocess and call webpack but I'm curious how I'd use it in legacy toolchains via JS.
webpack({...}) // does nothing
I found the use of webpack().apply() on some other stack overflow post and webpack does compile once, but not a second time when called within a gulp task.
(function exampleCreateBundle() => {
const compiler = webpack({
entry: './_js/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'js')
}
});
compiler.apply(new ProgressPlugin(function(percentage, msg) {
console.log((percentage * 100) + '%', msg);
}));
// works once
})();
Thanks for any help!
Update:
Honestly, I'm just spawning a child process and running npx webpack.
At this point the question is academic.
I’ve developed an application with a react front end and a node server on the backend. The React dependencies are bundled by webpack into bundle.min.js, but when I put my server.js on a container/VM wherever, how do I ensure its dependences (i.e. express, winston, body-parser, etc) are installed.
npm install --production
will install my production dependences on the server but this will include everything from react, react-dom, d3, etc.
I have tried using a separate webpack configuration to make a server bundle, along the lines of,
{
name: 'server',
target: 'node',
entry: path.resolve(__dirname, 'src', 'server', 'app.js'),
devtool: 'cheap-module-source-map',
output: {
path: path.resolve(__dirname, 'dist', 'server'),
filename: 'server.bundle.js'
}
},
node: {
__dirname: false
}
but when I start the server I am getting a Cannot Get / error.
What is the best method to install only the dependencies related to my express server for a production build?
Unless you are potentially going to run out of file space, I don't think its a problem to have all of your dependencies installed. It certainly makes maintainability simpler vs creating two separate projects. What advantage do you get from trying to only install production packages on your server? Or better yet, what disadvantage is there to having all of them?
I am using in my project:
"webpack": "2.2.1",
"webpack-dev-server": "2.4.2"
and I need to build an application when a file change using webpack-dev-server live reloading.
In my package.json I have this setup:
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack-dev-server --hot --inline"
},
Currently I am able to build the application manually by running:
webpack and I am able to initialize the developer server using npm start.
The problem I am facing is that after npm start and local server runs, if I make some changes in JS files the application is NOT being rebuilded and page is not refreshed automatically. Currently I need to rerun webpack manually all the time in console.
I receive no errors in console, so I suppose is a wrong configuration issue.
Could you please point me out what is wrong in my settings?
// file: webpack.config.js
const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.bundle.js',
},
devServer: {
inline: true,
port: 8080
},
module: {
loaders: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}
]
}
};
webpack-dev-server serves the files from memory.
From readme:
It uses webpack-dev-middleware under the hood, which provides fast in-memory access to the webpack assets.
So it does not write any file to disk and it also works without the files being present on your file system. When you delete the build directory and start the dev server without running webpack before, it should still work. If it doesn't, you don't hit the paths that are served from the dev server and instead are using the files from the file system.
The index.html you're using is probably outside the build directory and therefore you include the bundle like this:
<script src="build/app.bundle.js"></script>
You're requesting /build/app.bundle.js on the server, but webpack-dev-server will only serve /app.bundle.js (because that's the filename you configured). To solve this issue you can configure output.publicPath:
output: {
path: path.resolve(__dirname, 'build'),
filename: 'app.bundle.js',
publicPath: '/build/'
},
This will affect loaders that include assets. If you don't want that, you can set devServer.publicPath instead, but it's recommended to keep them the same.
I'm having a bit of trouble getting the react-hot webpack loader to work correctly.
When I load the page I get the following as I would expect:
[HMR] Waiting for update signal from WDS...
[WDS] Hot Module Replacement enabled.
But when I save a change the page automatically hard refreshes the browser (rather than a HMR replacement).
//webpack.config.js
{
entry: {
client: 'webpack-dev-server/client?http://localhost:8786', // WebpackDevServer host and port
app: "./HelloWorld.tsx"
},
devtool: process.env.WEBPACK_DEVTOOL || 'cheap-module-source-map',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].entry.js'
},
module: {
loaders: [
{
test: /\.ts(x?)$/,
loaders: ['react-hot', 'babel-loader?cacheDirectory=true,presets[]=es2015,presets[]=react', 'ts-loader']
}
]
},
devServer: {
contentBase: "./dist",
port:8786
},
plugins: [
new webpack.NoErrorsPlugin()
]
}
command: webpack-dev-server --hot --inline
on an interesting sidenote if I use babel-preset-react-hmre everything works as expected. (However I don't really want to use this as it seems less supported than the proper react-hot loader).
I just ran into this problem. A couple things:
To help debug your particular issue, try enabling "Preserve log" (in Chrome dev tools). This will persist console logs across page refreshes, so you'll at least be able to see any messages that webpack-dev-server is logging before it triggers a refresh.
In my case webpack-dev-server was refreshing because I had not opted into HMR in my entry js file. Adding the following line to the file solved the issue:
// Opt-in to Webpack hot module replacement
if (module.hot) module.hot.accept()
For details on the module.hot API the webpack HMR docs are very helpful.