Express static behaviour - node.js

I have a server running with express. Let's say I have the following folder structure:
- public
-- image1.png
-- image2.png
-- image3.png
- src
-- app.js
In the app.js I setup the server using express and I do:
const app = express();
app.use(express.static('public'));
Now, If I start the server and go to localhost:port/image1.png I get image1.png displayed.
I am confused because the path I specified is incorrect, kinda. If I do:
app.use(express.static(path.join(__dirname, '..', 'public'))
I get the same result. Why they work the same?

it all depends on "how you start your server"
if you do:
node src/app.js
it will work because from a Node.js perspective, the path public exists in the file system from where the node process started,
now, if you do:
cd src
node app.js
it will not work because there's no public folder in the file system from where the node process started
behind the scenes, Express.js is using the serve-static package,
if you look in the source code, it is using path.resolve to load the folder:
https://github.com/expressjs/serve-static/blob/master/index.js#L65
and looking at the Node.js documentation for path.resolve, we have:
"If no path segments are passed, path.resolve() will return the absolute path of the current working directory."
So, resolving public from the current working directory of node when using node src/app.js, the folder exists!
that's why it works! :)

Related

How Express.static decides a relative path

All:
I wonder when I use express.static with a relative path like
app.use(express.static('./dist'));
How do I know what is the root directory? One interesting thing I find is:
If I run node server/app.js(all express server code is inside app.js) and put dist fold along with server folder, it works, but if I run node app.js inside server folder, then it does not. So does this mean express decide root base on some variables from Node?
Thanks

how to use the webodf editor in localhost with node.js

I did not find any tutorials to how to run the webodf i read his apis and source code i am getting how to start it can anybody share the idea.
- WebODF version 0.5.10-8-gf5949f3
-- Found Java: /usr/bin/java (found version "1.7.0.91")
-- external downloads will be stored/expected in: /home/peoplelink/build/downloads
-- Installed Node.js found: /usr/bin/nodejs - 0.10.25
-- good Node.js found: 0.10.25 (0.10.5 required.)
-- npm found: /usr/bin/npm
-- Android was not found: APK will not be built.
JS file dependencies were updated.
-- Configuring done
-- Generating done
-- Build files have been written to:
i got this but i am not getting to webodf.js file in it i am missed out anything.
I am not not sure what you currently have . But This is how you can configure an application using node.js to serve html files and view/edit odf files.
Lets Start with your Node.js Server
First Create an index.js file(name it whatever you want)in our application directory,then initialize node application using node init.
We will have following folder structure : -
./ document-editor
../app (our html code and libraries)
../index.js
../package.json
../And some other auto-generated files.
Include all the modules necessary.We are going to use Express,Multer and
other util libraries.
var express = require("express");
var multer = require('multer'); //for file handling
var util = require('util');
var app = express(); // init express app
Configure Routes and Html files to be served on user request to you server.
app.use(express.static('app')); // use this as resource directory
//APP ROUTING URL => FUNCTIONS
app.get('/', function (req, res) {
res.sendFile(__dirname + "/app/index.html");
});
// this means when we get a request on 'myAppContext/' url provide
index.html
Start the Server
//START THE SERVER
app.listen(3000, function () {
console.log("Listening on port 3000");
});
Note* : Make sure you have node.js envoirnment installed on your system before you start.
Now Lets Look at how we include webodf to our application.
First create a directory in your main folder(we name it 'app'), where all
the html,styles and scripts..etc will be stored.
/app (our html code and libraries)
../index.html
../script
..wodotexteditor-0.5.9(folder)
..myScript.js
../styles
../images
../And some other files.
Create an index.html file and include webodf and/or Editor JavaScript libraries(Contains Webodf included in build... so need to download separately).
Create a container element and local script necessary to run webodf editor.Make sure to add a odt file to directory for you test or you can use the one which comes with wodo-editor.
You can refer this link for creating a local webodf editor using wodo-text-editor and complete the above to steps(2 & 3).
After we have done the above things,we will go into our root directory and run 'node index' command.... and that's it folks.
Just hit localhost:3000/ and you will see a workable webodf editor.
I hope this helps to get started with node.js and webodf. I will soon create and full application with open/edit and save features using webodf and node.js.
Thanks :)

Why use path.join() instead of just static('public')

In all the node express tutorials I've read the following syntax is used to create the public directory:
var path = require('path');
app.use(express.static(path.join(__dirname, 'public')))
However the following works just fine:
app.use(express.static('public'))
So why would I use the path module instead ?
The last example uses a relative path, which will work if you start your app from the directory that has public as a subdirectory.
However, it will break if you start your app from another directory. Let's assume that your app is located in /path/to/app/directory but that you start your script while /tmp is the current (working) directory:
/tmp$ node /path/to/app/directory/app.js
In that situation, Express will try to use /tmp/public as the location for your static files, which isn't correct.
Using path.join(__dirname, 'public') will create an absolute path, using the directory where app.js is located as the base. In the example above, it will resolve to /path/to/app/directory/public, which will also be valid if you start your script from another working directory.

