michaellperry / jinaga

Universal web back-end, offering an application-agnostic API, real-time collaboration, and conflict resolution.
http://jinaga.com
MIT License
35 stars 3 forks source link

RequireJS & lodash dependency #21

Closed leblancmeneses closed 9 years ago

leblancmeneses commented 9 years ago

Was starting to add this into an angularjs project and tried to create a Nuget package to share between my projects. I don't use RequireJS. Would you be willing to break that dependency?

Reviewing: https://github.com/socketio/engine.io-client I'll be willing to use browserify since I know you want to support both client and server using the same lib.

Do we really need lodash? I would prefer using native array methods. The majority of uses is .each -> array.forEach .some -> array.reduce(function(agg, current){}, false) _.isEqual -> I would make it internal to your lib and copy it from stackoverflow or take from angular.equals

michaellperry commented 9 years ago

I'm all for removing dependencies. The Lodash function mapping can be done in a utility file, so we can still use the _ syntax. I don't think we need Browserify, since the Typescript compiles to both AMD and CommonJS. RequireJS is only a dependency for the Web example, so it can be referenced from a CDN.

leblancmeneses commented 9 years ago

Sure I'll take this on tonight.

leblancmeneses commented 9 years ago

I wasn't able to finish tonight, however, I created a branch to make sure we are on the same page for your review.

https://github.com/leblancmeneses/jinaga/tree/client-script

I'm trying to create a vanilla js version for the client without the need of amd, requirejs, or commonjs.
I'm leaving lodash, requirejs for server side as it doesn't affect client.

Goal: I just want to be able to include jinaga.js

<script src='https://cdn.firebase.com/js/client/2.2.1/firebase.js'></script>

I have a few lodash methods to convert in memory.ts and that dependency will be gone from the client script. I'm following this for typescript: http://typescript.codeplex.com/wikipage?title=Modules%20in%20TypeScript&referringTitle=TypeScript%20Documentation

I'm hoping /// <reference path="abc.ts" /> for client side and require('abc') for server side will play nice with each other.

michaellperry commented 9 years ago

I'd like to take the first commit separately. Please factor out the _pairs, _some, and _isEqual code from interface.ts if possible, and we can get that merged.

As for replacing import with reference, it looks like the guidance is to avoid that. References are for type checking against libraries implemented in JavaScript. Instead, I would like to find a way for TypeScript to mininfy a collection of source files down to a single JavaScript file. I'm pretty sure there's a way.

The end goal is to use Jinaga from vanilla JavaScript with no dependencies. That shouldn't require a large change to the source code.

michaellperry commented 9 years ago

I merged your first commit, removing Lodash dependencies. I finished up the memory.ts conversion as well. I've also factored those utility methods into a separate file.

Let's keep investigating the best way to remove the Require.js dependency.

michaellperry commented 9 years ago

After researching this, I think I see where you are coming from on the /// <reference path="" /> suggestion. I was hoping that TypeScript could compile several modules with inter-dependencies down to a single, simple JavaScript file for the browser. Unfortunately, it doesn't appear to work that way.

I'm considering one TypeScript file that contains all of Jinaga core, rather than breaking it up. This would be everything that the browser needs. It would not use imports or exports, and just define a Jinaga class in the global namespace. This would be compiled not as an AMD module, but just to straight JavaScript for the browser.

Then I would define an interface.d.ts file that describes the shape of the objects that a storage provider needs to implement (such as the Mongo provider). The Mongo provider could then reference this file so that the implementation of these interface classes can live in Jinaga.ts.

The end result will be a single file to reference from the browser that can be used with no other dependencies. And it will define just a single global, which is named for the project and not a usurped punctuation mark (ex, $, _).

leblancmeneses commented 9 years ago

I would first try : http://browserify.org/

Browsers don't have the require method defined, but Node.js does. With Browserify you can write code that uses require in the same way that you would use it in Node.

Drop a single <script> tag into your html and you're done!

michaellperry commented 9 years ago

I looked at that before going with TypeScript. I got the impression that it was for library users who want to bring Node libraries to the browser, not for library authors who want to make them available for both platforms. Once I learned that TypeScript could target two module systems, I was satisfied.

To bring in Browserify would be to force my users to take a dependency on it in the browser. Isn't that just as bad as forcing them to use Require?

leblancmeneses commented 9 years ago

I was hoping that it was just a bundler that could remove the module system that TypeScript produces.

browserify main.js -o bundle.js

michaellperry commented 9 years ago

I think I misunderstood it. Looks like the bundle can be published stand-alone. Let me take another look.

michaellperry commented 9 years ago

Browserify solved the problem quite nicely. Thanks! No dependencies, single file, and no changes to source code.

The Bower package is updated. Give it a shot.

leblancmeneses commented 9 years ago

Awesome! Seeing typescript evolve in this project is really giving me confidence that I should start using it now. Especially since you managed to solve the bundling problem. :+1: