How to load bundles with angular-cli? - node.js

I must be missing something extremely simple here, because I don't understand how anyone can have a functioning angular-cli app without the ability to do the following...
Context
I have an Angular 2 app with an express.js backend acting as an API. I have switched from webpack to angular-cli to bundle my files as it offers easy Ahead-Of-Time compilation.
What I didn't expect was angular-cli is so opinionated, it even requires me to keep an index.html file inside the angular app directory in my repository (I had previously kept it in /views for express.js to send to clients).
Problem
I am struggling to see how I can load the outputted JS bundles from angular-cli if I have node.js server. Consider the following angular-cli.json snippet:
"apps": [
{
"root": "app",
"outDir": "public/dist",
],
Both my bundle.js files and my index.html will be outputted in public/dist. This means I have to update my node.js routes to change:
// Root
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/../views/index.html'));
});
to:
// Root
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname + '/../public/dist/index.html'));
});
Now the problem is that my public/dist/index.html file has a <base href="/"> tag, and the following generated script tags:
<script type="text/javascript" src="inline.bundle.js"></script><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script>
Well, obviously when I run my node.js server, those above bundles won't be found because they don't exist at the base href's location. There is no /inline.bundle.js, because it's located at /public/dist/inline.bundle.js. So, how can I ever load my frontend app?

I don't this will work, as it expect an absolute path, not relative.
res.sendFile(path.join(__dirname + '/../public/dist/index.html'));
You should point in a relative way all the dist server to / from the express folder, something like:
app.use('/', express.static('../public/dist'));
app.get('*', (req, res) => {
res.sendFile('index.html', { root: '../public/dist' });
});

I handle this kind of problems in a different way. I never send a file using sendFile, instead I only send JSON data.
Sending a file is suitable for traditional non-SPA applications. Sending JSON data is suitable for modern SPA applications.

Related

Express server serving index.html instead of chunk files, in a React app

I'm trying to serve a production build of a React app(Typescript), booted with create-react-app.
I'm following the official guide: https://create-react-app.dev/docs/deployment/
There's nothing unique about my setup. This is the server.js file, located in the root directory(above src):
app.use(express.static(path.join(__dirname, 'build')));
app.get('/*', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(8000);
The production files are created within a folder called build. An example of the paths generated:
<script src="./static/js/main.0ae46692.chunk.js"></script>
When i navigate to localhost:8000/, everything is served fine. The initial request serves the index.html, and the script requests serve the correct files.
But, when i try to navigate(from the browser) to something like localhost:8000/todos, all script requests return index.html.
I do not see anything "special" about my setup, and do not understand what's going on. Am i missing something in the guide? It clearly states that app.get('/*',...) fixes the issue.
Any help will be greatly appreciated.
Copying the comment into an answer here so it can be marked.
This sounds like the issue is the script tags are generated with relative paths, because it works when you make a request to the root /, but not anything else. Could you try setting the "homepage" to "localhost:8000"

Why I'm getting a blank page from running a node server that point to the /dist folder of an Angular app?

My simple node server is:
const express = require('express');
const app = express();
app.get('*', (req, res) => {
res.sendFile(__dirname + '/dist/page/index.html');
})
app.listen(3335, () => { console.log('Server is listening on 3335'); });
But I'm getting the index file that seems not running the main.js
The Angular app, at the moment it's literally a page/component that is app.component.ts, so there is not any routing.
Use express.static() for serving static files.
It is because you have set a response of 'index.html' file for each and every request the server would receive. The first response would be good that's the index.html page only as expected. But, the index.html page must be having some script and css tags to fetch your Angular Javascript code which I assume would be on the same node server. So when the browser would encounter a line like:
<script src="/angularApp.js"></script>
..in your index.html file while parsing it, it would make another request to the node server for http://localhost:<port>/angularApp.js but would get the index.html file as the response as that is what you have set.
Do it like this to serve static files like .html, .css, .js or what have you:
app.use(express.static(path.join(__dirname, '/dist')));

Serve static file outside of root directory in Koa2

I have a simple NodeJS server that uses Koa2. It serves static files from a client folder. However, there is a config.js that lives outside of the client folder. Right now my client/index.html file can't serve that config.js.
I'm trying to solve that by adding a router that should serve the config.js, like so:
let configPath = path.resolve(__dirname, '../', 'config.js');
//app.use(serve(configPath)); // this also doesn't work
router.get('/', (ctx) => serve(configPath));
In the client/index.html I simply have a script include.
<script src="config.js"></script>
But the browser says that it still can't find config.js.
How can I make this work in Koa2?

How to manually serve files on Parse.com?

I've deployed a single-page app using a frontend framework to my Parse Hosting.
However, there's a huge issue in there: sub-paths get routed to the /public folder, and there's only an index.html and a bunch of assets in there.
I've tried numerous options on serving that static index file through all other routes, by using Express or HTTP in cloud/main.js, but it seems Parse runs a custom subset of Node modules. They've erased all filesystem methods. There's no sendFile() on Express API, no readFile()on fs module...
What can I do to achieve that?? I just need all paths not in the public folder to serve the same thing: my index.html file.
What I've already tried:
Read the file and serve it:
app.use(function(req, res) {
fs.readFile('../public/index.html', 'utf8' , function(err, data) {
if (err) {
console.error(err);
}
res.send(data);
});
});
Serve it as an Express Middleware (probably the most efficient way):
app.use(function(req, res) {
res.sendFile('../public/index.html');
});
Serve it as a catch-all route:
app.get('*', function(req, res) {
res.sendfile('../public/index.html');
});

How to configure the page the / path goes to in a tiny express app?

I'm using a simple node express server which is wrapped in the Webpack Dev Server (http://webpack.github.io/docs/webpack-dev-server.html)
I'm starting an express app from a top level directory where the static files are in a directory called "public".
I've got this line of configuration:
server.app.use(express.static(__dirname + '/public'));
If I type http://0.0.0.0:3000/index.html, all is good.
How but the URL of http://0.0.0.0:3000/ produces a directory listing of the top level.
What is the proper way to configure http://0.0.0.0:3000/ to go to the index.html file?
add
server.app.get('/', function(req, res) {
res.sendFile('index.html');
});
See the docs http://devdocs.io/express/index#res.sendFile
The solution involved setting the contentBase proper of the WebpackDevServer plus telling the
server.app.use(express.static(__dirname + contentbase);
Per this diff
The docs are here: http://webpack.github.io/docs/webpack-dev-server.html

Resources