Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unclear how to use forge with the bower install #229

Closed
henry74 opened this issue Mar 10, 2015 · 10 comments
Closed

Unclear how to use forge with the bower install #229

henry74 opened this issue Mar 10, 2015 · 10 comments
Milestone

Comments

@henry74
Copy link

henry74 commented Mar 10, 2015

I've been trying to use forge after doing 'bower install forge' in an AngularJS application and it's unclear how to get the objects to be available.

I've resorted to manually creating the forge.min.js and including it directly in my index.html file as opposed to letting the build process pick it up through bower_components. I have multiple js libraries installed through bower and only the forge library has issues.

@dlongley
Copy link
Member

@henry74, forge is a modular project, so you have to include all of the scripts you want to use in your project. If you're using a module loader (RequireJS) this will be done for you automatically. If you're just trying to get access to the global forge variable and use html script tags, then you'll have to include all of the scripts you want in the proper dependency order. See #170.

Using forge.min.js will automatically pull in the whole library -- and is another option, but as you said, you have to manually build it. Forge doesn't distribute the minified binary in the bower package, see #155. It's likely different from other js libraries you're using because it's a crypto library -- which means how minification works may have more important consequences than non-crypto libs. We may end up including minified source in the future, as this isn't always relevant (it depends on which parts of forge you're using) but we'll need to work out how to best make it clear that there's an important difference between minified crypto and minified non-crypto source code.

@henry74
Copy link
Author

henry74 commented Mar 10, 2015

Makes sense, perhaps an example of injecting the scripts to make them available in AngularJS would be helpful? I'm just not sure where to start from an AngularJS injection standpoint to make them available.

@dlongley
Copy link
Member

AngularJS's modules and dependency injection is at a different layer of abstraction from other JavaScript module loaders or the browser's loading of scripts. This is sometimes a point of confusion.

Here's a quick high-level run down of the two different layers:

  1. Scripts the browser has access to. Module loaders like RequireJS, browserify, etc. can handle JavaScript file loading and dependency management for you. These loaders are responsible for making HTTP requests to your server to grab files when necessary. AngularJS modules/DI don't have anything to do with this.
  2. Components in an AngularJS application. AngularJS modules don't have to do with loading JavaScript files from the server, rather they allow you to break up your AngularJS application into reusable parts.

There's no registration of an AngularJS module "living" at a particular URL that gets fetched at some point. Rather, once some JavaScript file has already been pulled in by the browser (either via script tags, RequireJS, etc), it can run and register itself as an AngularJS module with some name. Then other AngularJS modules can reference those modules by name and declare them as dependencies, so when the AngularJS parser runs and needs to create directives, etc. it can find the (already loaded) JavaScript it needs.

So, before you can even begin running your AngularJS app or using its module system, you need to have your scripts available; which can be done either via script tags or RequireJS, or whatever module loader you prefer. In other words, you can combine AngularJS with a JavaScript file/module loader, they are two separate things.

All of that being said, forge has nothing to do with AngularJS. It's not an AngularJS app and it doesn't contain any AngularJS modules. There's nothing to (AngularJS) dependency inject with respect to forge. Forge should just be loaded either via script tags or some other JavaScript module loader of your choice.

@dlongley
Copy link
Member

If you really wanted to hook forge up to AngularJS, you could create another JavaScript file that does this:

var module = angular.module('forge', []);
module.service('forge', function() {
  // return the global forge instance
  return forge;
});

That's just an example. There are a number of other ways to get forge into AngularJS' DI system if that's something you need. Keep in mind, if you're not using a module loader like RequireJS, forge is going to be available as a global anyway. So it really only makes sense to do this if you're using a module loader.

See: http://www.sitepoint.com/using-requirejs-angularjs-applications/
See: http://leog.me/log/making-sense-of-requirejs-with-angularjs

@henry74
Copy link
Author

henry74 commented Mar 10, 2015

