Create an ES6 Module
Introduction
ES6 Time! I decided to migrate the share buttons script to ECMASCRIPT 6.
First some things I want to say:
- This is a prototype that may contain errors in code or concept. I am open to suggestions :)
- I just started, and if you are interested in ES6 you should too, reading the “Exploring ES6 - Upgrade to the next version of JavaScript” by Axel Rauschmayer.
- I started this code by reading this chapter from this book and using this repository.
- The code of this article is available in my github account in this repository to check it out.
What’s this post about
This post is about creating a small ES6 module we created in a previous post about Share Buttons Performance and a script to avoid all these problems. It’s a simple script that scans the dom for a specific class and adds a click event.
ES6 fast catchup
To fully understand this post you ‘ll need to understand some basic ES6 features. This is a rough explaination of these features, you should take a look at Axel Rauschmayer’s book for more in depth stuff.
VAR vs LET
In ES6 we can use let
to create block variables. Here is an example from MDN:
I noticed that if you set with let
the same variable in the same block you ‘ll get an error.
Arrow functions
In my opinion the main difference of using arrow functions is that the word this
doesn’t refer to the current arrow function’s scope but to some parent function that has a this
definition (We will see this in our code later). This means no more that = this
etc but this can be tricky, especially inside modules.
But here are some examples:
Template Strings
Yay! No more errors in your string templates! From MDN:
Template strings are enclosed by the back-tick (``) (grave accent) character instead of double or single quotes. Template strings can contain place holders. These are indicated by the Dollar sign and curly braces (${expression}). The expressions in the place holders and the text between them get passed to a function. The default function just concatenates the parts into a single string. If there is an expression preceding the template string (tag here), the template string is called “tagged template string”. In that case, the tag expression (usually a function) gets called with the processed template string, which you can then manipulate before outputting.
There is so much to learn about this but we are just going to cover the very basics just like we did before.
Here is how we are going to use our logMe()
with the new shiny string templates.
Modules
Last but not least, the modules. At last in ES6 we can create and use our modules in separate files and import them without any third party libraries. And this is what this post is about, building a simple module. But let’s cover the basics.
In ES6 we can use export
and have one default
export for a function or a class per module, or use named exports
to export as many functions as we want per module.
We are going to use two .js files, our module file called myLogModule.js and our main.js to import our module.
This is an example with a default export. This can be a function or a class.
If we were going to use named exports this is what we were going to do.
Or we can always import a specific function in our main.js
Or more than one
That’s a very (really) rough explaination of these features, but I am sure these are enought to continue with our own module.
Our Module
As I said before we are going to create our own module to see a more ‘complex’ situation. The script we are going to use is this and all it does is search the dom for elements with a .js-share-button
class and add a click event listener to each element that opens a window with a share url for facebook or twitter.
This is the script in ‘traditional’ javascript:
What we need to create is a main.js file as we had in our examples before, and a ShareButtons.js file with our module and begin by writing the functions we are going to use in our module.
ShareButtons.js
We can use let instead of var for everything without getting and error. This was a trial and error to for me. Every traditional function code is replaced with arrow functions. This module still reveals only the init function to the user.
Nothing else is changed in our init
or window_open
function
The most interesting parts are in the add_listeners_to_buttons
function.
First of all instead of using a for(var i=....)
function we used the new ES6 for...of
to iterate through our array of elements. Then we replaced our traditional string concatenation with the new ES6 string templates as we did in our examples before. That was easy and fun, I must say!
And now the evil event listener with arrow function and this
!
First I tried using this.getAttribute()
and never worked. Of course it never worked, it returned undefined, because this
doesn’t refer to the dom element but to some parent function.
After some research(google it) and some experemental time I came to the conclusion that I could either use a traditional function(e) {}
to get this
to work or (the experemental time we talked about) use the button variable that keeps the dom element. I wasn’t sure this would work but there was no error and the buttons worked whithout a problem. Up to this time I ‘m sure there is a way to make arrow functions and this
work inside an event listener but I don’t know it.
Another conceptual ‘problem’ I faced was the “What I am going to export? The main function? The init? What I am talking about? I just want to give the init to the user will the function export expose the other functions too?” and other fun things like these. At the end, it was easy, I needed to export the ShareButtons
function and expose only the init()
like I did before. Nothing else will be visible to the user.
So to export our module we add to the end of our ShareButtons.js file export default shareButtons;
. And that’s all for our module. It’s ready. I know this wasn’t difficult but if you create it from scratch you are going to face some problems - or not. I did :).
Remember, we could make this a class or we could separate our window_open
to another module and use it in our module to make things more interesting.
So, this is our complete module:
main.js
For our main.js file things are much easier. We just import our module as we did before and call the init function.
The code
You can try this code by downloading this repository from my github account.
Conclusion
Well, this was a big and fun post, at least for me.
As I said before, ES6 is new to me and I ‘m sure there are some errors in my concept or the code and it would be great if someone has any comment on this to make it better. Cheers!