I come from a django background, and basically, the framework allows for a lot of modular code. I've created a simple blog engine in nodejs and express. However, all the routes end up being in my main app.js file, or rather app.coffee, since I used coffeescript for my nodejs applications, which complied to javascript.
So, say this is how my routes look:
app.get('/', index.index)
app.get('/users', user.list)
app.get('/blog', blog.blogList)
app.get('/blog/:id(\\d{5})', blog.blogEntry)
Now, the problem here is that if I want to sort these by categories, then this happens, then I would have to add another app.get function to the same file. Code:
app.get('/blog/categores/:cat(\w+), blog.someotherview)
If I wanted to add sorting according to time, for example:
app.get('/blog/time/:year(\\d{4}), blog.someYearView)
What I would like to do is delegate everything concerning /blog to be handled by blog.js for example. Ideally, how do I get all these routes out of the main app.js file?
You could easily do this by using the include() method in django.
Create an Express app in your app.js file, as you are used to. Then, do the same in the blog.js file. Import and use it within app.js as follows:
var blog = require('./blog');
var app = express();
app.use(blog);
Inside your blog.js file, all you need to do is to export your app:
var app = express();
app.get('/blog/...', ...);
module.exports = app;
To put it in other words: Any Express app can be used as middleware for any other Express app, hence you can create sub-apps.
Hope this helps.
PS: TJ Holowaychuk (the creator of Express) created a video on this, Modular web applications with Node.js and Express.
Related
I'm trying to better organize my node project. I'm doing so by moving all the code that has deals with handling routs to a file outside of app.js.
This is a screenshot of the code I wish to move to another javaScript file
I tried putting this code in another file and requiring that file and then got my project to run but when I visit any route int the URL it will say something like "can't get /login" in the browser.
From the little experience I have, it seems that express dose not listen when I try to use the code
app.use(example);
anywhere other than in app.js.
Question:
How Can get the code in the screenshot to work in a file other than app.js in order to reduce the lines of code in app.js
Make use of middleware to accomplish this.
If you want to make a folder or file where all the controllers are present, require express-router in your router.js file(s). To require express-router in router.js add:
var express = require('express');
var router = express.Router();
Add this file in your app.js or index.js using:
var exampleController = require("./routers/router.js")
Also give the path where 'exampleController' is to be used. Considering you want it to be used for Login/Authentication. After requiring it in app.js, add:
app.use('/authenticate', exampleController)
After this whenever the client tries to access the '/authenticate' path or anything nested inside it, your server will use the router.js file to perform all the operations, like get and post. Be sure to not use the complete path when you are in your router.js file. For example if the path is '/authenticate/register'. Your code for basic and get and post requests should be:
router.route("/register")
.get(function(req,res){
//Handle get requests
})
.post(function(req,res){
//Handle post requests
})
Now instead of 'app' you can use 'router' in the router.js file and it will work the same. It is like a 'mini-app'.For using this, Do give this last part express documentation on routing a read : https://expressjs.com/en/guide/routing.html.
I'm writing an express 4 api server with no front end code. I chose to structure my project so that the folder structure is based on the business logic of the project rather than doing it based on the type of file (routes, models, etc.)
For instance, my User folder has my userRoutes.js, userModel,js, userApi.js, ...
My main question is actually how should I pass the app into my routes files? My favorite approach was doing global.app and making it global, but I hear that is not best practice. If you have any advice on my business logic structure that would be great too.
Firstly, your file structure sounds over-the-top. If you need that much to split things out cleanly, go for it. But, I have a hunch that you're overdoing it.
In any case, what I normally do is return middleware from each module. You can give each middleware its own Express router if you want. In the modules:
const express = require('express');
module.exports = function (config) {
const router = new express.Router();
router.get('/something', (req, res) => {
// Code here
});
return router;
}
Then in your main application:
const somethingHandler = require('somethingHandler.js');
app.use(somethingHandler);
This is in-line with how all other Express middleware modules work. This also allows you to namespace modules by path, with your app.use() call in the main app.
You must require express app or pass to routes file by excute require function like this:
var app = require('express');
var userRoutes= require('your route path')(app);
I think global variable is not good idea.
I've got one incredibly long index.js route file for my node/mongo/express application. Here is the structure.
app.js
/models
Schedule.js
Task.js
etc...
/routes
index.js
/public
/javascript
etc...
I want something like this
app.js
/models
Schedule.js
Task.js
etc...
/routes
index.js
schedule.js
tasks.js
etc...
/public
/javascript
etc...
How can I split up my index.js file?
For example, I have tried to do something like this in my app.js file
var routes = require('./routes/index');
var tasks = require('./routes/tasks');
// later in the file
app.use('/', routes);
app.use('/tasks', tasks);
However, it is not finding my task routes like it did before when I had only the index.js. This is probably because I took all the routes starting with "/task" from my routes/index.js and placed them in routes/task.js, but why express not recognizing the routes in this new file?
Any advice at all would be helpful, my friend and I are very new to the whole meanjs way of doing things, and basically cobbled together what we have from various tutorials. Now we desperately need to refactor, because routes/index.js is getting too long to work with. I did my best to do what makes sense intuitively, could anyone out there give advice on how to break up our routes file?
Well, the answer to this question lies in how you import (require in this context) the router instance. Each one of those files should do a module.exports with a router object or something similar where the routes can be mounted on the app instance you create.
For example, have a look at how I do it (with yeoman's help that is) in a project I have on GitHub here, then refer to how the router object is exported for each route like this example.
As another example of doing this, here is an open source project I've been contributing to here. Notice that we have a slightly similar approach here, then have a look at an example route declaration (with the corresponding export) here.
I can't find a good bare minimum example where I can wire up an express.js route to call a react view.
So far this is what I have.
+-- app.js
+-- config
| +-- server.js
+-- routes
| +-- index.js
+-- views
| +-- index.html
app.js
require('./config/server.js');
require('./routes/index.js');
config | server.js
"use strict";
var express = require('express'),
app = express(),
routes = require('./routes');
app.set('view engine', 'html');
app.engine('html', ); // how do I tell express that JSX is my template view engine?
var port = process.env.PORT || 3000;
app.engine('handlebars', exphbs({ defaultLayout: 'main'}));
app.set('view engine', 'handlebars');
var server = app.listen(port, function(){
console.log('Accepting connections on port ' + port + '...');
});
routes | index.js
app.get('/', function(request, response){
// how do we call the route that will run index.html ?
request.render('index');
});
views | index.html
<!DOCTYPE html>
<html>
<head>
<script src="build/react.js"></script>
<script src="build/JSXTransformer.js"></script>
<script type="text/jsx" src="build/noEpisodes.js"></script>
</head>
<body>
<div id="noEpisodesMessage"></div>
</body>
</html>
and then my index.htm page as well as generated jsx.
2021 edit:
the modern solution is to use the create-react-app tool, followed by dropping in your code where needed. It's been set up to do the rest for you. The React landscape has changed a fair bit over the last six years.
original 2015 answer:
The usual thing is to use react-router to take care of the routes; write your React app as a single React app (i.e. all your JSX source ends up bundled into a single app.js file, which knows how to load all your "pages" or "views") and then use express (or Hapi, or any other server process) mostly as your API and asset server, not your page/view generator.
You can then tap into the routes you set up in the react-router Router object so that on the express side you can forward your users to the URL that react-router can deal with for content loading, so you get
user request site.com/lol/monkeys
express redirects to /#/lol/monkeys
your react app loads the correct view because of the routes in Router
optionally, your app does a history.replaceState so that the user sees site.com/lol/monkeys (there are some react-router tricks to do this for you)
You can also automate most of this through server-side-rendering but the name can be confusing: you still write your React app as if there is no server involved at all, and then rely on React's render mechanism to fully render individual "pages" for a requested URL which will show all the right initial content while also then loading your app and silently hooking it back into the content the user is looking at, so that any interactions past the initial page load are handled by React again, and subsequent navigation is "fake" navigation (your url bar will show a new URL but no actual network navigation will happen, React simply swaps content in/out).
A good example for this is https://github.com/mhart/react-server-example
The other answers work with the usual way to use react, to replace an element in the dom like so
React.render(<APP />, document);
but if you want react to be your "template language" in express, you can also use react to render a simple string of html like so
app.get('/', function(req, res) {
var markup = React.renderToString(<APP />); // <-- render the APP here
res.send(markup); // <-- response with the component
});
there are a few other things you need to take care of in terms of bundling all the dependencies and working with jsx. this simple minimalist tutorial and this blog post helped me understand the situation better
note that the sample code in the tutorial uses this syntax
var markup = React.renderToString(APP());
which has been deprecated and will cause an error. to use it you'd have to replace
var APP = require('./app');
with
var APP = React.createFactory(require('./app'));
or just render jsx like i did in the first example. to get the tutorial to work i might have also had to use more recent versions of the dependencies in package.json.
once you've got that down a fancier tutorial shows a more powerful way to use react-engine to render react within express
If you want to keep it simple you can do this for the entry point of your app:
routes | index.js
app.get('/', function(request, response){
// how do we call the route that will run index.html ?
res.sendfile('../views/index.html');
});
React is going to target a specific element on your index.html page in it's render method:
React.render(<Application />, document.getElementById('foo'));
So if your javascript is included in index.html and an element with that id is present react is going to inject your Application into that div. From that point onwards you can do all of the routing with react-router OR you can setup different routes in express and handle them like you did index.html
Instead of manually dealing with React.render you can use a library called react-helper (https://github.com/tswayne/react-helper). It sets up a div for you, binds your react components to the div, allows you to pass properties to your components server side, and can even handle server-side rendering if you have webpack configured for your node app or are willing to use babel-register (not recommended for prod).
Im fairly new to Nodejs and express, I was looking through some tutorials and examples and stumbled across
this inside app.js
var router = require('./router')(app);
What is the purpose of doing this?
This is whats inside the router file
module.exports = function (app) {
// The signup route
app.use('/signup', require('./routes/signup'));
}
You import your routers from another file.
This is a technique for scaffolding. Models, views, controllers and routers are kept in different files and then you import them into a main.js with require().
You create your project modular, it's more easy to scale and develop with team.
This is a popular modular pattern in javascript, often seen in node. Here's what you gain:
You can modularize your code into separate files so you don't end up with big monolith chunks of code.
By requiring the module as a function, you can pass some variable constants (such as the application config, or a datatbase entry point).
You can choose what to expose, and what to keep private by using module.exports which cleans up the global object for the application.
In the code snippet you provided, your passing the app config to the routes file, where you are creating a route that is reliant on the variable. If that route relied on interior logic, that logic could be scoped to the routes.js file rather than be exposed to the rest of the application.