@dlongley Thanks so much for the overview - super helpful!

With regards to using the bower install forge method - I did validate the forge.js library was loaded into the browser. I was using a gulp script which automatically injects all js libraries in bower_components into the index.html so it was correctly loaded.

My problem was actually using the objects off the forge object - they were all undefined so I thought I had to inject something into the angular modules to make them available. But based on your comments I'm thinking there is more to do after the forge.js file is loaded to bring in the forge modules you want to actually use within Angular...

@dlongley
Copy link
Member

Thanks so much for the overview - super helpful!

Sure :).

With regards to using the bower install forge method - I did validate the forge.js library was loaded into the browser. I was using a gulp script which automatically injects all js libraries in bower_components into the index.html so it was correctly loaded.

Forge is broken up into many submodules so that each one can be individually loaded by an AMD (Asynchronous Module Definition) loader, like RequireJS. That way, you only have to deliver the parts of forge that your application needs. Since each submodule isn't its own bower package, bower doesn't know anything about the dependency structure of forge, so it can't declare that information in bower.json. The only JavaScript file declared in the bower.json file for forge is the main forge.js script. This means your tool can't possibly know how to pull in all of the submodules. And, as mentioned, some people wouldn't want them all pulled in -- they only want to serve a subset. With RequireJS, you can just declare the modules you want to pull in and that's all that will end up getting served to your application. RequireJS uses dependency injection like AngularJS does, but, again, at a different layer.

For example, to use RequireJS, you'd set up a RequireJS config that tells RequireJS which URL to get forge from, then you'd add requirejs.js to a script tag, then you'd serve your own modules with their own AMD boilerplate like:

define(['forge', function(forge) {
  // do something with forge, where forge now has *everything* attached to it
}]);

// or ... just use 'x509' features
define(['forge/x509', function(x509) {
  // do something with x509 only, it's the only module loaded
}]);

You could read more here: How To Get Started with RequireJS.

So, the point is that your browser needs to know how to get the forge submodules it needs and that information can't be in bower.json -- unless forge is broken up into a bunch of individual small bower packages. We are planning on upgrading the forge build and packaging system in the future and that's one approach we could take to help in situations like these -- but that's TBD (note: forge was started years before bower and other more modern tools existed). For now, if you just read what's in bower.json and send that to the browser, the browser is going to get the main forge object with no real functionality hanging off of it. That's because no submodules, which provide the functionality, are loaded.

So, to get around this, you'll either have to bundle up forge like you've been doing, or use something like RequireJS or browserify, etc. in your build process. Unfortunately, JavaScript file/module loading is generally a mess throughout the industry as the concept wasn't built into JavaScript from the beginning (like it was for other languages/platforms).

We've got making a lot of this easier and more compatible with the wide-variety of build tools/module loaders out there on our roadmap. See: number 6 in #203.

@dlongley
Copy link
Member

@henry74, I should add -- there may very well be a gulp plugin you can install that will read through the AMD dependencies in the main forge.js file and build what you need and/or combine with gulp-inject or whatever else you're using. Maybe something like gulp-requirejs or similar (I haven't looked too hard).

@henry74
Copy link
Author

henry74 commented Mar 10, 2015

Thanks again for the in-depth explanation. Makes a lot more sense now. I'll look into RequireJS. For now I've had success explicitly including the forge.min.js file and keeping out of the gulp minification pipe :-) Looking forward to the roadmap and thanks for driving this project forward. I'm using it to add encryption client-side for Firebase which seems to work quite well.

I am curious how folks are handling the passkey storage/retrieval and not actually storing it in the same data store as the encrypted data :-) but I guess that could be a separate post.

@samartioli
Copy link

I needed to be able to install the minified version via bower, so I created a repo if it is helpful to anyone else.

https://github.com/samartioli/forge-min

@dlongley
Copy link
Member

Addressed by #456.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants