Yeoman & RequireJS build with dynamically generated HTML? - concatenation

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.

Related

Do I need to generate static files when I using webpack?

I am using webpack in my Project, here is the tools:
HTML as - jade-html-loader
CSS as - sass-loader
Project written with AngularJS - all with components & templateUrl (ngTemplate-loader in webpack)
So I got 1 JS file in the end of the process.
All this stuff pretty cool, but I think that it will be good to create static HTML files for clients...
It's going to Improve performance(caching / no need to draw DOM elements throw JS) and it's better for browser - to download few small files, not one big JS...
I am wrong? I can't find good tools that generates static assets(html, css)/cache files.
In the end of the line - I need to find an easy way to require Jade files as templates(templateUrl) into Angular Component, but files needs to be static - so I can see them in "Sources" of the browser...
It is hard to explain - so I hope you can understand me =(.
I been there and what i learned is angular cache template are faster then static. You can also copy static html files to dist map using npm cpy tool but i will highly recommend you to use angular cache template. There is this tool you can use for converting you jade to html.
You don't need to build only one single file you could build one for the vendors and one for your app this will keep your app more clean and you can also make one for the only templates which load in angular from cache on demand. I hope i could explain. webpack come with lot's awesome plugins witch can make life easier! good luck
After week I agree that cache templates works fantastic! =).
I used plugin "webpack.optimize.CommonsChunkPlugin" to generate 2 files for my app:
Vendor - all node_modules/bower_components/libs (js+css).
App - all source of app - controllers/models/business logic/views (js,css(sass),html(jade+ngTemplate for angular)).
My entry looks like:
entry: {
app: './src/app.js',
vendor: [
"angular",
"angular-route",
... and other libs...
],
},
And there I found really cool thing: html-webpack-plugin - this plugin creates index.html file and automatically attaches all your generated JS files.
Add Used "hash" string to my files.
My dist looks like this:
/dist
/index.html
/app.xxxxxxxxx.js
/vendor.xxxxxxxxxx.js
Little magic with webpack.optimize.UglifyJsPlugin to minify all files.
And now I got lightweight, small app that waiting for deploy! =)

How does browserify work with angular based app?

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.

ExtJs app without sencha-cmd: ExtJs Loader trying to load files already loaded

I am trying to run an ExtJs application without using SenchaCmd. These are the scripts I load in the index HTML file:
<script type="text/javascript" language="javascript" src="dev/ext-all-debug.js"></script>
<script type="text/javascript" language="javascript" src="dev/all.js"></script>
The all.js file contains all the views, controllers, stores and models concatenated into one file using a gulp task (including app.js and Application.js files). The problem is that after these 2 files are loaded, The Ext Loader is still trying to load the required Controllers/Views one by one.
I tried adding the following code into the Application.js file but nothing changed:
constructor: function() {
this.callParent(arguments);
Ext.Loader.setConfig({enabled:false});
},
Any ideas? Why is the Ext.loader trying to load all the requires if they are included in the all.js file? Thanks.
What version of Ext JS? If you're using 5.0.1 the "ext-all-debug.js" file in the root of the ext directory will not work - you want the one in the "build" directory...
I think I know why the Ext.Loader didn't work as expected...
The concatenated files need to be in the right order because on each Ext.define the loader is searching for the dependencies specified in the requires section and if the dependencies are not loaded it will try to load them.
It works recursively until the dependency tree is loaded.
There is a Grunt plugin doing this: https://www.npmjs.com/package/grunt-sencha-dependencies
However I am still not satisfied of the development workflow with ExtJs because when using "app watch", in dev mode, you could be loading hundreds of JS files on a page refresh if your app is big enough and this impacts the performance quite a bit.

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

yeoman including google map api

I am using yeoman to build an angular js application. For this I am using google map api like this<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=weather" type="text/javascript"></script>
But after build the project using "grunt build" the file is not included in the html in the dist folder.
Can anyone suggest me how to include this file?
Thanks in advance.
Nabaraj
You have to put your Google Map <script> tag outside of the commentaries which looks like
<!-- build:js(.) scripts/vendor.js -->
The fact is that all the scripts contained inside are concatenated and minified after a build, breaking the Google Maps API since it's a CDN.

Resources