I am using Golang (Echo) for my backend and React for my frontend. When I bundle my code using webpack, the file is created; however, I am getting an error in my console when I go to localhost:3000 stating the bundle file cannot be found. This is the exact error message: GET http://localhost:3000/build/app.bundle.js net::ERR_ABORTED.
Here is my server:
func main() {
env.SetEnvVars()
e := echo.New()
e.File("/", "server/static/index.html")
e.Logger.Fatal(e.Start(os.Getenv("PORT")))
}
Here is my webpack.config.js file:
module.exports = {
entry: './client/main.jsx',
output: {
path: path.resolve(__dirname, 'server/static/build'),
filename: 'app.bundle.js'
},
...
And the script tag in my index.html file is:
<script src="./build/app.bundle.js"></script>
The directory path regarding these files is currently:
/
server/
main.go
static/
index.html
build/
app.bundle.js
Any help would be appreciated!
The echo server you've set up only serves one single path, the root path ("/"), by rendering the contents of the index.html file. Because you haven't set up any other handlers for that server, any request to a path other than the root will result in 404, including those requests made from the index page via script and link tags, e.g.; <script src="./build/app.bundle.js"></script>.
To be able to serve a request to a path like "/static/build/app.bundle.js" for example you need to tell the server how to do that by registering a new handler.
With the echo server you can use its Static method to do that.
e.Static("/static", "static")
Please keep in mind that the links you use in html tags, the location of the corresponding files on your machine, and the location from where you launched your app matters if you use relative paths like ./build/app.bundle.js, and because of that the two arguments to e.Static may need to be somewhat different from the example here.
Here's a bit more info.
Related
I have a react app which I serve with nodejs backend. My requirement is to inject a variable from node server to react code when it is running. When I access the app with the home page URL it works fine but not with other URLs. I am going to put more details to understand the complete scenario.
In node server I have code to create a file like this: dist folder is where react build is stored
fs.writeFileSync(
path.join(__dirname, "../dist", "config.js"),
`window.INJECTED_VARIABLE= { value: "qwerty", }`
);
In public > index.html I have this script to load the created config.js file.
<script src="./config.js"></script>
Now, when I run my node server and access my app with the home URL http://localhost:3000, I am able to access the injected value - window.INJECTED_VARIABLE as { value: "qwerty", } and config file is also present under "sources" tab in chrome devtools.
I have one page in my app - http://localhost:3000/profile/profileId, when I directly open my app with this URL, I see window.INJECTED_VARIABLE as undefined. It looks like there is no config file in source tab if we look in chrome devtools.
I am getting a same problem in production too.
Can anyone explain this behavior and help me in fixing it. I would appreciate any help.
The dot in ./config.js denotes a URL relative to the current path. i.e. A document served from /profile/profileId will request the file /profile/profileId/config.js - which doesn't exist.
To specify that a partial URL always be from the root, you should omit the dot.
<script src="/config.js"></script>
I'm following Heroku's tutorial to create a contact list using the MEAN stack (Heroku's running example here). I'm able to deploy it to Heroku and it works there. But when I run it locally on my machine, the browser (Chrome 67.0.3396.87 on macOS High Sierra) only displays a "Cannot GET /" message.
I believe it's related to how the Angular build directory /dist/ referenced in line 12 of server.js does not exist (as far as I can tell). The beginning of server.js looks like this:
var express = require("express");
var bodyParser = require("body-parser");
var mongodb = require("mongodb");
var ObjectID = mongodb.ObjectID;
var CONTACTS_COLLECTION = "contacts";
var app = express();
app.use(bodyParser.json());
// Create link to Angular build directory
var distDir = __dirname + "/dist/";
app.use(express.static(distDir));
// Create a database variable outside of the database connection callback to reuse the connection pool in your app.
var db;
I looked into it and found that Angular deletes the /dist/ directory upon ng serve. I also found that there is a flag --delete-output-path whose default is true.
I set the --delete-output-path flag to false in .angular-cli.json as recommended by this answer as well as in /node_modules/#angular/cli/lib/config/schema.json. Despite those changes (trying to set the flag in one file, or the other file, or both files at the same time), I'm still getting the "Cannot GET /" message and the /dist/ directory still doesn't appear to be there.
The only way I've been able to even run part of the app is to change server.js's line 12 reference from /dist/ to /src/. This allows /src/index.html to begin loading at localhost:5000/ (the browser displays the text "Loading..." as specified in line 16 of index.html) and gets the contacts API up and running at localhost:5000/api/contacts/. But the Angular components (the list of contacts that is the purpose of the tutorial) don't load. Maybe because I changed the build directory to a totally different location.
Is there something with the /dist/ directory that I'm missing? Or does my issue with getting the app to run locally have nothing to do with /dist/ at all?
Notice that you don't have a way of handling requests to the route '/' since the line:
app.use(express.static(distDir));
only ensures that all bundled files generated in your "dist" folder are accessible when your index.html requires them, but you still have to serve the index.html itself. When using the MEAN stack one normally would do something like this:
app.use ('/api', yourApiRouter);
//and for everything else let the client-side routing handle the route:
app.get ('*', function(req, res) {
res.sendFile(distDir + 'index.html');
}
I recommend to use the native "path" module to join your __dirname with your "dist" folder and your index.html location rather than simple concatenation.
You can use an arrow function instead of a callback when using app.get function if you are using ES6
I am using AngularJs of ES6 syntax, I am trying to load a local themes.json file from ApiService.js
getThemesOptions() {
this.$http.get('src/app-builder/p3-modal/themes.json')
.success(function(data) {
console.log(data);
})
.error(function() {
});
My file structure:
src/
app-builder/
p3-modal/
themes.json
service/
apiService/
apiService.js
From the console, looks like it found the file successfully, but the output is very strange,
Because themes.json looks like this:
I am running the application using Webpack, the url to access the application is not normally localhost, but http://10.98.142.233:8080/o2/search/ab instead, I don't know what cause the problem
Please tell me how to load the json file from local correctly , using AngularJs ES6 with webpack.
Thanks!
This is the network tab.
No, actually what happens is it can't find the JSON file, and the Webpack dev server routes the 404 back to your index.html, which is what you're seeing in the console. The success callback fires because technically, it's not a 404 but a 200 OK.
What you're doing should work so long as the Webpack dev server is serving content from the directory immediately above the src folder. I'm guessing that might not be the case.
your browser location is www.google.com/image,and then when you call an ajax the url that request to is www.google.com/image/${url} but if put a slash before your url would be like /src/app.. and the url it would request to is like www.google.com/${url}
I'm having a weird issue where our staging server is throwing a 500 error when trying to retrieve css or js assets. We are using broccoli to compile the assets to a distribution directory, so I have ~/dist/assets/app.css (as well as app.js and an img directory). Images seem to be served fine! Only the app.js and app.css files are throwing the 500 error. I've ensured the files definitely exist in their proper places.
We're using express.js and the serve-static module. Code is simply:
serveStatic = require('serve-static');
app.use(serveStatic('dist/assets'));
Then hitting 'http://url.com/assets/app.css' throws the 500.
Hitting 'http://url.com/app.css' WORKS. This seems like it would be okay (since I'm serving dist/assets so the request should be relative to /assets), but this was all working with the /assets prefix on the request a few days ago.
There is no error output produced in the logs anywhere. Stumped on this one.
I just want to make sure I'm not doing anything too dumb.
Have you tried this:
serveStatic = require('serve-static');
app.use(serveStatic('dist'));
serveStatic(root, options)
Create a new middleware function to serve files from within a given
root directory.
Based on that statement, you should expect that using "serveStatic('dist/assets')" will serve the app.css from http://url.com/app.css
I get this error when trying to register the service worker:
Failed to register a ServiceWorker: A bad HTTP response code (404) was gwreceived when fetching the script.
I'm working with ionic and this is what I have in the app.js:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('service-worker.js').then(function(registration) {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
}).catch(function(err) {
//registration failed :(
console.log('ServiceWorker registration failed: ', err);
});
}else {
console.log('No service-worker on this browser');
}
On the directory I have the service-worker.js file right next to the app.js on the same folder.
Using latest chrome version on ubuntu desktop.
You mention that you have service-worker.js in the same directory as app.js, but the URL passed to .register() is relative to the HTML document's path. You need to make sure your service-worker.js file is in the same directory as the .html file corresponding to the page you're on.
The HTML document which is trying to register a service worker and SW.js should be in the same directory.
These are great replies and it helped with my confusion. I just wanted to add another thing just in case others are running into this problem and are confused as I was.
If you are using a bundler like Webpack, the path needs to be relative to the compiled version.
If your sw.js is in the /src folder but the compiled version of your html goes to a ./dist folder and your path to register the sw.js is "./sw.js", service worker is going to be searching in the dist folder for the sw.js file.
My solution to the problem above for Webpack is to use copy-webpack-plugin and send the file over from the src folder to the dist folder.
You just need need to pass the right path to navigator.serviceWorker.register and it doesn't necessarily need to be the same of html file.
For instance, my service-worker.js is in the Scripts folder of my app, thus I needed to pass the path "/Scripts/service-worker.js" on navigator.serviceWorker.register, like:
navigator.serviceWorker.register('/Scripts/service-worker.js')
service workers and index.html file should be in a common directory.
This Problem is Caused By the sw.js file position in your directory
Possible Solution -
Move your sw.js file out of any sub folder/directory and put it at the common or public folder. And the error would go away and the Service Worker would get easily registered.
Try to set the source to look in the root directory using a ~
Like this:
navigator.serviceWorker.register('~service-worker.js')