I understand most apps using Node and Express use a view engine (ejs, pug etc…), and you can very well do without, sticking to plain HTML.
From my perspective, a view engine only adds an extra layer of complexity, as it means you have just another syntax to memorize, on top of the specific syntax of all the frameworks you have hardly mastered. I find HTML easy enough to read with the opening and closing tags, and indents.
So, why use view engines ? What do they actually bring ? I did a quick research, no one seems to explain that. It seems everyone uses view engines as if it’s just the way to go because everyone else is doing it.
3 Likes
Templating.
EJS stands for Embedded JavaScript - which means you can pull JS from the server to dynamically create page elements.
For example:
<!DOCTYPE html>
<html>
<head>
<% include ../partials/header.ejs %>
</head>
<body>
<% include ../partials/navbar.ejs %>
<div class='container'>
<div class='collection'>
<% for( var i = 0; i < docs.length; i++ ) { %>
<a class='collection-item' href="/results/<%= docs[i]._id %>"><%= docs[i].poll %></a>
<% } %>
</div>
</body>
</html>
The <% ... %>
style of tag is the way you pull in the embedded js. The include partials
ones save me from typing the same boilerplate code over and over again. For example, my nav bar only needs to exist in one place, and then I include it on every page.
This bit:
<% for( var i = 0; i < docs.length; i++ ) { %>
<a class='collection-item' href="/results/<%= docs[i]._id %>"><%= docs[i].poll %></a>
<% } %>
Renders as many objects as have been passed from the server to the view. If you read it carefully you’ll notice it’s just a loop, but EJS lets you use that loop to dynamically write HTML to the page. On the client side, if a user views source, all they see is the fully rendered page - they don’t see what kind of object was passed or how the page was constructed.
It’s a very messy syntax, but super powerful. Definitely worth learning.
3 Likes
As @JacksonBates pointed out, it is very powerful.
At first, I liked EJS, because it was like HTML, but with superpowers, but then I saw that Jade (or Pug) also adds an easier way to write HTML. You can only put the starting tagname, and BOOM works like a charm.
If you worked with Emmet, you know what I mean.
For example, if you are working with bootstrap and want to build a 3 column layout:
.container
.row
.col-md-3
.col-md-3
.col-md-3
Converts into:
<div class="container">
<div class="row">
<div class="col-md-3"></div>
<div class="col-md-3"></div>
<div class="col-md-3"></div>
</div>
</div>
A good resource for understanding Jade:
Also, codepen gives you the possibility to work with it.
1 Like
Thanks! I see. So, when do you use EJS and when do you use React ? Based on your explanation, I feel EJS allows me to do what React also allows me to do. And you would probably prefer to focus on mastering React and use React in your app.
I use EJS for something reasonably small in scope, or something that didn’t need to deal with data in the React way . For bigger projects, I’d use React.
1 Like
I’d also add that I think at their core, they’re essentially opposites - with view engines, you’re creating HTML and inserting a bit of JS here and there. With React, you’re actually writing JavaScript, and you just happen to have HTML in it.
Once you start building larger-scale applications, you’ll come to realize the difference, I think, and why React can be so powerful. (You can always try building a larger-scale application with a templating language…if you do, let us know how that goes; I’m genuinely curious, although I should maybe warn that that sounds like an enormous headache to me. )
A view engine allows you to render HTML with options. For example, using squirrelly, I can create a file that looks like this:
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
{{if(options.userSignedIn)}}
Hi, {{user.name}}!
{{#else}}
<button>Sign in!</button>
{{/if}}
</body>
</html>
This is especially helpful for sending server-side logic to HTML; for example, you could use Express to listen for a request at a dynamic url (users/:username), fetch the user, and then display user info by passing it into an options object.
1 Like
React is built for rendering all of the UI for single-page apps - ie there is one HTML page, and the app sits inside it. Template engines like ejs and pug are just for rendering HTML pages, they have no concept of behaviour.
They work differently. So with React, when you write code using the framework, you never write any HTML. You can write the render part using something that looks like HTML (JSX), but that’s just basically a plain JS object with some syntactic sugar to make it look like HTML. React builds a model of what the HTML should be, in JS. When you apply updates to that (maybe an onClick prop that triggers a state change), it compares what you want to change with its model, then goes and does the HTML rendering/updating bit using that model.
React is not designed to just make arbitrary HTML pages. Template engines are. In theory you could make a React-like thing using say Pug, it’s just JS and you could wire it up (eg LoDash has a builtin templating engine, jQuery at least used to as well). But it gets super complex for large apps, and string-based stuff is normally super slow. Note React is designed to fix the problem of large JS apps generally being unmaintainable
1 Like