Configure Webpack to serve react at relative path - javascript

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

Related

Why is webpack unable to find react when I'm using a custom entry point?

I set up a custom entry point in Webpack but am getting an error on this line of my React code:
import React from 'react';
Webpack is able to build it, but itsnt intercepting that path because Chrome gives me this console error:
Uncaught TypeError: Failed to resolve module specifier "react".
Relative references must start with either "/", "./", or "../"
However, when I change the path as suggested to:
import React from './react';
Then webpack is unable to build and gives this error:
ERROR in ./path/to/my/file.js Module not found: Error: Can't resolve
'./react' in '/Users/me/Documents/GitHub/myProject/path/to/my #
./path/to/my/file.js 3:0-28
And furthermore I get this Chrome console error:
GET http://localhost:9000/path/to/my/file/react net::ERR_ABORTED 404 (Not Found)
So webpack is looking for react in path/to/my/ instead of in node_modules as it should.
My webpack.config.js looks like this:
//snip
module.exports = {
entry: './path/to/my/file.js',
output: {
path: path.join(__dirname, '/build'),
publicPath: '/',
filename: 'bundle.js'
},
devServer: {
contentBase: path.join(__dirname, '/'),
port: 9000
},
//snip
}
and package.json
{
//snip
"main": "path/to/my/file.js",
//snip
}
This problem is caused by the <script> tag in the HTML file pointing to the actual location of the source script, rather than pointing to the compiled output file that webpack creates.
This is wrong:
<script src="/path/to/my/file.js"></script>
^ That is pointing to the raw source code in its actual location in the repository. It isn't handled by webpack and isn't compiled by babel, it's just a plain javascript file handled by the browser, which explains the browser errors.
This is correct:
<script src="bundle.js"></script>
^ that is pointing to the compiled output that webpack generates based on the configuration. In the dev server, there is not an actual file called bundle.js, the file lives in memory, and the path to that file is just the dev server, e.g. something like http://localhost:8000.
The reason the name is bundle.js is because that's what it happens to be set to in webpack.config.js module output filename. If it's set to something else, it will be that.
output: {
path: path.join(__dirname, '/build'),
publicPath: '/',
filename: 'bundle.js'
},

webpack entry and output path

I have a file directory like this
and my webpack.config.js look like
module.exports = {
entry: [
'webpack/hot/dev-server',
'webpack-hot-middleware/client',
'./resources/assets/bundle/entries/feed.js'],
output: {
path : path.join(__dirname, 'public/bundle'),
publicPath : '/',
filename : 'bundle.js'
}
}
what is wrong? why I did not find the bundle.js in my public/bundle/bundle.js? I run http://localhost:3000/bundle/bundle.js I got 404 error hmm..
In developer mode webpack is not generating the file in the hard-drive.
If you run webpack in production mode you will see the generated file.
When you use hot reload or different watcher, webpack generate virtual bundle. If you try to run global command 'webpack' or build project, you can get bundle.js
In your index.html we do not mention the path of a file with localhost rather relative to the current file. So if index.html is in root you will mention the script src as below
<script src="./public/bundle/bundle.js"></script>

How to understand the webpack config in react-router project

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"),
...
],

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.

publicPath with react hot loader

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)

Categories