How does browserify work with angular based app? - angularjs

I was mess around this for a couple of days. I was trying to get browserfiy to work well with angular based app. I have tried following options but still cannot decide on a better way to do it, it will be appreciated if anyone can give any suggestion on this.
Option 1
Bundle all angular related libs, like angular, angular-animate, angular-ui-router, etc into vendor.js by using bundle.require
Bundle all app reated source files into app.js by using bundle.external
That works fine in dev environment, all modules in vendor.js could be required from app.js
But it crashed in prod environment. The minified angular files are not all CMD. Although I can browserify-shim angular.min.js and bundle.require angular-ui-router.min.js, it's kind of cubersome to do this file by file.
Option 2
Leave all angular libs into <script> and only output bundle for app files. That means in app.js, I have to refer to angular as a global var which is not good.
So what's the best practise to do this?

Even if you do require() angularjs, it still exposes the angular namespace in the context of its environment (Window object for browsers). What I usually do is simply put all angularjs modules dependencies (e.g. ui.router, ngResource and etc) below the bundled(browserified) javascript where your angularjs application resides. In my case, I use gulp-useref to concatenate all the script provided by the gulp-inject tags(this includes scripts bundled by browserify).
As you may have noticed below, the bower components(bower:js tag) are added below the bundle(inject:js tag). Since requiring the angular module will attach the angular object in the window object, then any components external to browserify can access window.angular.
The answer I provided is somehow similar to option 2 but without the disadvantage of referring angular as a global variable within your browserified code.
e.g.
<!-- build:js({./.tmp,./}) js/index.js -->
<!-- inject:js -->
<!-- endinject -->
<!-- bower:js -->
<!-- endinject -->
<!-- endbuild -->
UPDATE:
I've create a github repo that resembles the answer provided above. Try to clone it, and see what you can do with it.

Related

Polymer production app with angular full stack framework-generated by yeoman

I am using angular full stack generator by yeoman with polymer as manually injected. I am not using polymer generator and not to sure how to use vulcanise task to include polymer element in production version of the app.
This is how I included polymer in my index.html
<!-- 1. Load platform support before any code that touches the DOM. -->
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<!-- 2. Load the component using an HTML Import, in this case element list is imported which consists of all required elementLis -->
<link rel="import" href="elements/elementList.html">
It works perfectly from local host, but when I run grunt serve: dist
no polymer element displays on the page, and error logs
angular is trying to load too many times.
I have found some answers from stack overflow that I might have to include vulcanise task in grunt to be able to include polymer html.
I want to be able to include any polymer element and relevant css files from a certain directory for the dist version of the application.
I am new to polymer and still learning grunt.. Any help will be much appreciated.
Here is my polymer element directory..
https://github.com/knofler/angular-fullstack-base/tree/master/client/elements

How to add google api to grunt build

I'm fairly new to Grunt, Bower and Yoeman so please forgive me if I'm not asking the right question. I've added the angular-google-maps module to my build and set it up manually and everything looks fine. However whenever I restart my project in Webstorm or build using grunt, my google maps api reference keeps getting lost. I've added the google and lodash dependencies to the package.json file and those references are being added just fine. However, how do I add a dependency to an api or should I just be putting the reference before the bower/components block? I've been searching the web for the last day or so and nothing seems to address this that I've found.
Here's an example of the api I need to add -
<script src='//maps.googleapis.com/maps/api/js?sensor=false'></script>
Thanks for the help in advance!
Please make sure to put your reference outside of the <!-- bower:js --><!-- endbower --> block in your HTML. This section is overwritten by grunt-wiredep when you build your application

Can not open datepicker in angularjs using bootstrap UI

