JS modularization and assets embedding

Julien Singler
Wizeline Engineering
3 min readMay 24, 2018

Introduction

Let’s say you want to build a vanillaJS widget, containing html, css and javascript of its own that can be inserted on any website without creating any conflicts.

The requirements are then:

  • Modular code with minimum duplication
  • Minimum or no external calls to retrieve assets
  • No Javascript or CSS side effects. Isolation.
  • Elegant solution for a better maintainability

Which means:

  • No third parties libraries / frameworks.
  • Embed assets and HTML files (if possible)
  • Standard separations of concerns (your code is readable and maintainable).

Webpack

This article will not attend to draw a line between different es6 module bundlers or different approach (loaders vs bundlers). We chose Webpack because it answered our needs. As far as we are concerned there is other alternatives that would be as good as Webpack.

Authoring library

Documentation: Webpack Authoring library.

When you build a library you actually build a namespace via a module as you want your code to be a separated object that has a name and is distinguishable from other functions / objects.

Our team used Webpack to generate code that lives inside a namespace and can be inserted into any website without creating any javascript or css conflicts.

Folder tree structure is the following:

|- index.html (for testing inserting our widget)
|- src
|- js
|- images
|- css
|- views
|- index.js

First try

Since we are building a web widget, we use babel to transpile our files into a browser friendly javascript.
As the documentation tells us, we have to expose our library.

We used the name field inside thepackage.json as namespace but you could use something else. Since we do a web build, the libraryTarget field is set to UMD which makes it compatible with AMD and CommonJS implementations (web browser friendly).

UMD stands for Universal Module Definition, you can find more details here.

^ We have to export our components in this root file for Webpack to expose them in our namespace. You can now call your exposed modules this way : namespace.test.myfunction()

Now, this is building our Javascript files into one bundle. Nothing fancy since it’s what have been doing most of the websites for the last two decades.

What about assets?

Now, we have CSS files and images to embed into this bundle as we don’t want our widget to do external calls or at least a minimum amount of them.

There is many different loaders with webpack and that’s what makes our lives easier.

What will these loaders do? Well, images urls will be base64 encoded and inserted directly into your html instead.

Now, to get your CSS to be embedded you have to include it into your javascript application :

So we have now a bundle containing JS, CSS and some assets. But we are missing the HTML itself right? At that stage, you can still load your html views via external calls. But if you want to go to the next level and make sure your widget is self-sufficient, then read the next step.

Embed HTML as templates

We tried to use ejs with Webpack, unfortunately it can’t use url-loader inside the ejs templates, it leads to this issue which recommends using the underscore-template-loader which worked perfectly..

we built a small function that load the compiled html into the webpage:

So basically, the modal.html file is compiled into our Javascript file since we import it. Now we just have this utility function to insert that HTML where we want. There is other ways to proceed but this modal.html file is our entry point really and will be appearing when you click on a button.

Now what’s really interesting is that, you will probably have nested views and you don’t want to end up having one huge html file to support.

This is how we make sure we can import nested html views and our underscore-template-loader just magically do the rest :

That will also compile the nested.html inside the modal.html view which are located in the same folder.

Can you show me your dependencies?

Sure thing, here is our package.json file :

Conclusion

We are able to build a single Javascript file containing our html views, assets and javascript itself by leveraging webpack and some interesting loaders.

We hope you enjoyed this article, we will write soon about custom webpack loaders and CSS obfuscation in embed html templates / css files.

--

--

Julien Singler
Wizeline Engineering

"The world needs more weird people who know how things work and who love to figure it all out" - Zed A. Shaw