What do you want to learn?
Skip to main content
by Jonathan Mills
Resume CourseBookmarkAdd to Channel
Table of contents
Why Best Practices?
Don't Code in a Vacuum
Write Code in a Maintainable Way
Rules of the Road
Automatic Semicolon Insertion
Now since I suggested using semicolons in conjunction with a linter, we should probably spend a couple minutes talking about linting your code and see what that means when I say that. Now, a linter scans your code to detect potential problems and errors and the keywords there are potential problems and potential errors. That doesn't mean when it says you need to do something it is an error, it just means that sometimes in some circumstances some things may break and so it helps you avoid that situation altogether and we kind of looked at that with semicolons. Right, semicolons or not using semicolons aren't going to break your code all the time, but every once in awhile it might cause a problem so we use a linter to help prevent that from happening. Now, JSLint was the first linting tool that came about and it was created by Doug Crockford back in 2002. It came preconfigured, it just worked right out of the box, using the set of rules that Doug Crockford wanted in his code and ultimately it still kind of sits that way. It's not very configurable. If you like the rules the way he likes them, then it works great, but I prefer something a little bit more configurable so there's a couple more options. The one I prefer is JSHint and JSHint is a fork of JSLint. So it started off of JSLint and they took a fork of that. It's much more configurable. There's a config file involved and we can change all kinds of stuff. It's got built-in package support. So if you're using a package code like jQuery, then it comes preconfigured for some of that. It's not very extensible, which means you can't extend on it very well and for most people that's just fine, but for some people it's going to be more of a problem. So there's one more that I'm going to just let you know exists and that's ESLint. ESLint's the most recent of the three and it includes some custom rules support just like JSHint does, but it also has lots of configuration options. It's actually much more configurable than JSHint is and with that comes some configuration struggles and for someone new using it right out of the box, it can be maybe a little bit of overkill, that doesn't mean it's not good, it's great, but if you just want to use something to get started, JSHint might be the way to go and so what we're actually going to do now is we're going to work through getting JSHint up and running on your machine. So JSHint is the one I'm going to recommend just for right out of the box just to get stuff done quickly. Now getting started with JSHint is really easy and there's a couple of different ways we can do this. The first one's in the browser, which may seem kind of weird, but I'm going to show it to you just in case you're interested. The way that works, go to JSHint.com and you can just paste your code right in here. And if I take the semicolon off of there, we get a warning that says "Hey, you're missing a semicolon" and if we do the same thing here, this is semicolons is all we've talked about so that's all I'm going to show you right now. But there you go. Also it'll tell you cyclomatic complexity and we may talk about that later and all of these things that are wrong with your code. You might imagine copying and pasting your code into JSHint.com is not the most efficient way to do this. So there's a couple other options. The next one is using brackets and we kind of looked at this earlier when we said we had a plugin to brackets that right here tells me, "Hey look, JSHint, I'm missing some semicolons everywhere." So we come in, semicolon, semicolon, semicolon, we can save that. I'm getting one error left, we haven't talked about that one yet so we'll come back to that. The way that I'm doing this inside brackets is I'm using a plugin. So if you can click the little Lego looking thing, then I have something called JSHint that I've installed into my brackets. So if you just click the Lego, go up here to Search and type JSHint, you'll find it right here. Then you can just install it that way. Now, this is actually very convenient because as I'm writing code, it'll warn me, hey you've got problems, something's going on. It is not necessarily the most convenient for a holistic project. Oftentimes you'll want to run a linter, or JSHint, across your entire code base and the way you do that is with a command line. So if I come to a command line and I do an npm install -g, I can run JSHint. Once I've got that installed, since I ran it with the -g, I can just type JSHInt right here at the command line and I can do JSHint and I've got one file in here, this one in my brackets window, semi.js, run that and I get no errors and I get no errors because I took the semicolons. Let me take the semicolons out and I'll run this again and now you see I've got some errors going. So those are the three ways that you can run JSHint. Now for the command line, you can also plug it into your gulp or your grunt or your npm scripts or however your particular situation is that you're running your build utilities or whatever you want to do there. I for one, whenever I have a gulp script running, I've got JSHint that runs inside of that. Alright so that's JSHint, that's up and running, and so now as we go through the rest of these syntactical things that we've got going on we'll refer back to JSHint and let JSHint identify those for us. But instead of just saying hey run JSHint and you'll see what's going on, I want to actually show you the issues that arise when you do some of the things that we're going to talk about.
Now one thing to call out real quick, notice I've got the double equals and I told you we don't do double equals, we want to do triple equals instead. Well if you look down at my JSHint down at the bottom, I've got two console is not defined errors, which is fine, but I want my JSHint to tell me about my triple equals issue and because I want to handle this stuff with my JSHint with my syntax and JSHint has a series of options available to enforce rules that are not enforced out of the box. So this is that configuration piece that we talked about earlier when we were talking about JSHint. And you can do bitwise, you can do camelcase stuff. If we go all the way down, there's one called eqeqeq that's going to prohibit the use of double equals in favor of triple equals. This is what we want to do and this is what I want to use and the way we do that is I'm going to right-click and I'm going to create a new file called .jshintrc and all we're going to put in here is a JSON object and this is a JSON object that basically has a set of parameters, in this case eqeqeq and true. Now that I've set that and I hit Save, I'm going to go back over to my equals and all of the sudden down here at the bottom, hey I expect triple equals and instead I saw double equals. Right here, I switch that to triple equals, I hit Save, now that error's gone. So I can go over to my JSHint options, look through what these enforcement options are, there's enforcing options, and I can configure JSHint to report on errors that I want to use in my code.
Read Only Properties
Octals and Hexidecimals, Oh My
What Is This Anyway?
This in New Objects
So let's create a new file just so that you can play around with this one in the exercise files. But let's do newobject.js. And let's create a function. So we'll just say var obj equals a function. And inside this function we've got this.hello = 'hello'. And we've got this.greet equals a function. And we'll just print out the greeting. We'll just print out hello. All right, now, here's my function, this.hello, this.greet. But it's a function, and so when I execute this function what's going to happen? This, as we've already said, is going to equal the global scope, right? So, that's weird and that doesn't mean anything. But actually, what's funny is I've seen this quite a bit, where people start doing this and then they'll actually just, well, actually they'll return an object with greet in it. And then they'll try and execute greet. They'll do object.greet. And it doesn't work, it's weird. And it's not even going to do anything. newobject.js, when I run that I get undefined. It's all weird, it doesn't even work. But I see people try and do something like this, thinking that it's going to make a difference, and it doesn't. But let's go back to our function, okay. So, I've got this .greet and we're going to say console.log, this.hello. All right, but what we're going to do now is we're going to say our var greeter equals a new object. So this is the 4th way that the this keyword gets dealt with. And so, var greeter equals new object. And in this situation, greeter is now a new object. And so the new keyword, when the keyword is executed, the first thing it does is it creates a new this scope. So now that I called new object, this actually has a scope. So if I just do a, let's see, let me just show you this. If I do a console.log on this, and I don't have the new, what am I going to see when I print this? I'm going to see the global scope. If I put the new on, now I have nothing. So, the new keyword binds a new this scope onto this function, that's what new does. Then it allows, so this.hello, this.greet, and then it also implicitly does a return this. Just like that. So, what that means is that I've got a greeter that is equal to just an object that has this.hello on it and this.greet. So let's actually, if we get rid of this, and I just do a console.log on greeter, that's what you'll see. See, greeter is now hello, and the greet function. Now I can just do greeter.greet. Execute that, and there I get my hello. Okay, so now I have this function. And I have, this function does stuff. And so now we're going to get into some best practices. Because this function may be an event that is fired. Now, I may hand this function off. So let's actually do that, let's hand this function off. Let's do a this.delayGreeting. And we're going to make that a function. And we're going to do a setTimeout. This is an easy way for us to play around with a callback. And we're going to pass into setTimeout, or this.greet. And we're going to set that for 1000, 1000 milliseconds. And then down here, we're going to call delayGreeting. Now when I run this, check this out. I get undefined. And that's weird, because this is obviously this.hello. This is the object. It should just work, but it doesn't, and I get undefined. And here's why. Because in my callback, setTimeout isn't calling object.greet. It's not calling, remember from over here in this file, it's not calling object2.printVal. It's making a copy of printVal, just like that, and handing it to another variable. And then it's just executing that variable. So, somewhere in setTimeout, there's a, so, if I setTimeout equals a function, then it takes a callback and a value. And it just does cb and executes it. Well, since there's no dot, we know what happens. It gets a global scope, and that stinks. That's not what we want. So there's two things we can do here. There's a painful way and a less painful way. And so, this is where we kind of get into best practice. So, if I go to this and I add this .bind, right, and so every time I do a callback, I pass in this .greet and I bind it back to this. I pass that in, hey, look, it works. Because I'm binding the function to this. Now, every time you do a callback, and every time you're going to pass something into a callback, you have to do .bind and that kind of stinks. And that's not a lot of fun, so let's not do that way. Let's do it this way. Let's actually take a copy. And I can say var_this = this. Now I'm not referencing the this keyword anymore. I'm referencing _this. And I can say hey, everywhere I referenced this, I'd just reference _this and it's all good. Now when I call .greet it's not looking for global this. Or the this context. It actually is executing a specific thing. And that allows me to maintain my hello. My reference. So this is what you'll actually see a lot of people do. When you're creating an object and you've got a constructor and this is all working, if you take a copy of this up here at the top, when you're creating your variables, if you're in Angular, I do this a lot. If I'm in Angular and I'm creating something for my controller, I'll just call it ctrl, my controller equals this. Or you might see it as a vm for view model. My view model equals this. And then it references the view model all throughout. And that's why, so that you don't lose your this scope over the course of the thing. All right, so that's this. And hopefully that was helpful to kind of help you understand what this does and where it comes from and all that kind of stuff. But to, ultimately, the best practice of. When you're dealing with the this keyword, it is easier to just take a copy of it and use that copy throughout than to try and always figure out what this might reference at this point. Because here, we're not referencing this. When I've got _this here, I'm not referencing this wherever I'm at. I'm actually referencing this very specific thing, which is for the object.
ES6 and Babel
Now before I can talk too much about the async stuff that I want to talk to you about we have to address ES6 first because actually the async stuff we're going to talk about it's even ES7 and so that's like not even close to here yet, but we can still use it because we have a cool tool called Babel. And when we're talking best practices there's a lot of cool syntactic sugar that comes along with ES6 that we could be using in our code today regardless of the browser, as long as the browser supports ES5 we're fine. So, let's talk about Babel real quick, and what we can do to kind of fix our code and some of the issues that we run into. Now, the feature list involved with ES6 is really extensive and I don't want to turn this course into a conversation about ES6 in general, more about the fact that you can use and should be using ES6 code. There's a lot of courses out there already, and just a lot of Internet references around what the feature set is involved with ES6, so I'm going to show you just one, I'm going to show you scoping, and then if that picks your interest then you can use Babel and you can explore ES6 a little bit more in depth. Well, let's go back a little bit to the issue we had with scoping before. And once again, I'm going to do this in the browser, so using index.html where we're pulling in app.js, and I'm doing this because these functions are native in NodeJS. So if we're running in Node and you're in strict mode, which you should be, best practice, alright, if you're in strict mode and you're in NodeJS you already have access to a lot of ES6 features, so there isn't this extra step that there is on the browser side, and that's what we really want to talk about here. So we want to talk about that extra step on the browser side using Babel. So, let's go back into our app.js, and let's just do something simple, so let's do just a for loop 'cause this falls into what we were talking about. So let's just say var i = 0, i is less than 10, i++, and we'll just print that out to the console. Now, if you're coming from another language you may think "i" is safe. When we talked about, we've talked about scoping and we're not going to rehash that, but I can right here say, "Hey, 'I see i....'" and if I put a "+ i" there when we run this code, we look at our console, you see "I see" 1 through 10. So it's 0 through 9, "I see i ...." and i equals 10. So we don't like that. Really want to use the let keyword because the let keyword is going to allow us to hide that i from everything else, and so the point of all of that comes down to we can use Babel to compile down our var, so we can use let, and still use that in the scope of ES5. So, here's what we got. If we go to our command prompt there's two things we need to install, we need to do an "install -g" on babel-cli and then we need to create a file called .babelrc. And this babelrc file basically just looks like this, it's just a JSON file that says, "Hey, I've got presets and plugins", and for right now our presets are "es2015". And so what that preset's going to allow us to do is compile ES2015 code down to ES5. So if we run back to the command line we also want to do "npm install", I'll make that a little bigger, "npm install babel-preset-es2015". And when we install that that will now give us the preset for Babel so that we can run our code because right now, while that's installing, right now if I use let, and I'll actually show you this on the Safari side 'cause Safari is actually worse, if I refresh this page you see, "Hey, 'unexpected identifier i'". So it doesn't know what to do with this let keyword. So that's broken, which is what we expected. So I've got my app.js with my let keyword, Babel's done, so now what we're going to do is we're going to type "babel app.js -o es6.js". And what that's going to do is convert our app.js file to code that is runnable inside ES6, and we can do this with all of the ES6 commands, so like class and Arrow functions and all of that stuff, we can now use and we just do Babel to transpile it down. So now if I go to index and I change this to es6.js what we expect is now we get "i is not defined". And if we go over here and I refresh, look at that, "can't find variable i". So now that's how to get up and running with ES6, we've got Babel, Babel CLI, you can wire up Babel into Gulp or Grunt or whatever build process you use and compile all of your ES6 code down to ES5. So now that we've got that now we can talk about async, which is actually not even ES6, it's ES7, but Babel will still work for us.
Async - Await
Alright, so coming up in ES Next is Async/Await, and what this does is kind of eliminate the need for callbacks and promises and all that with the way it works. And so let's take a look at how these functions work and how we can start using them now. Alright, so to start with it's still based off of a promise, so the Async/Await mentality still works off of the promise principle, so our asyncMethod is going to remain unchanged. It's going to still return a new promise and everything is going to be fine. But what we want to do now is create a new method and we're going to create an async method called main, and we're just going to run everything through this main method. And we're going to take all this stuff and we're going to drop it off in there. And then we're going to call main and execute that. Now, what the async method allows us to do is to use a keyword await, and what await does is eliminate the callback, it basically is going to sit and wait for this async method to continue or to be done before it continues. So, actually, we'll just do this, var one = await asyncMethod, and so what used to be passed in a callback now gets passed into this variable, and we'll just do this. We'll create a bunch of these, just three of them, and we'll get rid of our .thens. And this will be "two", this will be "three", and this will be "four". And let's pass to our methods this way. And our last one. And then we'll get rid of all our functions, and now we just have this. So basically it's each variable await asyncMethod, I'll pass our awaits on them. So basically now what we have is await asyncMethod open a database controller, await asyncMethod find the user, and it's just going to execute this in order. Now, just so you get an idea, we haven't been using variables in our callbacks, so just so you get an idea of what this is going to look like let's change our asyncMethod to take a number, and our number is actually -- So we do a console.log(message), we'll just add that number to the end of it, and then when we call fulfill we'll just increment the number. So we say, "Hey, 'Open DB Connection 1'. 'Find User 2'". And we'll pass these variables in so you can see how that works. And this first one we'll just pass a 1 in, or we'll pass a 0 so you can see it. Okay, now, basically what that means is, "Hey, whatever gets executed in this callback "gets assigned to this variable", and then I can use this variable in my next call. This is cool if it works, and so we got to get there. The first think we're going to do is we're going to create our new file .babelrc. And our .babelrc is going to look extremely similar to the last clip. So, "presets", "es2015" and "plugins". Now, here's the deal though, in ES Next we're not talking about ES2015, and so what I want to do is I want to take you to a website that you should become very interested in, and this is a compatibility list of all of ES5, 6 and Next. So if I look at 6 you can see what features, so for example the Arrow functions that we haven't talked about yet, or Map or Typed Arrays, and you can see what browser support what. And notice Node 0.12 doesn't support a whole lot but we get up into Node 5 now all of a sudden we've got a bunch of green. Babel's the same way. So if we go to ES Next we can see where our function support is, and so if we look at async functions Babel core supports them. And they support them in something called Stage 3, and just real quick, 10 seconds or less, Stage 0 means these are things that we would like to support sometime, Stage 1 is proposed, 2 is draft, Stage 3 actually has a pretty darn good chance of getting included in a next version of ECMAScript. And so they've moved away from, I sometimes use interchangeably ES6, ES7 and 2015 and Next and ... That's fine, some people get better shape, it's okay. But ES Next is going to potentially be ES2016, right? Maybe, if it gets done. But then we have Stage 3, things to get included, and you'll see async functions are in Stage 3 and they have basic support for await. So what that means is we have to pull in the Stage 3 preset. So once we've got the "stage-3" preset we need to install it, so "npm install -save babel-preset-stage-3", we'll run that. And then once that's done we'll run our compiler. So "babel app.js -o esNext.js". Now, just for simplicity sake we're going to just leave it there and so one thing we need to add to our app.js is 'use strict' because we're going to run this in Chrome and this is going to pop up a lot and I'm just going to let it go because we can, so we'll do a 'use strict' instead of trying to pipe it through a whole bunch of other stuff. There we go. So that has run and we go to our index and now I'm pointing to esNext.js. So we're going to run this. And when we look at this now you look and see 0, 1, 2, 3, that's exactly what we were expecting. Let's refresh. 0, 1, 2, 3. So what' we're getting is this asyncMethod('Open DB Connection') returns 0 + 1, and so now this variable "one" actually contains this. And so that's kind of how async works, it's just a quick little look, a peek into the feature, if you will, of what's coming for callbacks and promises, and we're going to end up in this Async/Await style which is kind of what like everybody else does. Like if you do .NET you just wait for it to come back, and so that's kind of what it's implementing here on the site.
So the first thing involved in getting your Node code production ready is npm and using npm in the right way and there's a couple of tricks I want to show you that may help in getting you ready for where you want to go. So let's start. I am in a new directory, basically I just have my app.js file, and I've got my app.js just console.log('hi'). It didn't really do anything. But the first thing you want to do always, and you probably already know this, the first thing you want to do always when you're creating a new Node application is nmp init and what nmp init is going to do for you is it's going to create your package.json file and your package.json file is actually really important and we'll talk about all the reasons why here in just a minute, but to get it up and running and do it right, just take the defaults, there you go, let's set up, it's ready, and now I have this package.json file that I can use to get some stuff done. If you're lazy, delete that, and you do a --yes, oh look it's done, you don't even have to hit Enter, you don't have to do anything. Okay so there's my package.json file and there's two things about my package.json file I want to talk about right now, first and foremost, and the first one is dealing with the engine keyword. Now you may not have seen this, but basically I can say hey I can set my engines or the versions of node that I am allowed to run on. So in this case, let's just do this, let's do 4.2.1. I am running currently 4.1.2 and this wants 4.2.1 so in theory my code should not work 'cause I can just say hey everybody, I am only allowed to run on version 4.2.1 of Node. Now you can do the same thing with this that you can do with your nmp packages, or your dependencies, you can do the tildes or the less thans, I can only run on things that are less than 4.2.1 and that should work. Now what this does is says when I'm a package, when I'm installing something with a package.json, it checks this engines and let's us know whether or not it's okay. So in order to see that, we're going to do a cd .. and then nmp install code. So I'm installing this thing I just did and I'm going to get a big, huge warning that says "Hey, Node 4.2.1 is wanted" and I've got 4.1.2 and npm 2.14.6. So everything's old and so it's bad. So that's a way for where you just to say hey this is only for Node 5 or this is only for Node 0.10, right. Node changes fast and it's really a good idea to wrap some constraints around your code to make sure that if somebody's running bleeding edge Node that your package isn't going to work on that they get an error saying hey this isn't going to work. Alright, one other thing that I want to talk about when it comes to npm packages is if I'm sitting here and I'm in code and I do an npm install express, I'm going to install Express, it's going to go into my Node modules, oh it didn't get into my package.json. Hold on, so we got to go back, save 'cause you always do --save because it's going to pop into this directory and now I have my dependencies and so basically what this says is hey anything that's close to 4.13.4 go ahead and install and there's two problems with this. One, I'm lazy and I want to keep things simple as possible and the --save is offensive to me because if I'm doing nmp install, I know that I want it there. Almost never do I do an nmp install on something inside my application and not want it to be saved. So the --save is this unnecessary extra thing that I have to add when it should be implied and also I don't like the idea of the caret because my code and especially we've seen some issues where package developers are deploying breaking changes from one minor version to the next and that's not cool and so I don't want it to default to this caret. So what we can do is set two command line parameters for nmp that will solve a lot of these problems. The first one is this. So we'll do an npm config set and we'll set save equals to true. Now just by doing that, if I do an nmp install passport and I run that, look it saved it automatically. No more --save for every single thing that I'm trying to do an nmp install on. But I still have the caret and I don't like the caret because I don't know if I'm going to work with 0.3.3 or 0.4.0. I want to use the version that I know I work with and just use that version and when I have tested a new version then I can change my dependencies and so let's fix that as well. So here you're going to do instead of save=true, we're going to do save-exact=true. Now if I do, we'll just come in and we'll delete these two, save that, and I'll do nmp install passport, nmp install express, look at that, there they both are, the exact version saved, I didn't have to do --save, I didn't have to do any of that. So that's setting up your nmp environment. So now I've got nmp, I've got my package.json file, it's done, it's set up, I've got my dependencies being tracked. When it comes to best practices for deploying production code, this is the start of it. Right, so I've got a file here that says this is the way it's going to be, this is my code, this is the version, this is the version of Node I run on, here are my dependencies. You don't have to worry about whether you forgot to do --save on that one. That's no longer a concern for you.
The next thing we're going to talk about is the environment that you're running in because some things are going to be different between where you're running in Dev versus running in QA versus running in production and one of those things might be your database connection strengths, that's definitely going to change, or your port that you're running on, that could change, or there's a lot of other potential things that will be different from one environment to the next and one of the easiest ways to do that is to use a tool called Node Foreman and we're going to get into how to work with that to get your environment set up to be different from one thing to the next. So back to my application here and I've got my app.js and when we start up an Express application specifically, we always run it on a port and the standard thing that you see a lot is now you see Express listening on port and then a port number and where we want to pull this port number form is from our process, process.env.PORT, and that's ultimately what we want to do is we want to, after putting a plus in here, we want to keep our ports and our connection strengths and all those things in our environment and let everything else deal with it and the way we're going to do that is we're going to use a tool called Node Foreman and Node Foreman does a lot of stuff for us. It can set up worker processes and do all those things, but right now we're going to focus just on the environmental variables and the first thing we want to do is do an nmp install -g foreman and what that's going to do is allow us to use the NF command to run our application for us and what Node Foreman's going to look for, if we go to our package.json file 'cause remember everything comes back to our package.json, is it's going to run a script. So if I say start, our start command is going to be app.js. So now I have a script called start that's just going to do node app.js because app.js is the script I want to run. And so now if I do nmp start, it'll run and you see right here listening on port: undefined because it's not there, right. But if I do nf start, which is Node Foreman, Node Foreman is going to run that start directory and hey look, Express is listening on port: 5000. Isn't that weird, it has a default to some of these things. And so it's automatically setting our environmental variable because it didn't find, no ENV file found, it automatically set some stuff and so let's fix that. So right-click, new file, ENV with a dot in front of it, .ENV, and this is going to take a JSON object and we're going to say hey our port is going to be 9000 or I could say our connection strings, our sequel one and our mongo one. We can do all that stuff right here in our .ENV file. And now I can get to that or Node Foreman will automatically take everything in my .ENV file and stick it in my process.env. So if I run this, nf start, hey look, Express is listening on port: 9000. So make sure that as we're writing our Node code and we're building out our applications, we're pulling in environmentally specific things using our process.env and then we use a tool like Node Foreman, you could use Nodemon or a couple others, to set your environment. But Node Foreman, what it will do, it will set your environment and get it ready to go so that when you deploy to production and you do nf start in production, you're pulling in your .ENV from there instead of whatever you're running locally. So just a simple little thing you can do to make sure your code is doing the right thing in production without having to do some weird hack to make it work.
Cross Platform Concerns
One thing that's easy to forget is that Node.js is truly cross platform, it can run on Windows, it can run on Mac, it can run on Linux, all of that full across the board and sometimes that comes with a couple of gotchas and I want to show you one of them real quick. I'm going to create a new file called myObject.js and this object is going to do a module.exports and we're just going to send back an object that says hi: 'Hello there' and we're going to go back to our app.js and we're going to say var myObject = require('myObject') and then instead of console.logging our port, well we'll still do that, but we'll also CL myObject.hi because myObject.hi is hello there. Alright, if I run this, everything breaks because I need my dot slash. There we go, alright now let's run it. And of course, not my semicolon. We know I talked a lot about semicolons, well don't use it there. Okay, now we ran it and I said hello there. So this seems extremely straightforward, I don't know why I'm wasting time with this. Right, so I've got my myObject, my myObject, all that's cool, everything's great. If I rename this to myObject, actually in order to get it to do it, I've got to cut that, I've got to do a delete, don't save. I'm going to do a new file, myObject.js, paste that. Oh look, now when I run it, look how it still works, myObject lowercase, myObject uppercase, it all worked. This is where you start to have problems with cross platform because in Mac and Windows, this myObject and this myObject are the same thing, but on Linux they're different and so the best practice here when it comes to making sure everything's cross platform able, one of the first things you do is everything's lowercase, your file names are lowercase, this is lowercase, and if you're actually doing a full-blown package, it'd be more like this. A lot of us are used to doing the camelcase. Well, we don't do that, we do this because the camelcase, if your file name's aren't correct, can cause you problems. So just little snippet there. Make sure that everything is lowercase as appropriate and you can do the dash casing, there you go, to make sure everything's going to run appropriately, right. So that's that for the cross platform, making sure everything's going to work. Just be aware that Linux, especially with file systems, is going to be a little different. Windows will have its own idiosyncrasies, but just be aware.
Simplify Your World
Released5 Apr 2016