Im making a module for node.js and it is meant to serve javascript on the server side (like most nodejs modules) but also needs to enable a javascript file to be shared with a client (browser).
The client is served by an express server, dealing with the routes.
However I can't seem to find a way to server the javascript file from the node module, as a static file (without it having to, either be placed to a static folder by the user or having to parse the app as parameter to the module).
These are two posibilities that I'd like to avoid, as I noticed Socket.IO does not take these steps to share its socket.io-client code.
I looked into their code, to look in how they did it but can't seem to find it.
So I am wondering what the best way is, to share a static javascript file to a client from a node module.
Related
I have a script that generates sitemap.xml file in the public directory. It is accessible in localhost:3000/sitemap.xml when it is in development. But when it goes for build, I cant access the file from the public folder. I made some research and I found out build doesnt have access of the public folder! Please help me with a way to access the public/sitemap.xml if there is any, if not is it possible to show .xml format as a page in reac-router-dom?
Reading through your question and comments there isn't a lot to work with, however I can inform you of a couple of things.
The reason your sitemap might work locally and not on a build is because you're very likely using webpack-dev-server (if you're using CRA then you're using it), which in return uses express to locally serve your files. When you build it will no longer be using that server and you'll need your own custom server.
When you build your files for production it will output all your files to static js/css files which then need to be served using some or other server (express/nginx/apache). In your question you've not specified what server you're using, beyond the development server, so I can only assume that you probably don't have any and/or are depending on some host that you're using without realizing that you're using one.
When you want to serve something like .xml, you have to configure the server to actually serve .xml files. Also you should not be serving .xml as any form of react route, it's not a route and it has nothing to do with react. Your request should directly hit the server, i.e. nginx, and that server should be configured to serve the .xml file.
In your comments you mentioned that it's "sitemap.exe", I'm not sure if that's a typo but you can't serve and run .exe files over web and no server will be configured to do so by default. The sitemap.xml or sitemap.txt should contain only the valid xml or text content and also make sure it's actually in the build directory once you've built it.
If the .xml exists in your build and all of that's fine then the only thing left you need is to add a location block to your nginx server, or to add a get route to your express (or static resources) in order to actually serve that file. If your server is giving you a 404 at that point it likely means it isn't recognizing .xml files at all. That needs to be configured in your server.
In nginx it means you need something like location = /sitemap.xml.
In express it means you need something like app.get('/sitemap.xml').
A default nginx installation with try_files $uri $uri/ =404 should work for .xml as well.
I solved a similar issue by going into the "Rewrites and redirects" section and adding a rule says the "source address" of "/sitemap.xml" will redirect to "/sitemap.xml" and prioritized that rule over the rule in which </^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|woff2|ttf|map|json)$)([^.]+$)/> is redirected to /index.html.
I am working on a personal project and there are two things that keep bugging me.
This project is written in React and I am using an express node app for backend. In my frontend, I can load and send images to the server and I am saving the files inside an upload file and the path is stored inside a mongo database.
After the build, the files look like this:
As you can see, my uploads folder is inside the public folder. The public folder is the build of the react app. I just renamed it. The problem is, if I want to update the build, I have to save the uploads file in someplace else and than reintroduce it inside the new build(public) folder. And that sounds impractical to me. Is there a way around that? A best practice?
That would be the first thing.
The second one is the path that I am using to link the image folder to the <img src=''/>.
Right now, the path looks like this: http://localhost:5000/${ filePath }. And works just fine. But I don't think that in a production scenario I will be able to use this path.
The question is: Do I have to link the port as well? Something like: http://localhost:${PORT}/${ filePath } and the port is const PORT = process.env.PORT? Or is there a better practice? A way to get your own domain?
Hope I delivered all the info needed for an accurate answer. If not, I am waiting for feedback. Thanks!
"Best practice" would be uploading the files to static file server like S3 and storing a reference to they file key.
But short of that, I believe Express lets you set multiple static file directories using
app.use('/uploads', express.static(path.join(__dirname, 'uploads')));
so you could then keep your uploads directory outside your build folder.
As for including port in your asset URIs, what I've done in the past was to use an environment variable called domain that specified the web address of the current environment (including protocol, domain, and port). This way your dev enviornment can use localhost, but if you decied to deploy your production app to the public, you can just set the environment to the domain name -- and could tell your express server to listen on the 80/443 ports.
I am using Vue.js 3 for my front end, and Node/Express on the back-end. I am trying to enable server side rendering which is proving difficult.
I understand the client-side is built into a file called app.js. However I never see server.js being built and exported to the dist folder? Here are some examples:
vue-hackernews where there is an entry-client.js and entry-server.js file being provided to Webpack, but server.js is not anywhere to be seen.
Another question/answer also only provides main.server.js as the server entry file and does not build server.js.
It is my understanding that server.js is the back-end and has to run for Node.js/Express to work. In the above two examples what exactly is being built from the server entry files because it doesn't seem to be server.js where the Express routes live. Surely server.js must be built to the dist folder so that it can be accessed and run by a web server like Windows IIS for example (which I am using)?
You are correct, usually there is no need to bundle the server code.
But there are some benefits from doing so:
One project wide configuration, must of the client & server config can be shared - no need to maintain multiple build tools
Server code HMR (Hot Module Replacement)- you can swap your server code during dev without the need to restart the server
Code sharing between client & server
Code transpilation - server code can be written in modern syntax (ESM etc...) and it will be transpiled to the target node version.
I'm building SPA with Vue and serve it with nodejs and wrapping it in docker container.
Here is the problem, I'm trying to stick to 12 factor app where for configuration it says keep in env file.
VueJS provides configs for different environment in config folder. But, according to 12 factor app config should not be in files based on environment.
In a twelve-factor app, env vars are granular controls, each fully orthogonal to other env vars. They are never grouped together as “environments”, but instead are independently managed for each deploy.
So how can I access nodejs environment variables in VueJS app?
EDIT:
Thanks for the answers.
The whole idea is to change for example api url on run time trough providing different env variable. If I commit the config file with api url, I would have to rebuild the container on commit and deploy it just for this small change.
I could also have a api access key that is different in dev and prod.
I'm looking for the best way possible to do this kind of things in SPA.
SPA applications nowadays usually go through a build step. This means compiling all of your files into [near to] one dist file and an index.html which may be served statically. This creates a clear separation between front-end (VueJS) and backend (NodeJS). The index.html and js files themselves continue to be static files nonetheless.
This is usually what you want since you can scale server and client independently: Serve static files, say, through s3 + cdn and run your nodejs server independently.
I think what you want is a way to pass runtime configuration to the client. I wouldn't get too caught up on the details of actually sharing the envvars per se.
In your case, I see two possible solutions:
1) Implement an API to access whitelisted envvars from your server - You can think of this as a /config endpoint
2) Render the index.html dynamically via nodejs with something like ejs with the prepopulated envvars - You'll have more coupling between frontend and server but you could extend this to much more than envvars and, say, preopolute the frontend with prefetched data.
Regardless on how you do it, you can consider this runtime configuration for the frontend which should not be attempted to be fixed at build time since otherwise you may be expose sensitive data into static files and it is not always guaranteed that you have all the data at this time.
The way you access the env variables should be the same no matter which OS you are using. The way you set them is different though. On windows I would set an environment variable like so
set PASSWORD=somepassword
And then in the code I can access this variable by doing the following
var pw = process.env.PASSWORD;
You should be able to use this the same way in VueJS.
EDIT:
If you use docker-compose you can set the endpoint on the fly by using environment variables too. Then whenever you docker-compose up the endpoint will be updated with the current value of your environment variable. In your shell update the api endpoint to whatever you want it to be.
set API_URL=http://my-api-endpoint
Then in the docker-compose.yml you would access this value like so
version: '3'
services:
app:
image: 'myapp'
environment:
- API_URL=${API_URL}
You would still access the variable in your code using process.env.API_URL as I mentioned in my example above.
our devops team will use https://github.com/tinou98/vue-12factor
However it's really a big question mark how VueJs does not consider that as a mature frontend/spa framework.
We used to build React Apps since more than 6 years with a built-in support of externalizing env.js file ( create-react-app )
I'm curious if anyone has developed a best practice for organizing Meteor applications that contain external shell scripts, or other back-end processes that happen outside of the node.js server code and the client side js code.
For instance, I have a meteor app that is structured like this:
project-name
client
lib
models
packages
public
server
I have a shell script that processes some external data sources, and a Python script that does some other heavy lifting. These all then help by inserting new data into the Mongo instance. Yes, I know that's a bit of a jumble, but so are the backend data systems. My question is should I put these sorts of projects within the meteor app folder, or should they live outside of the system? Just curious how others are structuring apps like this.
Option #1
project-name
client
...
server
data-processor.sh
other-utility.py
Option #2
project-name
client
...
private
data-processor.sh
other-utility.py
Option #3
bin
data-processor.sh
other-utility.py
meteor-project-name
client
...
private
You shouldn't put any non-meteor files inside your meteor project directory, all of those CAN be picked up by some package, even if standard meteor-platform packages don't recognize the extension. So putting them in the /server might cause problems in the future. The /private folder on the other hand is meant for resources used by your application, so placing the scripts there is unsemantic and inelegant.
To avoid moving those scripts outside of the project folder you can store them inside a hidden directory, that is any directory with name starting with a dot, i.e. /.scripts. Files placed there will not be picked up by Meteor application.