Hello I am using UI Bootstrap for displaying datepicker in my app.
this is my reference order:
<!--ANGULAR CORE-->
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.18/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.18/angular-route.min.js"></script>
<!--APPLICATION INIT-->
<script src="app/js/app.js"></script>
<!--JQUERY-->
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<!--BOOTSRAP UI-->
<script src="app/js/libs/ui-bootstrap-tpls-0.11.0.min.js"></script>
I use the tpls version because it supposes to include the templates.
I inject the dependency like that:
angular.module('globapp', ['ngRoute', 'ui.bootstrap'])
when I try to popup the datepicker it doesn't show. In the chrome developer I can see that the code searches for template folder, and I recieve 404 error (datepicker.html, popup.html).
I searched about that in the internet, and everyone tells the same thing: if I use the tpls version, it should provide me the default templates.
thanks
Your app.js has your app init -so that's where your creating your angular module and are hoping to inject bootstrap-ui as a dependency but that script hasn't been loaded yet as it's last in the list.
This would be the first thing to check. Load your scripts in order of least dependent first so jquery first then your core angular, then your plugin libraries and then your app scripts.

Too many import statement at home page when initializing the framework

In my angular project, I am planning to have a separate .js file for each page and a separate .js file for each service.
However, as I begin to code, I realized that I have a lot of import statement in my index.html. This would cause user having to load all the .js file even if they might not need it.
An example of the .js for my index.html
<!-- JS -->
<script src="js/vendor/angular.js"></script>
<script src="js/app/app.js" ></script>
<!-- controllers -->
<script src="js/app/controllers/roomController.js"></script>
<script src="js/app/controllers/dashBoardController.js"></script>
<!-- services -->
<script src="js/app/services/dashBoardService.js"></script>
<script src="js/app/services/roomService.js"></script>
<script src="js/app/services/chatService.js"></script>
<script src="js/app/services/videoService.js"></script>
Is there any solution to this?
It's really a best practice to have each controller, each service, each directive… in a separate file, so you're doing it in the right way.
However, as you notice, it's better for the user (and for the server!) to download a minimal number of files. Your index.html is fine for development, but in production, you must compress all your files in in one, typically with a tool like UglifyJS or YUI Compressor.
This is a known issue, especially with large projects. A viable solution is using RequireJs . You can find plenty of resources on the web about that, for instance you can try this.
I had exactly the same problem so decided to use RequireJS to allow on-demand loading of my angularJS scripts. I created a wrapper called angularAMD that hopefully can help you integrate RequireJS and AngularJS:
http://marcoslin.github.io/angularAMD/

Yeoman & RequireJS build with dynamically generated HTML?

I'm trying to integrate a RequireJS setup on my front-end generated / administered by Yeoman, with the Laravel PHP framework on the backend. Everything is golden except the concatenation part of the build step in Yeoman / r.js for my javascript files.
My problem in a nut-shell: the r.js build step in Yeoman looks for an index.html file with the HTML comments like <!-- build:js scripts/amd-app.js --> around the RequireJS script tag, which kicks off the optimisation and concatenation routine in the RequireJS optimiser. However: I'm using the Laravel framework, so there is no index.html, since it is generated dynamically.
I've managed to make the process work by doing an ugly hack and adding in an index.html in the app directory file, that just has:
<!-- build:js scripts/amd-app.js -->
<script data-main="scripts/main" src="scripts/vendor/require.js"></script>
<!-- endbuild -->
Which lets Yeoman / r.js find an index.html file with the appropriate tags and filepath, do all its awesome concatenation of my AMD modules and output it into a dist directory.
Only this is a horrible hack, and I'm sure there is a much simpler of achieving the same end. I assume it has to do with editing the Gruntfile containing the Yeoman build settings to reflect the info above. I'm just not sure how :(
Anyone with some experience integrating Yeoman / RequireJS setup, with a backend framework might help? (I imagine this question applies equally to rails as well).
If you check (at least on Mac/linux):
/usr/local/lib/node_modules/yeoman/tasks/rjs.js
You'll see a line:
var appIndexPath = path.resolve('mainFile' in options ? '../app/' + options.mainFile : '../app/index.html');
My guess is you can speficy another html file to kickoff the process by
rjs: {
// no minification, is done by the min task
optimize: 'none',
baseUrl: './scripts',
wrap: true,
name: 'main'
mainFile: 'kickoff.html'
},
Actually,
<!-- build:js scripts/amd-app.js -->
This is used by the usemin task, not rjs.
To skip the need of a html file at all, I would have to dig deeper.

Resources