So I have the following webpack configuration :
import path from 'path';
module.exports = {
entry: {
index: './dev/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: './dist/',
filename: 'bundle.js',
chunkFilename: '[id].bundle.js'
},
module:{
loader:{
test: /\.js$/,
exclude:path.resolve(__dirname, "node_modules"),
loader: 'js'
}
}
};
The problem is that when I do webpack --watchthe file does build in the /dist/ folder at every change. Yet when I run the webpack-dev-server the files don't even build. Why is that?
Please help.
The reason you are not seeing files emitted into your dist folder is because webpack-dev-server uses an in-memory filesystem
This allows for extremely fast incremental builds when your code changes. This was an intentional design on our part. You can view the resulting code in your browser and never need to reference those files.
It is not recommended by us, for the sake of build performance, but you can look in to plugins like write-file-webpack-plugin if you need this feature.
'webpack' writes your bundle to disk, whereas 'webpack-dev-server' loads the bundle into memory. So when running the latter command you wont see a new 'bundle.js' file appear in your file system, even though you should see output to the console reporting the bundling and the start up of the dev server).
The output.publicPath config key determines the location of the in-memory bundle on the host dev server. So if you set the publicPath to 'dist' then the index.html served by the webpack dev server will need a script tag in order to reference the bundle.
Related
I'm trying to get an extremely simple bare-bones TypeScript project setup with Webpack and I'm having an incredibly hard time for some reason.
I followed this guide and everything is working. When I simply run webpack my files will bundle and compile and be outputted into the dist directory. From there I can host them on a local server and it all works fine.
However, I want to avoid having to manually bundle and compile my code every single time I make a change, and I'd like for this to be done automatically each time I save my files. As far as I can tell this is a common use for Webpack and so I'm not sure why I'm having such an incredibly hard time finding any good information on it.
I decided to use the webpack dev server to accomplish this, so I read this tutorial and for the life of me I can't find anybody who explains how to get it to also server my index.html? When I run webpack serve --mode=development all goes well, and when I navigate to the localhost port that I server to I get a 404 error.
One of the "tips" on the previously linked page reads
If you're having trouble, navigating to the /webpack-dev-server route will show where files are served. For example, http://localhost:9000/webpack-dev-server.
When I navigate to localhost:1234/webpack-dev-server it tells me that it's only serving a single file: bundle.js Clearly a JavaScript file alone is not going to work, and I need it to also serve the index.html file that's in my dist directory.
Now, my knowledge here is very limited as this is my first time working with Webpack, but here's all the detail I can give and hopefully it's not accidentally totally unrelated:
Whenever my dev server reloads itself (whenever it's booted up or if a watched file changes while it's running) it only updates the bundle.js file that it's serving. It doesn't update the bundle.js file stored in my dist directory on my hard drive. How can I make it update both?
And also, how do I make the server also serve my index.html file instead of only the bundle.js? Where is it even getting that bundle.js from? Is it compiling all of my code from scratch to create that js file or is it taking that out of the dist directory?
And additionally, am I going about this totally in the wrong way? Where should my index.html even go? I put my TypeScript files into a src directory and they're converted to .js files and moved into my dist directory... Should I also put my index.html inside src or does it belong in dist or somewhere else entirely? When I put index.html in src it doesn't get copied over into dist, it just ignores it completely. If my index.html file doesn't belong in src it must belong in dist, but if it belongs in dist then how can I expect the dev server to find it and serve it along with the other TypeScript files in src? Why can't the dev server just serve everything in dist and automatically compile everything from src into dist? I must be misunderstanding the flow of it all, but I have no idea where to look for an explanation and I've been at this for several hours now.
Just a general explanation of how it all works would be very helpful as well, as I can't find a single article or forum post anywhere that details all the spaghetti going on with Webpack. I've been avoiding bundlers and all this NPM mess for as long as I can because I constantly run into issues like this, but I finally decided to jump in and just push through all the mess and I'm already regretting it. If someone could just point me (and other people having similar problems) to some good resources for learning about all the automagic going on that would be hugely appreciated. The Webpack documentation and guides are very much worthless to a newbie.
My Webpack config file:
const path = require("path");
module.exports = {
entry: "./src/index.ts",
module: {
rules: [
{
test: /\.tsx?$/,
use: "ts-loader",
exclude: /node_modules/,
}
]
},
resolve: {
extensions: [".tsx", ".ts", ".js"]
},
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "dist")
},
devServer: {
compress: false,
static: false,
client: {
logging: "warn",
overlay: {
errors: true,
warnings: false
},
progress: true
},
port: 1234, host: "0.0.0.0"
}
};
Is your entry set in webpack? So that it is included?
entry: {
main: 'path/to/index.ts'
},
You could also try adding to your index.ts file
require('file-loader?name=[name].[ext]!../index.html');
Or
require("./src/index.html");
// Then In your webpack config file add a loader
loaders : { { test: /\.html/, loader: 'file?name=[name].[ext]' } }
Otherwise you could always copy this file over with webpack copy plugin
{
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html'
})
]
}
will need to run npm install --save-dev html-webpack-plugin to install it. As well as move your index.html file into your src folder
Please visit localhost:1234/bundle (Where bundle.js is your bundled file) the magichHTML route, which will load the HTML file with the bundled script.
We have the following structure in our web application:
/src(.sln)
--/ClientSite
--/AdminSite
--/SharedWeb
In SharedWeb we have the following folders:
--/Client
--/Admin
--/Shared
We have this structure in order to have hot reloading with webpack-dev-server no matter what file we edit and only have one package.json etc. Thread about why we choose this structure if anyone is interested:
Shared react front end components -> Separate project with TypeScript -> Visual Studio 2017
Everything has worked fine so far but now that we need to deploy our solution we need to export the bundle.js to the correct site.
In webpack.client.config.js:
Works fine with hot reloading but script file is not exported to the site correctly:
output: {
filename: "./Scripts/dist/[name].bundle.js",
},
Script file is exported correctly but hot reloading stops working:
output: {
filename: "../ClientSite/Scripts/dist/[name].bundle.js",
},
Correct way with using path and filename according to documentation, nothing works:
output: {
path: path.resolve(__dirname, "Scripts/dist/"),
filename: "[name].bundle.js"
}
Script file is exported correctly but hot reloading does not work. If I use webpack with --watch and manually reload webpack-dev-server URL I can see the changes but it does not reload automatically.
output: {
path: path.resolve(__dirname, "../ClientSite/Scripts/dist/"),
filename: "[name].bundle.js"
},
Solved it like this, publicPath was the key for automatic updates to work in webpack-dev-server.
output: {
path: path.resolve(__dirname, "../ClientSite/Scripts/dist/"),
publicPath: '/Scripts/dist',
filename: "[name].bundle.js"
},
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
I've set up a basic react application with webpack but I couldn't get the webpack-dev-server running properly.
I've installed webpack-dev-server globally and tried running the command sudo webpack-dev-server --hot as hot reloading was required.
The project seems to be working fine with just webpack cmd. It builds into my build folder and I can get it working via some server but it wont work with webpack-dev-server. From terminal its clear that the build process has completed with no error being thrown [webpack: bundle is now VALID.] and its in fact watching properly because on any change it does trigger the build process but it doesn't really gets built [it doesn't serve my bundle.js]. I tried changing the entire config and still couldn't get the issue resolved.
It would be much appreciated if someone can help.
Following is my webpack.config.js file.
var path = require('path');
module.exports = {
devtool: '#inline-source-map"',
watch: true,
colors: true,
progress: true,
module: {
loaders: [{
loader: "babel",
include: [
path.resolve(__dirname, "src"),
],
test: /\.jsx?$/,
query: {
plugins: ['transform-runtime'],
presets: ['es2015', 'react', 'stage-0'],
}
}, {
loader: 'style!css!sass',
include: path.join(__dirname, 'src'),
test: /\.scss$/
}]
},
plugins: [],
output: {
path: path.join(__dirname, 'build/js'),
publicPath: '/build/',
filename: '[name].js'
},
entry: {
bundle: [
'./src/index.js'
]
},
devServer: {
contentBase: "./",
inline: true,
port: 8080
},
};
I've got the issue resolved by myself. Silly as it sounds but the issue was with the publicPath under the output object. It should match the path property instead of just /build/, i.e.,
output: {
path: path.join(__dirname, 'build/js'),
publicPath: '/build/js', // instead of publicPath: '/build/'
filename: '[name].js'
},
In my case I had to check where the webpack is serving the file.
You can see it:
http://localhost:8080/webpack-dev-server
Then I could see my bundle.js path > http://localhost:8080/dist/bundle.js
After that I used that /dist/bundle.js in my index.html <script src="/dist/bundle.js"></script>
Now it refreshes any file changes.
webpack-dev-server serves your bundle.js from memory. It won't generate the file when you run it. So bundle.js is not present as a file in this scenario.
If you wan't to use bundle.js, for example to optimize it's size or test your production deployment, generate it with webpack using the webpack command and serve it in production mode.
By the way, started from Webpack v4 it is possible to write in-memory assets to disk:
devServer: {
contentBase: "./",
port: 8080,
writeToDisk: true
}
See doc.
The fix to this for me was:
devServer: {
devMiddleware: {
writeToDisk: true,
}
}
https://webpack.js.org/configuration/dev-server/#devserverwritetodisk-
Dev-server keeps the compiled file in memory, and I can't access it directly...
BUT! THE SOLUTION is that you have no need to access it, in development(even when you run your project on node server or localhost) use localhost:8080 to access your page, and that's where webpack-dev-server is serving your page and you can feel all advantages of using it(live reload!), BUT! it doesn't compile your bundle.js, SO! before production, you need to manually run webpack build command, and that's it! there is no way for dev-server to compile your bundle.js file! Good Luck!
Please refer to this - https://github.com/webpack/webpack-dev-server/issues/24
According to this, webpack dev server no longer writes to the disk. So, you wont be able to see the build file. Instead, it will be served from the memory. To get it working you have to set the proper path.
Example: in index.html loads the build file from '/dist/main.js' so in webpack config file set the output.publicPath to '/dist/'
In my case I was using VS Code and I had to restart it. I have noticed that vs code bugs up sometimes. The changes you make in configuration files (package.json, webpack.config.js etc.) do not take effect sometimes. So, in case you encounter a situation where something doesn't work even with the correct settings, just restart vs code.
I can't see any bug reports related to this. So that's strange. I'm thinking this bug is triggered if you change one of the configuration files some time later after you have already built the project multiple times.
If this is actually what's happening then it's a huge bug. I'll try switching to Visual Studio instead of Code and see if this still happens. If it does then it's probably an issue with webpack.
I'm using webpack-dev-server -d --inline to serve my dist/app.js file generated through webpack. I've activated source mapping and it is generating an app.js.map file in my dist/ folder, along with //# sourceMappingURL=app.js.map at the end of the file, yet Chrome devtools doesn't seem to be using the source mapping.
I thought that maybe the problem was that Chrome couldn't see the raw source files (since only the dist/ folder is being served by webpack-dev-server), so I've tried mapping the served file to the local file in dev tools.
Unfortunately I then get a "workspace mapping mismatch", I'm not sure why the file would be different, nor am I sure that this would fix the source mapping problem even if the files did match.
I would appreciate any help.
Configuring publicPath did the trick for me. In your case you could try to point to the same path of your bundled output.
webpack.config.js
var path = require("path");
module.exports = {
entry: './main.js',
output: {
path: path.resolve(__dirname, 'dist'),
publicPath: '/dist/',
filename: 'app.js'
}
};
I'm not quite sure what the publicPath in webpack does. Specifically, output.publicPath. In the github docs, I see this
https://github.com/webpack/docs/wiki/configuration#outputpublicpath
The output.path from the view of the Javascript / HTML page.
For reactjs hot loading, I have
output: {
path: path.resolve('./public/bundle/'),
// path: './public/bundle',
filename: 'main.js',
// Webpack dev server is bound to port 8080, we have to force use of absolute URL, using the publicPath property
publicPath: 'http://localhost:8080/public/bundle/'
},
Does this mean that the built webpack files (main.js) is placed in my dev-server http://localhost:8080/public/bundle/ ?
Yep, Webpack needs to know where you'll host the generated bundle file (or any other assets it generates) so that it can request additional chunks or files that are loaded from file-loader or url-loader. Hence in this case, when you start your webpack-dev-server, you'll be able to access your bundle file at: http://localhost:8080/public/bundle/main.js (any related assets like images, commonchunk, fonts, etc will be under that path)
Outside of dev-server, you can use it to define the location of your assets (from a custom directory or even a CDN)