Editing values during build via hooks - ionic2

Im trying to edit a version variable when I build my applications, but I can't get any scripts to run using the cordova hooks at all.
I want to get the version from the package.json and the last 5 digits of the git commit so i can have something like 1.0.0.89gkt as my versions.
In the past for ionic 1 and using grunt or gulp I was able to add the scripts into the build process easily.
I've tried both the old way using the hooks/hook_name/script format and using the hook tag in the config.xml and neither work for me.
Overwriting the ionic scripts via the package.json allows me to change the scripts that are automatically run, but I want to avoid that if I can. Though I can easily add my text replace to one of the copy scripts or something (ill need to work out which one is best)
If someone knows a better way or a reason as to why the hooks wont fire, please let me know.

This is the solution that I ended up using.
scripts/before_prepare_increment_build_number.js
var fs = require('fs');
var git = require('git-rev-sync')
console.log('Incrementing Build Number');
var file = fs.readFileSync('www/build/main.js', 'utf8');
var str = git.short();
console.log('short', str)
var result = file.replace(/{{GITVERSIONSTRING}}/g, str);
fs.writeFileSync('www/build/main.js', result);
console.log('Incrementing Build Number Completed');
config.xml
<hook src="scripts/before_prepare_increment_build_number.js" type="before_prepare"/>
I needed to ensure that everything was happening synchronously otherwise the built in scripts would start copying before the strings had been replaced.
Currently its targeting the whole main.js that is generated by the default ionic-app-scripts so all comparisons and replacements can be added as required.
This solution uses the built in cordova hook before_prepare
Another solution that can be used to make it a bit more efficient is targeting the individual files as required and adding the script before the build/serve scripts in the package.json and have npm control and manage it.
Inside your package.json you could add a script to a prepare hook.
"scripts": {
"prepare": "node increment_build_number.js",
}

Related

What is the best way to "compile" HTML templates in production?

i'm developing my first Angular2 app and i'm using this folders structure:
components
component1
home.component.ts
home.component.html
home.component.scss
I'm using Gulp to run tasks for building the app. The final folders structure will be this one:
scripts
somefile1.js
somefile2.js
...
styles
mine.css
vendor.css
index.html
favicon.ico
Can you tell me what is the best way to incorporate HTML templates within Javascript files?
Besides i would be able to easily debug code, so i would see the original folders structure in browser's inspection tools.
I'm currently using gulp-sourcemaps plugin and sourceMap option set to true for Typescript compiler to do the same for Styles and Scripts.
What node plugins could i use to reach this purpose for HTML templates?
I've used gulp-angular-embed-templates on multiple projects with great success.
Here is an example task:
gulp.task('embed-templates', () => {
gulp.src('app/**/**.js')
.pipe(embedTemplates({sourceType:'js', minimize: {quotes: true, empty: true}}))
.pipe(gulp.dest('app/'));
});

How to compile project's CSS files into one file

By default ember-cli seems to be set up not to compile css files into one (as it does with the JS files).
What is the best way to configure ember-cli to merge all files in app/styles (and subdirectories) into one app.css file (and then fingerprint etc)? Is this possible via the Brocfile or do I need to override EmberApp.styles()?
Update: As far as I can see there are the following (not very elegant) options:
1) Using SASS and #import the CSS files into app.scss individually. The downside of this is that I need to use an extra plugin (SASS) and that SASS does not seem to allow for globbing patterns in #import (e.g. #import('**/*.scss')), which makes this solution cumbersome for big projects.
2) Overriding EmberApp.styles() such that it does not copy the CSS files (this is currently being done by a wrapper around broccoli-static-compiler) and configuring Broccoli such that it concatenates the css files into app.css. This solution seems a bit hacky though and there is a risk of incompatibility with newer versions of ember-cli.
3) Workaround: Use broccoli-funnel and broccoli-concat to do the concatenation yourself.
In Brocfile.js:
var appTree = app.toTree()
var concatenated = concat(appTree, {
inputFiles: [
'**/*.css'
],
outputFile: '/assets/app.css',
});
module.exports = mergeTrees([appTree, concatenated], { overwrite: true });
This will create a new app.css with all our concatenated CSS in /assets/app.css.However, this file not fingerprinted. Our assets directory now looks something like this:
/assets/app.css
/assets/app-<fingerprint>.css
So a - admittedly hacky - second step is to 1) get the filename of the fingerprinted app-<fingerprint>.css, 2) delete app-<fingerprint>.css and 3) rename app.css to app-<fingerprint>.css. This last step can be automated using Grunt or gulp.
Personally, I think SCSS would be the way to go. It is the simplest solution and there are other advantages to using SCSS besides importing things into one file (variables for repeated patterns, for example).
In addition, manually adding files allows the developer to configure exactly where each piece of code is included. I don't see that as a con, but I can understand the other point of view and I've definitely spent 5m trying to figure out why my styles weren't being applied until I realized it was because I didn't include a new style file.
Edit: There are some node-sass globbing solutions available that could probably be added if that is a big show stopper.

