full-stack angular with no dependencies
Warning! ng is pre-alpha, but is being built for production with sponsorship by Pook-n-Cheek. If you have suggestions or are interested in contributing, email adam at email@example.com
Browse the code of a working application, ocrx
#Update - because of the planned release of angular 2.0, ng is being put on hold and will be refactored to work with angular 2.0 when released
Enter in the url or file path of module dependencies. ng will load them first
var modules =ng:'//ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.js'ngRoute:'node_modules/ng.cdn/1.2.0-route.js'require'ng'modules//ng is a listener that accepts a request & reponserequire'http'createServernglisten1337//Load your application here
ngmodule'example' 'ngRoute'factory'example'return ngisString'Hi! I am identical on both the server and the client'
ng enables full-stack development by allowing you to access node.js within your services.
//Require is a node specific functionfactory'os'return require'os'
utilizing node's require, it is easy to build a modular application using external npm modules
factory'third-party' require'ng.thirdparty'factorydirective'third-party' require'ng.thirdparty'directive
here we leverage node's readFileSync to load our templates
config$routeProviderwhen'/'template: require'fs'readFileSync'view/splash.html'controller: 'splashCtrl'when'/example'template:require'fs'readFileSync'view/example.html'controller: 'exampleCtrl'$locationProviderhtml5Modetrue;
Config, run, provider, factory, & service are all put on both the client and server. Some services, however, such as controllers, directives, and animations are only available on the client.
//Controller's only make sense to be on the clientcontroller'example'$scopeos = os
Each method includes a client and server property if you wish to register the function in only one place.
//I will only be available on the serverfactoryserver'dependent'var q = $qdefer//I will only be available on the clientfactoryclient'dependent'var q = $qdefer//I am equivalent to the two factories abovefactory'dependent'var q = $qdefer
Using the client & server properties in tandem, one can create an injectable service that acts differently on the client and on the server, as in this authentication example below.
factoryclient'login'returnvar promise = $httpget'/rpc/login?verify["'+id+'","'+password+'"]'return promisethen//code to store the access token in a sessionreturn access_token ? true : falsefactoryserver'login'var hmac = require'crypto'createHmacreturnvar access_token = hmac'sha256' idupdatepassworddigest'hex'//Save access token to the databasereturn access_token
Almost everything works exactly like angular including dependency injection & decorators. Things that don't work on the server are - understandably - $location, $document, & $window
//This works on both the client and serverfactory'dependent'var q = $qdefer//This works on the client but not the serverfactory'dependent'$windowalert"Can I alert on the server?"
There are two non-angular (ng-only) methods:
ng - like many node frameworks - uses middleware to process and respond to incoming requests. ng uses angular's interceptor api to build a middleware stack. Register middleware using the module's interceptor method. You will need at least one interceptor to serve your application
interceptorreturn//ng.toString() will concatenate all modules, replacing//the need to specify each one manually. To do it the//manual way replace ng with the three lines below. Note//that modules are automatically enclosed in script tags//ng.module('ng'),//ng.module('ngRoute'),//ng.module('example'),responsedata = responsedata ||"<html ng-app='example'>""<head>"ng"</head>""<body>""<div class='ng-view'></div>""</body>""</html>"join'\n'return response
In the previous os factory and routing config, we showed you a little magic. How do we make these functions that contain node-specific code run on a browser where node is not available?
Factories: Actually the os factory - unlike the other factory examples - will run only on the server. However, ng automatically creates a factory of the same name and identical api on the client. This "twin" client factory simply calls the server factory via an http request and the result is returned to the client. Since this all happens automatically, the client functionality appears identical to the server's.
//This is what the os factory looks like on the clientfactory'os'//ng's $rpc sends an $http request to the server//and will return require('os') asyncronouslyreturn $rpc'os' '0' 'trigger'
Templates: Something similar happens in the routing config. The routing config is executed on the server as soon as ng is started. Once loaded on the server, the templates are written to the client module before it is served by the interceptor. The template will simply appear in the client's config.
Sound complicated? It's not! ng uses a very elegant api exposed as the module's transform method. ng has built in transforms for making client-side factories - like the os example - and filling in templates - like the routing config - but allows you to create your own transforms as well.
transform//Uncomment lines below to see how a custom transform works//console.log('I am transforming', type, name)//console.log('Function to transform & return', fn.toString())//console.log('Module API available as this', this)return fn //I didn't do anything: kept function as-is
Transforms are incredibly powerful. This simple transform automatically makes your code minification-safe by surrounding every client function with an angular inline injection array. Now that's power!
transformclient//No injection array needed if nothing to injectif ! fnlengthreturn fn//Make an array of args with annotate, then manually append function's stringreturn JSONstringifynginjectorannotatefnreplace']' ','+fn+']'