Serve multiple entry points with webpack dev server - reactjs

I've got multiple entry points being generated with outputs successfully but what I'm not too sure on is if there is a way with the webpack dev server to serve these multiple entry points and somehow be able to work on them all at the same time?
Here is my basic setup right now, is there a way I can get webpack dev server to somehow serve these on different ports maybe or by changing the URL serve the different entry points?
I've tried changing the port number on one of the apps but it doesn't seem to run a server with that port, which I kind of figured it wouldn't
entry: {
dashboard: [
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
paths.appIndexJs
],
display: [
"webpack-dev-server/client?http://localhost:3000",
"webpack/hot/only-dev-server",
paths.displayJs
]
},
output: {
pathinfo: true,
filename: "static/js/[name].js",
chunkFilename: "static/js/[name].chunk.js",
publicPath: publicPath,
devtoolModuleFilenameTemplate: info =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")
},

Related

How is this webpack devServer configured incorrectly?

I am running into issues with my webpack-dev-server. When i try to load at a specified route such as "http://localhost:3000/login" I get the following message "Cannot GET /login".
I've read through the docs and seen many different solutions, but I don't see the flaws in my config. I have my webpack setup like this.
webpack.config.js
module.exports = {
mode: 'development',
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'bundle.js',
},
module: [ rules... ],
devServer: {
contentBase: path.join(__dirname, 'build'),
compress: true,
port: 3000
},
}
My scripts for the app look like this:
"build": "webpack",
"dev": "webpack-dev-server --open"
If I run dev the app will open to the initial route - "/". If I click on a link to login - "/login" that will load fine. But if I refresh the page on login it will throw the "Cannot GET /login" error.
Is there something I'm missing or have wrong in my webpack configuration?
webpack-dev-server only serves two things: bundled assets, and whatever is in the directory you gave it as the value for contentBase. things work the way you want when you browse to / then navigate to /login since I assume you have some kind of client-side routing framework in your webapp. none of that applies when you refresh your browser and ask the server for a page at /login .
w-d-s is 404ing on you since you don't have a file named "login" in your build directory (and I doubt you have a compiled bundle or chunk with that name either). do you have an index.html file in that directory? is that what you're served when you visit localhost:3000/ ? does that file have a <script> tag which loads your webapp?
what were you expecting to happen when you visited /login ? I'm assuming you wanted to display your webapp's login screen when you visit localhost:3000/login ? if so you'll most likely need to use a separate server like express.js to server-side-render your webapp. this server can either be on a different port from the server launched by w-d-s, or it can actually use w-d-s as middleware so you only need one server with one port.
this seems like a decent resource at first glance: Server side rendering with react, react-router, and express . but if it doesn't work for you, there are dozens more on SO already which might.

Web-pack successfully compiled but does not show output in browser

Browser http://localhost:8080 still says
This page isn’t working
localhost didn’t send any data.
ERR_EMPTY_RESPONSE
As you are using webpack, please check what parameters you have used in devserver tag of your webpack.config.js file.
It should be as below:
devServer: {
inline: true,
contentBase: './src',
port: 3000
},
Hope this will resolve your issue.

Webpack dev server cannot get `http://localhost/8080/bundle.js`

Given this config:
var webpack = require('webpack');
const path = require('path')
module.exports = {
entry: "./src/index.js",
output: {
path: path.join(__dirname, 'dist'),
publicPath: path.join(__dirname, 'dist'),
filename: "bundle.js"
},
devServer: {
contentBase: "./dist",
// hot: true,
}
}
Why won't webpack-dev-server server my app properly? I have 0% understanding of localhost, vs localhost/webpack-dev-server, vs publicPath, vs contentBase, etc.. I know all of these paths, and configuration keys are important to setting up my project properly but despite hours of reading about them, they remain as confusing as when I started.
If I go to localhost:8080/webpack-dev-server I see Get http://localhost:8080/bundle.js net:ERR_ABORTED` in the console.
Below are simple and straight forward rules for webpack & webpack-dev-server :
output.path : It needs to be an absolute path or /. You can get it easily using path.join
output.filename : This needs to be the name of output file without any extra file path.
devServer.contentBase : It is the physical location on the disk which is served as the root directory of webpack-dev-server when you open http://localhost:8080
By convention, we keep both output.path and devServer.contentBase same.
The tricky part is when you run webpack cmd, it generates the physical bundle.js file.
But when you run webpack-dev-server, NO PHYSICAL OUTPUT file is generated, rather it keeps the generated output in memory to avoid File-Write operate which in turn helps in faster development/debugging cycle.
So any change you make in src.js or main.js file, it will generate the output but won't write that to disk and wepack-dev-server reads that directly from the memory.
output.publicPath : This is used by webpack, webpack-dev-server & other plug-in to generate the output or serve the generated bundle.
The default value is /.
It is VIRTUAL PATH and need not be present on the physical
disk. Example : final application name if multiple apps are
hosted on the same server like /app1, /app2, or some external CDN path
/CDN-Path.
It is also helpful for React-Router <BrowserRouter basename='/app1'>
Now to refer the bundle output file that is generated & kept in the memory , you need to append the output.publicPath i.e. Virtual Path in the browser's URL.
The final URL for webpack-dev-server will be :
http://localhost:8080/<output.publicPath>/<output.filename>
In your case, either you change the
publicPath: path.join(__dirname, 'dist')
to
publicPath: '/dist' if it contains any spaces.
You can check it by printing the value of path.join(__dirname, 'dist') which returns the absolve path [different on MacOS & Window system].
http://localhost:8080/dist/bundle.js
If you want to dig further deeper, then here is the URL
https://medium.com/p/webpack-understanding-the-publicpath-mystery-aeb96d9effb1

Webpack dev VS production server

Just like we have the webpack-dev-server (only for development), I was wondering, do we also have webpack for production server, something like webpack-prod-server. This is getting very confusing
module.exports = {
entry: [
'webpack-dev-server/client?http://localhost:8080', // WebpackDevServer host and port
'webpack/hot/only-dev-server',
'babel-polyfill',
'./js/app' // Your appʼs entry point
],
output: {
filename: "js/bundle.js"
},
You would run webpack -p and it would output a minified bundle.
You then use something like nginx or some other web server and load an html file that imports your minified JS bundle.
To skip having to edit an html file with the bundle location, you can use https://github.com/jantimon/html-webpack-plugin.

Testing for App Engine+Angularjs client - each running on a different port

I'm sure my title needs some tweaking, but here's the question:
Is there a way for me to serve up my AppEngine/Google Endpoint (Python) project using dev_appserver running on a given port (web on 8080, API on 54381), while serving my AngularJS client using a different server (and by necessity a different port, maybe 5000)?
Background:
The problem I'm encountering is around the structure of my app and
the tools/processes I can use for dev/testing.
To leverage existing GruntJS goodness out there I decided to layer my project's App Engine
server code and AngularJS client code into the directory structure
created by the Yeoman Generator for Angular.
I thought by bringing in this Grunt-like environment I could easily pull in
mobile-angular-ui code as a bower_component and easily link it
into my main index html page. This seemed to be the case.
The issue: App Engine ended up monitoring the folders/hierarchy under bower_components, which exceeded the file count limit for the app server to monitor (dev_appserver.py said 'There are too many files in your application for '). This generally made me think "there has to be a smarter way".
Options I see:
Serve the client code from the Grunt-serve server, and the Google Endpoint server using the normal dev_appserver.py. I believe these need to run on different ports if on the same host. So I don't know how I can tie the Google Endpoint client loading javascript against the server.
Google adds a patch to dev_appserver to allow the file-change monitoring code to adhere to exclusions (something discussed in this Google App Engine Issue)
Find a way to move the files around using grunt plugins so that I effectively re-build a "dist" folder for any external components I use that I point my served client code against. Avoiding the need to have my App Engine app.yaml expose the entire bower_components folder to make my script includes work.
If you use grunt-connect-proxy your Grunt server running on port 5000 will be able to forward requests to the App Engine server on port 8080.
That way you keep Grunt's nice live-reload features.
This article explains how to do it on for Java/Maven but the Grunt part is exactly the same.
Here are extracts of my Gruntfile.js modified to use the proxy :
connect: {
options: {
port: 9000,
// Change this to '0.0.0.0' to access the server from outside.
hostname: 'localhost',
livereload: 35729
}, proxies: [
{
context: [
'/_ah',
'/admin'
],
host: 'localhost',
port: 8080,
https: false,
changeOrigin: false,
xforward: false
}
], livereload: {
options: {
open: true,
base: [
'.tmp',
'<%= yeoman.app %>'
],
middleware: function (connect, options) {
if (!Array.isArray(options.base)) {
options.base = [options.base];
}
// Setup the proxy
var middlewares = [require('grunt-connect-proxy/lib/utils').proxyRequest];
// Serve static files.
options.base.forEach(function (base) {
middlewares.push(connect.static(base));
});
// Make directory browse-able.
var directory = options.directory || options.base[options.base.length - 1];
middlewares.push(connect.directory(directory));
return middlewares;
}
}
},
...
grunt.loadNpmTasks('grunt-connect-proxy');
...
grunt.registerTask('server', function (target) {
if (target === 'dist') {
return grunt.task.run(['build', 'connect:dist:keepalive']);
}
grunt.task.run([
'clean:server',
'concurrent:server',
'autoprefixer',
'configureProxies:server',
'connect:livereload',
'watch'
]);
});

Resources