What every developer should know about developing SPAs
Hang out in any front-end web development chatroom for even a short period and you’ll come across the same set of “help me” or “how do it?” questions over and over again. They are not difficult issues once you have learnt about them but until you do and while you are learning frontend development they are often a source of confusion and frustration.
So I thought I’d try and cover a few of the common issues that seem to come up repeatedly …
Seriously, the first thing to know isn’t anything technical at all, just a little common-sense. If you are asking for help, you are asking complete strangers to give up their time and energy to help solve your problem. No one is obligated to do that and people often have their own work to be getting on with so don’t be impatient or demanding.
No one is obligated to provide you with free 1:1 tuition or training so don’t demand help by inviting people to private chat or direct-messaging them unless they have offered this help. If no one is answering you, don’t just keep spamming the room with the same question - maybe it’s unanswerable or no one is available who knows about the subject.
There maybe no wrong questions but there are definitely wrong ways to ask questions. You will get better responses if you make clear you have put some effort in solving things yourself first and are not just looking for other people to do your work for you. So, explain what you are seeing, what you expect to see instead, what errors you are getting and what you have tried already to solve things and you will dramatically increase your chances of getting a positive, helpful response.
It’s not uncommon for the immediate issue we’re facing to be the result of a fundamentally wrong approach, especially when learning something new. So, don’t get angry if someone tries to explain that you are doing something wrong and would be better approaching it another way. You should be more concerned with learning how to do things right than just making an error message go away and if someone is willing to take the time to explain how and why, you should be grateful and take advantage of it instead of arguing.
It should go without saying that insulting people or the technology choices they have made isn’t going to make anyone enthusiastic to help you. Technology can be frustrating sometimes, but there’s no excuse for personal insults, denigrating someone else’s skills or bad language.
You are unlikely to get much help if your only description of an issue is “it’s not working”. Browsers like Chrome now come with incredibly rich and useful developer tools that will help you debug and analyze any issue you might be having and there is simply no excuse not to use them.
So, have you opened the developer tools and checked the console for any error messages as a first step?
bind or using a lambda expression / arrow function) without understanding what the issue is. Do a google search, read the results and learn how the platform and language you are trying to use work.
Learn to set breakpoints in code and inspect things. Posting an error message or stack trace to a chat room (or worse, a screenshot of an error message or stack trace) isn’t going to help - no one can debug your code remotely via chat unless it’s something really obvious (in which case, learn what those obvious things are to save you time).
That “HTML being loaded instead of script” issue is just one symptom of the misunderstanding around how routing works with Single Page Apps. The other problem you can run into is that you build the site, it works when you start at the home page but if you are on any other page and press “refresh” you get a 404 error.
Here’s why …
With a traditional server-rendered web-site, the browser sends the URL to the server and the server responds with the content for that page. But when you are writing a SPA, that isn’t how things work. What needs to happen is that the server sends the “index.html” page that loads the app for pretty much any request it receives that shouldn’t be handled as something specific (typically images, scripts and other assets that make up the site).
This is often referred to as a 404-redirect but it’s not really a redirect, it’s a re-write. You need the URL to stay as it was in the browser and the server to serve-up the
index.html page content for all requests that match the page routes in your app. The routing logic within your client-side code will then look at the URL in the browser and decide which view to load and render.
If you are developing locally and your development web-server doesn’t handle this re-writing for you then you should learn to configure it so that it does (most tools support it, if not find a better tool). Some frameworks provide tools with it built in - with Polymer’s CLI tool for example you just run
polymer serve and it handles everything automatically.
Remember - any server that your code is going to run on will need to be configured to behave the same way and that includes production. Now there was another solution that avoided doing this which was to move the “route” information to use the hash part of the URL instead of the path.
This meant that any page request was always to the root
index.html page and the server only served out that single page from the same URL path. If you have a server that doesn’t provide any re-writing then the hash-routing might be your only option but you should try to use proper path based routing if you can for SEO and other technical reasons.
Don’t “fix” the issue locally by switching which one you are using unless you can run with the same system in production when you deploy your app and plan on using proper path-routing if you can because it’s better, even if it might seem harder to get started with than hash routing.
Understanding how URL paths work becomes important when your app page content could be loading from different paths. You should understand all the pieces of a URL, the protocol, host, path and so on but especially the path part.
You may be used to loading everything from a full absolute URL such as:
This works great, but at some point you will have code or a component that can’t and shouldn’t know about the entirety of the app and instead just needs to reference something such as a script or image relative to itself.
This is when you’ll use a relative reference and it’s especially common with web-components where they need to reference other components but can’t know anything about the app they are being used with other than that the component they need will be a sibling to whatever folder they are in.
So, they will have a reference such as
"../polymer/polymer-element.html". This means that a component loaded from
/bower_components/my-elements/my-widget.html would be going “up” a level from the
my-elements folder to
bower_components and then down into the
polymer folder to load
polymer-element.html. It doesn’t matter if someone decides to call their folder “components” or “vendor” or anything else - the relative path works.
Remember, the path is relative to where things are going to be loaded from at runtime, not where they are on disk while you develop them. A common problem is mixing and matching things - it’s easy to “solve” a relative path issue by making some references root-relative (e.g. “/bower_components/polymer/polymer-element.html” but if a different folder is used or the app needs to load from a sub-folder instead of the root, this isn’t going to work. It will also lead to other issues where files that should be seen as the same and already loaded are not, because they are referenced from a different URL, so code that should only load and run once is duplicated and causes errors.
Remember to use the network tools tab to check what is being requested, that things are not being loaded from different URLs and that things are loading successfully.
It doesn’t matter that you read that es6 (or es2015 as it’s also known) is “the future” and it’s easier to use, if you want your site to run on a browser that only understands es5 you need to give it es5 to execute. It’s a bit like sticking a bluray disc into a machine that only understands DVDs, it just ain’t going to play because it just doesn’t understand it.
Incidentally, you may be thinking “I don’t care about users with old browsers, I’m just going to use es6 and serve that”. That’s definitely an option and it works (there are some technical reasons for wanting to serve es6 to a browser that supports it instead of es5). But I have bad news for you - one of the most important users that is ever going to visit your site still insists on using es5. Who? Google, that’s who. Yes, the google-bot currently understands es5 only so you still need to support it for now if you care about SEO even if you don’t care about any of the people with IE11.
var hasCompanyBeenActivated = false; and convert it to something smaller but equivalent, like
var a=0; (with any references also updated). Fewer bytes mean faster loading pages which is great.
But oh dear, you then have an issue and instead of the beautiful code you wrote you instead have a wall of hieroglyphic looking JS to try and debug.
No, you don’t.