3

I'm creating a javascript library, and i want it to be environment agnostic (It will not use DOM, AJAX, or NodeJS api. It will be vanilla javascript). So, it's supposed to run in any javascript environment (browsers, npm, meteor smart packages, V8 C bindings...).

My currently approach is creating git repo with the library, with all the library inside a single global variable, without thinking about patterns like CommonJS or AMD. Later, i'll create another git repo, using my library as a git submodule, and create what is needed to release it as a npm module. I'm concerned if it's a good approach, i didn't found anyone doing this way. Pros: code will be vanilla javascript, without awareness of environment patterns. It will not bind itself to CommonJS. It will be repackable (copy and paste or git submodule) to any javascript environment. It will be as small as needed to be sent to browsers. Cons: I'll have to maintain as many git as environments i want to support. At least a second git repo to deliver on npm.

Taking jQuery as example, it runs in both browser and nodejs, with just one git repo. There is some code to be aware of the "exports" variable to run on nodejs or other CommonJS compatible enviroment. Pros: Just one git repo to mantain. Cons: It will be binded to CommonJS pattern (to achieve npm compatibility)

My question is: Am i following a correct (or acceptable) approach? Or should i follow jquery's path, and try to create a single git repo?

Update 1:
Browserify and other require() libraries are not valid answers. My question is not how to use require() on the browser, instead, it's about the architecture pattern to achieve enviroment agnosticism.

Update 2:
Create a browser/nodejs module is not the question, it's known. The question is: can make a real enviroment agnostic library? This example is binded to CommonJS pattern, used in NodeJS.

Community
  • 1
  • 1
Josmar
  • 584
  • 7
  • 16
  • related question: http://stackoverflow.com/questions/5171213/load-vanilla-javascript-libraries-into-node-js – Josmar Apr 06 '14 at 18:37
  • related article: http://addyosmani.com/writing-modular-js/ – Josmar Apr 09 '14 at 17:57
  • does this -> http://stackoverflow.com/a/23251110/2626313 <- answer about "Universal Module Definition (UMD)" patterns help? – xmojmr Apr 24 '14 at 16:56
  • The question is about patterns to be enviroment agnostic, not compatible (see update 2). But it's a useful link, thanks. – Josmar Apr 25 '14 at 19:34
  • I had to lookup what does the "environment agnostic" usually mean :) English is not my native language. You have my answer based on that new understanding of what you need ↓ – xmojmr Apr 25 '14 at 19:55

3 Answers3

1

If you are looking for design recommendation for your future library work then in my opinion you can think-future and just use usual Object Oriented Practices well proven in other languages, systems and libraries.

Mainly concentrate on the UML view of your design.

Forget the "one variable" requirement.

Use features proposed in the planned next version of JavaScript.

There is an experimental compiler available that allows you to write ES6-style code even today (see https://www.npmjs.org/package/es6-module-transpiler-rewrite).

Node.js has a --harmony command line switch that allows for the same (see What does `node --harmony` do?)

So in my opinion correct approach is to follow best practices and "think future"

Community
  • 1
  • 1
xmojmr
  • 8,073
  • 5
  • 31
  • 54
1

"Use a build tool" is the answer for this question. With a build tool, you can develop with the best code pratices, without accopling your code to some enviroment standard of today (AMD, commonjs...) and still publish your code to these kind of enviroments.

For example, I'm using Grunt.js to run some tasks, like build, lint, test, etc.
It perform tedious operations (minification, compilation...) like Make, Maven, Gulp.js, and various others.

The build task can handle standards (like commonjs) for the compiled code. So, the library can be totally enviroment agnostic, and the build process handle enviroment adaptations.
Note that i'm not talking about compiling to binaries. It's compiling source to another source, like CoffeScript to JavaScript. In my case, it's compilation of JavaScript without enviroment standard to JavaScript with commonjs standard (to run as a Node.js module).
The final result is that i can compile my project to various standards without messing with my code.

Aditionally, with a build phase i can "think-future", like xmojmr answered and use the EcmaScript 6 features on my JavaScript code, using Grunt plugins like grunt-es6-transpiler or grunt-traceur to compile JavaScript code from ES 6 to 5 (so it can run on enviroments of today)

Community
  • 1
  • 1
Josmar
  • 584
  • 7
  • 16
0

According to modular your library (if you need modules). Read this question Relation between CommonJS, AMD and RequireJS?

Take bootstrap for example, it uses npm to manage project dependencies and use bower to publish as static content for other web apps.

Take a look at browserify as reference, it's a little heavy because it provides the capability to bundle dependent npm modules as resource for browsers.

Community
  • 1
  • 1
shawnzhu
  • 7,233
  • 4
  • 35
  • 51
  • When you load jQuery files on a browser, you will have both jQuery and $ global variables. – Josmar Apr 06 '14 at 22:51
  • @Josmar you're right. the point is jquery only introduces very few global variables (`$` and `jQuery`, so far as I know). I'm against using global variables in javascript because it's the top 1 awful parts of javascript. see [Appendix A, Awful parts](http://stackoverflow.com/questions/2866866/jquery-global-variable-best-practice-options) – shawnzhu Apr 06 '14 at 23:02
  • Like i said in my question: "all the library stuff inside a single global variable". – Josmar Apr 07 '14 at 13:29
  • Browserify is not an acceptable answer, cause the question isn't how to use "require()" on browser. Updated question to avoid this kind of answer. – Josmar Apr 07 '14 at 13:45
  • Bootstrap is not an acceptable example. The twitter-bootstrap npm do not runs on the server, just in browsers. It's not enviroment agnostic. – Josmar Apr 07 '14 at 13:45
  • Updated the question to clarify what is not the question. – Josmar Apr 07 '14 at 15:49