sprockets - precompiling a standalone asset

I am trying to make sprokets compile a single standalone js asset, so it will uglify and minify it and be part of the entire rails projects.
I need that this js to have a non-digest name, so it's will not change (i.e. embedded in other websites, etc)
I can't seem to force rails (4) /sprockets to do my bidding.
What I tried:
Adding the asset (script.js) in a misc folder unders assets/javascripts and not load it in the sprockets javascript manifest. While this keeps it in the project, it doesn't get uglified and minified, and doesn't get automatically loaded via asset-sync.
Tried adding another manifest called scripts-manifest.js to //= require script.js asset, to add its path in the precompile path in application.rb, but the problem is that rails 4 adds digest to all assets no matter what (doesn't work like that in rails 3)
Tried using https://github.com/alexspeller/non-stupid-digest-assets to add a non digest version of the asset. I may have done it incorrectly, as it doesn't work or do anything..
I add the initializer NonStupidDigestAssets.whitelist = ["script.js"] and tried putting it in app/assets/javascripts/misc and in public/ but it still won't work/
I have read that this gem should help in most cases, and I am sure I am doing something wrong with either path definition or no including it somewhere
One way to do this is to add an initializer that generates the compiled versions directly.
Add your js file to a subfolder in /app/assets/javascripts. Don't include this in application.js so it isn't added to the compiled assets.
Create an initializer in /config/initializers that uses uglify directly
output_file = "#{Rails.root}/public/public_script.js"
input_file = "#{Rails.root}/app/assets/javascripts/non_digest/public_script.js"
uglified = Uglifier.compile(File.read(input_file))
File.open(output_file, 'w') {|f| f.write(uglified) }
Include the public js file (in this example: /public/public_script.js) in your application layout
This way you have direct access to make custom changes to how uglify handles your js and the location of the file never changes for your external services accessing them.
I did all this locally and tested that it worked using the beta version of Rails 4.2
Just wanted to add my own solution based off Ken's answer.
I created non_digest.rb in config/initializers:
Dir["#{Rails.root}/app/assets/javascripts/non_digest/*"].each do |asset|
asset_name = File.basename(asset)
asset_output = "#{Rails.root}/public/external/#{asset_name}"
asset_uglified = Uglifier.compile(File.read(asset))
File.open(asset_output, 'w') {|a| a.write(asset_uglified) }
end
Don't forget to stub the file in javascripts/application.js. as we probably don't want it compiled with the rest of our JS and we can continue to use //= require_tree .:
//= stub non_digest/external_bookmarklet
the way you would do this with rails 4 is the following:
add it to the precompile list config.assets.precompile += %w(your_file_name.js)
make sure it's not referenced in application.js (directly or via require_tree)
symlink the digested file on deployment
read the manifest.yml to get the actual filename
ln -s digested-filename.js actual-filename.js
since rails 4, generation of non-digested assets has been removed (for good reasons) and this is a simple and straight forward way to implement the desired behavior.

Ember-cli-compass-compiler: how to override the default options?

I'm using ember-cli-compass-compiler right now, it works well if only compass used, but I also want to use some plugins, such as Susy. I don't know how to require plugins with compass.
I've try to read the source code, founded it has a option object and includes require: sass-CSS-importer by default, but how to override/extend this option? What code should I put in Broccoli.js file?
Thanks for helping.
Finally I figure this out by myself, in case of someone needs help, I put my solution at here:
Open Brocfile.js and find this line:
var app = new EmberApp();
then, change it to:
var app = new EmberApp({
compassOptions: {
require: ['sass-css-importer', 'susy']
}
});
this assumes you want to use Susy as well as me, and of course you can override other options like above.
BTW, if you use sass syntax checker, e.g. syntastic in vim, #import "susy"; will rise an error about load path problem. Before using Ember-CLI, I use a config.rb as compass's configurations, so sass knows about require "susy" is a dependency should be concerned about. But now we no longer have config.rb file anymore, fortunately you can let sass knows required gem(s) by passing -r GEM_NAME to passing the syntax checker. For case of syntastic, you can simply put this line in your .vimrc file:
let g:syntastic_scss_sass_args = "-r sass-css-importer -r susy"

Subtract code from app.js

To tackle some touch-related problems I have written a script in app.js to reopen and enhance the EventDispatcher. The script is pretty long and contaminates the normally so clean app.js.
So I'd like to have my script in a seperate file and than somehow be imported in app.js. What in your opinion is the best (cleanest) way to do this?
FYI I'm using Ember CLI
I would place the script in file in in public/assets/js and load the script using Modernizr.load (Modernizr's implementation of yes nope) like this inside of script tags just before the closing body tag of your index.html file. In this situation, you could use Modernizr.touch to detect for touch event support on the user's device and, if present, load the touch polyfill/script.
Alternatively, place the file in the same place and load the script inside an if statement using $.getScript(url) in an initializer or the application view.
In both situations the script will not be imported into app.js but will still be loaded and ran.