NodeJitsu error: Error: ENOENT, stat '/opt/run/snapshot/

My app’s folder structure for NodeJitsu is as follows (i.e., when i do a jitsu deploy, I'm in the folder that contains "server.js" - i.e., the "server" folder).
Root server
|___server.js
|___package.json
client
|___www
|___index.html
|___css
|___js
|___etc.
So at the root is the folder "server", containing the starting script, “server.js”. Then there’s a folder called “client”, parallel to "server", with a folder within that called “www”, and within “www” is the main “index.html”.
In my “server.js” file, I have the following code:
app.get(‘/’, function(req,res)
{
var aPath = path.resolve(“../client/www/”, “index.html”);
res.sendFile(aPath);
});
I don’t have a app.use(express.static(__dirname + '/somefolder'). And when I start the app, I get this error:
Error: ENOENT, stat '/opt/run/snapshot/client/www/index.html'
My process.cwd() is /opt/run/snapshot/package. Obviously the above path isn’t pointing to the location where “index.html” resides. But I thought the way I do the path.resolve(…) should point to “index.html”. I can’t see where the problem is. If “server.js” is in the root, then to get to “index.html”, which is in “client/www/index.html”, then I should need to write “../client/www”, relative to the excuting script, to get to “index.html”, right?.
Do you have any insights as to where the path is not set up correctly? What should /opt/run/snapshot/ be pointing to? Or, what changes do I need to make in the get(‘/’) handler to correctly point to my “index.html”?
EDIT
I incorrectly drew the folder structure. Now it's correct.
I also turned off the app.get() and turned on the app.use(express.static(__dirname + '/../client/www/'). But to no avail: now i get a Cannot GET / error.
What I'm ultimately after is to have the "server.js" file be the Node server that, mostly, just serves AngularJS HTML files to the browser, with attendant images, stylesheets, etc., from the "client" folder. This is the server's main role, with an additional role of authenticating the app's users, employing the very nice Satellizer module. And that's it. I have a MongoDB attached, but otherwise this is a very common and straightforward Node.js server app.
Thanks!
Try it without rooting, resolving and log out to double check:
// notice no leading / which is root. __dirname should be the dir of current file running
var staticPath = path.resolve(__dirname, '../client/www');
console.log(staticPath);
Then pass that into express.static
app.use(express.static(staticPath);
I would probably recommend following the layout and convention of express generated apps with app in the root and static files under public
/public
<static files>
app.js
Then do what the generated app does:
app.use(express.static(path.join(__dirname, 'public')));

Setting Up Node.js App Directory

I'm completely new to using Node.js and even utilizing the command line, so this question may be extremely elementary, but I am unable to find a solution.
I am trying to set up an app directory using Node.js and NPM. For some reason, whenever I try to use the port:5000 I get a "Cannot GET/" error. My question is, why is my setup for my app directory not working?
I have installed connect and serve-static, and yet it will not retrieve files and listen on port 5000. I have created a server.js file in my user, kstach1. Here is the code I have within that file:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
app.use(serveStatic('../angularjs'));
app.listen(5000);
So, I don't quite understand why this won't reference my folder of angularjs, where I want to store my app. I have tested it by adding a file within the folder called test.html, and entered localhost:5000/test.html, and still get the "Cannot GET/test.html" error.
I know that Node is working correctly because I can enter scripts into the command line and they give the correct output. I do this as a user (kstach1).
The only thing I can think of that I may be doing wrong, is where my files are located. I have the angularjs folder located in the root user folder on my Mac (kstach1), as well as the server.js file. Is this incorrect? If this is not the issue, is it because of where Node is installed (usr/local/bin/node)? My research to this point has led me to think that my problem could also be that I need to add the installation directory to my path. However, I don't want to mess with this unless I know that is the case.
Any help would be greatly appreciated.
I did a little research on the serve-static package and copied the code you provided.
My project folder is located at "C:\teststatic" and the folder with the static files is: "C:\angularjs", also using "text.html" that is located in the 'angularjs' folder.
When running the code you provided and going to localhost:5000 it indeed returns "Cannot GET/". This is most likely because there is no "/" file declared.
Going to localhost:5000/test.html works for me, so you could try setting a "/" like this:
app.use(serveStatic('../angularjs', {'index': ['test.html', 'index.html']}));
And see if that works for you. If not, you should double check directory names / locations.
EDIT:
From reading the comment you posted: try this instead:
app.use(serveStatic('angularjs'));
I suggest moving your angularjs folder up into your main project's directory in a public/ folder. Its a pretty standard convention to have all of your static assets in public/. You can then use the path module to automatically resolve your path, inserting this where you have '../angularjs': path.join(__dirname, 'public').
So, your code would look like this:
var connect = require('connect');
var serveStatic = require('serve-static');
var app = connect();
var path = require('path');
app.use(serveStatic(path.join(__dirname, 'public'));
app.listen(5000);
And, your directory structure would look like this:
server.js
public/
angularjs/
test.html
You should then be able to use localhost:5000/angularjs/test.html to view your test.html

Resources