DEV Community

Namespaces and Javascript: I Don’t Know What I’m Doing

Dave Jacoby on February 07, 2019

Here’s a simple JS library I wrote today: let rr = {}; rr.data = {}; rr.code = {}; rr.code.listen = function (event){ console.log(this.respons...
Collapse
 
joelnet profile image
JavaScript Joel • Edited

So, I’m curious: What is the best way to handle JS namespaces?

I don't namespace.

I use es modules and bundle them with webpack (for web apps). This way I never pollute the global namespace. This is the approach I would recommend.

In the past (previous to webpack) I have also use an IIFE to encapsulate my code to prevent it from being exposed globally.

(function(global) {
  // code goes here
}(window || global))

However... I have had some times where I am forced to make something global. This was in a legacy application that was a mess.

I used a function similar to this:

const namespace = (context, name = '', object) => {
  const [head, ...tail] = name.split('.')
  if (tail.length > 0) {
    return namespace(context[head] = context[head] || {}, tail.join('.'), object)
  }
  context[head] = object
}

namespace(window, 'math.add', (x, y) => {
  return x + y
})

window.math.add(3, 4) //=> 7

p.s. I would run through a little testing with that function, I just kinda whipped it up on the spot, so I don't know if it's buggy.

Cheers!

Collapse
 
jacoby profile image
Dave Jacoby

I'd be happy to learn more about this approach. I'm very trailing-edge in most of the technologies I use, because I regularly switch between dev to admin to helpdesk, so a link that goes into how this works and why would be appreciated.

Thanks!

Collapse
 
joelnet profile image
JavaScript Joel

If you are just starting out with this, I would recommend looking into Parcel (Getting Started). It's an easy to configure bundler. You can get up and running in a few minutes.

I personally prefer Webpack (Getting started) because I am more familiar with it. You'll have to be familiar with other toolsets, like babel or webpack-devserver, etc. It's more work.

Got questions, hit me up on Twitter!

Cheers!

Collapse
 
anduser96 profile image
Andrei Gatej

What I would do is to have a file from which I export constant variables.
For example:
const addPost = ‘post/add’
const addComment = ‘comment/add’

At least one downside of using this approach would be that you have to include this file everywhere you are going to use that specific function for that specific namespace.

I have tried this when developing a Vue app with Vuex, but fortunately, Vuex has also the concept of namespaced modules(I know I’m going a little bit beyond the scope of the article).

Here is a demo of both implementations: github.com/Andrei0872/vue-pocket-r...

Hope you found this useful!

Collapse
 
jacoby profile image
Dave Jacoby

If you'll excuse me, I'm not really seeing what that buys me. I guess I knew that const was added to ES at the same time as let. Can you do const addPost = function () { /* adding post here */ }?

My prime concern is keeping my "toys" to the corner of the "playground" so nobody else's stuff gets mixed up in mine, and vice versa. It isn't immediately clear what this does to help me.

(Disclaimer: JS Dev is one of the hats I wear only rarely. I've looked at Vue.JS once, maybe. People tell me it's nice.)

Collapse
 
anduser96 profile image
Andrei Gatej

I’m sorry, now that I look twice, my answer is pretty misleading.

But just to finish my idea:
const addPost = ‘post/add’
You could define this as an obj prop:
{
addPost { ...}
}

Anyway, it doesn’t seem to be practical. There are definitely better ways that have already been mentioned.