How to understand the webpack config in react-router project - javascript

I am learning react-router dynamic routing from this link https://github.com/ReactTraining/react-router/blob/master/docs/guides/DynamicRouting.md. The huge-apps project is the one I am looking into. I cloned the react-router git repo from https://github.com/ReactTraining/react-router and followed the instruction to set it up. Everything works fine here. But I don't understand some parts of the configuration in webpack configuration under examples directory.
Below is the output of the webpack config:
output: {
path: __dirname + '/__build__',
filename: '[name].js',
chunkFilename: '[id].chunk.js',
publicPath: '/__build__/'
},
I can see that all the output files are put under /__build__ directory. In huge-apps/index.html file, I can see it load the javascript files as below:
<script src="/__build__/shared.js"></script>
<script src="/__build__/huge-apps.js"></script>
But I couldn't find the __build__ directory under the entire react-router project. And I couldn't find the shraed.js and huge-apps.js file either. I am confused about where webpack put these files. From the inspect on browser I can see it loads the javascript files from http://localhost:8080/build/huge-apps.js. Are they in memory only?

The React Router examples use webpackDevMiddleware to handle requests to __build__ resources, which serves files from in-memory.
From server.js:
app.use(webpackDevMiddleware(webpack(WebpackConfig), {
publicPath: '/__build__/',
stats: {
colors: true
}
}))

If you are running webpack indevelopment mode all the file get loaded in memory. to create the file in you need to add "ExtractTextPlugin" plugin in webpack
output: {
path: __dirname + '/__build__',
filename: '[name].js',
chunkFilename: '[id].chunk.js',
publicPath: '/__build__/
},
plugins: [
....
new ExtractTextPlugin("[name].css"),
...
],

Related

Webpack bundling a library that uses another library that contains WebAssembly gives several files as output, but the paths to them are not relative

I'm making a custom element using Svelte, that I plan to publish to NPM as a library. The component uses a library I made, that uses WebAssembly. When I build the Svelte library with Webpack, it gives me three files.
1.1.js
[hash].wasm
bundle.js
bundle.js references both the wasm file and 1.1.js. This works in the project folder itself, but when I npm pack it and try to use it in another project, it can't find the 1.1.js file or the wasm file. Apparently, the paths are relative to the website root instead of eg. /1.1.js instead of node_modules/packageName/1.1.js. I really have no clue how to fix this. Any ideas?
The start of my webpack config file looks like this:
const config: webpack.Configuration & WebpackDevServer.Configuration = {
entry: {
bundle: [
'./src/main.ts',
],
},
resolve: {
alias: {
// Note: Additional aliases will be loaded automatically from `tsconfig.compilerOptions.paths`
svelte: path.resolve('node_modules', 'svelte'),
},
extensions: ['.mjs', '.js', '.ts', '.svelte'],
mainFields: ['svelte', 'browser', 'module', 'main'],
},
output: {
path: __dirname + '/public/build',
filename: '[name].js',
chunkFilename: '[name].[id].js',
},
...
I have tried both importing the bundle.js directly with HTML, and importing the package using import x from y syntax in a JavaScript file, and running Webpack on the project that uses the Svelte component. I get errors such as this ChunkLoadError: Loading chunk 1 failed. (error: http://localhost:8080/1.1.js)

Configure Webpack to serve react at relative path

I have a koajs server that serves react as static files from the /dist folder.
const static_pages = new Koa();
static_pages.use(serve(process.env.PWD + "/dist"));
app.use(mount("/app", static_pages));
The problem is that, I want to mount the index.html from /dist at the relative path "/app" because at "/" i have something else.
My webpack.config.js looks like this:
entry: "./static/index.js",
output: {
path: path.join(__dirname, 'dist'),
filename: "[name].js"
},
where static/index.js is my react app. And when i open the browser i get an 500 error
"http://localhost:4000/main.js net::ERR_ABORTED 500 (Internal Server
Error)"
But if i go to localhost:4000/app/main.js it works, i get the main.js bundled file, but my index.html from dist tries to get main.js not /app/main.js.
How I'm supposed to change the webpack config file bundle it so that my app will be mounted at relative path?
If you're willing to use React + Koa at the development you should use webpack-dev-server to serve you're react bundle with HRM on a specified PORT, otherwise if you're willing to sever static build from React.js files you should use koa-static middleware which will allow you to serve bundle.
According to your webpack configuration, you're missing important html-webpack-plugin which will generate an index.html in your bundle (without that koa isn't able to serve content on specified path).
const htmlPlugin = new HtmlWebPackPlugin({
template: "./static/index.html",
filename: "./index.html"
});
This is my HtmlWbpackPlugin configuration. I've managed to solve the issue by adding publigPath to the output like that:
output: {
path: path.join(__dirname, 'dist'),
filename: "[name].js",
publicPath: '/app'
},
I don't know if this is the best solution but it works

webpack-dev-server and webpack -> output file to parent directory and have webpack-dev-server hot reloading still working

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

Webpack-dev-server doesn't build files on change

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.

Webpack-dev-server not bundling even after showing bundle valid message

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.

Categories