Separate angularjs library from bundled browserify - angularjs

I've got a gulp task that browersify my files. currently it works by bundling everything including the angular.js file which is quite large. I want to pull angular.js out and load that in my index.html just before the bundled javascript file.
I've done this by adding the .external('angular') to the browserify call but the bundled resulting file does not get any smaller, and when I run the app in a browser, it acts like it is still trying to load the node angular package (error: Uncaught Error: Cannot find module 'angular')
Below is my gulp task that is where the problem is I believe.
function identity (input) {
return input;
}
function bundler (watch, mocks) {
var b = (watch ? watchify : identity)(
browserify(watch && watchify.args)
.external('angular')
);
b.add(format('./%s', app)).add('babel/polyfill');
if (mocks) b.add(format('./%s/mock', app));
return b;
}
function bundle (bundler) {
return bundler
.bundle()
.pipe(source('main.js'))
.pipe(gulp.dest('dist/app'));
}
gulp.task('bundle', function () {
var bundled = bundle(bundler())
if (!production) return bundled;
return bundled
.pipe(buffer())
.pipe(replace(/('|")use strict\1/g, ''))
.pipe(plugins.uglify())
.pipe(plugins.rename({
suffix: '.min'
}))
.pipe(gulp.dest('dist/app'));
});

Related

How to call cordova plugin in ionic v1

I was installed cordova-plugin-media in ionic v1 . But media is not define by the app when I running it in the browser .
ionic.bundle.js:26794 ReferenceError: Media is not defined
at ChildScope.$scope.playPodcast (controllers.js:1405)
at fn (eval at compile (ionic.bundle.js:27638), <anonymous>:4:232)
at ionic.bundle.js:65427
at ChildScope.$eval (ionic.bundle.js:30395)
at ChildScope.$apply (ionic.bundle.js:30495)
at HTMLElement.<anonymous> (ionic.bundle.js:65426)
at defaultHandlerWrapper (ionic.bundle.js:16787)
at HTMLElement.eventHandler (ionic.bundle.js:16775)
at triggerMouseEvent (ionic.bundle.js:2953)
at tapClick (ionic.bundle.js:2942)
and this is my code
$scope.playPodcast = function($audioId) {
new Media("http://www.viaviweb.in/envato/cc/online_mp3_app_demo/uploads/40655_Overboard.mp3").play();
}
Just a quick search to that plugin's github page shows the way to use that method.
Specifically if you want to play a media file, this is the correct way to use it.
function playAudio(url) {
// Play the audio file at url
var my_media = new Media(url,
// success callback
function () { console.log("playAudio():Audio Success"); },
// error callback
function (err) { console.log("playAudio():Audio Error: " + err); }
);
// Play audio
my_media.play();
// Pause after 10 seconds
setTimeout(function () {
my_media.pause();
}, 10000);
}
Ok, depending on how you have the script file injected, you need to call it one of two ways:
If the media plugin is being loaded as a script file that is in your index.html by itself and it attaches itself to the global namespace, then add the following to your app.js:
angular.module('Media', [])
.factory('Media', function () {
return window.Media;
});
Later, in your app.js module definition, add the following:
angular.module('myApp',
[
'ionic',
'Media'
])
.run(
[
'ionicReady',
'Media',
function (
ionicReady,
Media,
) {
//Media initialization code here
}
This allows angular to use its Dependency Injection to ensure "Media" gets initialized in your main module. You'll have to import it to your other modules if you want to use it somewhere else in your application.
If you're using NgCordova, which provides angular wrappers for common Cordova plugins, then you'd import it the same way you'd import any other AngularJS library. There's sample code for the media plugin here.

inject node modules files into index.html

I am using bower & npm as package manager to handle dependencies. now the bower is showing
npm WARN deprecated bower#1.8.2: ...psst!
Your project can stop working at any moment because its dependencies can change. Prevent this by migrating to Yarn:
https://bower.io/blog/2017/how-to-migrate-away-from-bower/
So i have integrated yarn using bower-away. Now all the bower dependencies are moved into my package.json as like below
"#bower_components/angular": "angular/bower-angular#~1.6.4",
"#bower_components/jquery": "jquery/jquery-dist#>= 1.9.1"
I used wiredep to inject all the dependency libraries into index.html. It will automatically handle bower dependencies.
Now i have removed bower completely so this won't work.
Is there any other method to move dependencies into index.html. currently I am using gulp inject method to inject all the files like as below .pipe(inject(gulp.src(["./src/*.js", "./src/*.css"], {read: false})) but it's not handling for all packages. because path is completely different.
For Ex: jquery and angular folder like as below
can anyone suggest is there any other method to achieve this.
you still able to fix it using gulp inject:
gulp.task('injectfiles', function () {
var appJS= ["./src/*.js"];// pattern to match your files
var libJS= [
'(path where jquery exist)/jquery.js',
'(path where angular exist)/angular.js'
];
var jsOrder= [
'**/jquery.js',
'**/angular.js',
'(rest lib js)'
'**/app.module.js',
'**/*.module.js',
'**/*.constants.js',
'**/*.value.js',
'**/*.config.js',
'**/*.route.js',
'**/*.filter.js',
'**/*.service.js',
'**/*.controller.js',
'**/*.directive.js',
'**/*.js'
];
var src = [].concat(libJS,appJS)
return gulp
.src('index path')
.pipe(inject(src, '', jsOrder))
.pipe(gulp.dest('dest path'))
})
function inject(src, label, order) {
// var options = { read: false };
var options = {}
if (label) {
options.name = 'inject:' + label
}
return $.inject(orderSrc(src, order), options)
}
function orderSrc(src, order) {
// order = order || ['**/*'];
return gulp
.src(src)
.pipe($.if(order, $.order(order)))
}

gulp-ng-annotate - how to use it?

I want to minify my big angular project.
Using angular 1.5.0.
I'm trying to use the module gulp-ng-annotate to do so.
var gulp = require('gulp');
var ngAnnotate = require('gulp-ng-annotate');
gulp.task('default', function () {
return gulp.src('../www-myalcoholist-com-angular/model/app.js')
.pipe(ngAnnotate())
.pipe(gulp.dest('dist'));
});
when I execute this nodejs script, it fails silently. or... welll.. it doesn't do anything.
i gave it only the main app.js file as a parameter. can I some how give it the all project ?
when I run ng-annotate from terminal, it added annotations properly to my project.. well.. i hope :)
so why this script fails?
I'm new to gulp so any information would be greatly appreciated.
gulp-ng-annotate does not try to find other files in your application. You'll need to either concat your application into a single app.js file before piping to gulp-ng-annotate or src all files separately and pass them to`gulp-ng-annotate.
E.g. the concat method:
var gulp = require('gulp');
var ngAnnotate = require('gulp-ng-annotate');
var concat = require('gulp-concat');
gulp.task('default', function () {
return gulp.src('../www-myalcoholist-com-angular/model/**/*.js')
.pipe(concat('app.js'))
.pipe(ngAnnotate())
.pipe(gulp.dest('dist'));
});
A sample configuration -
gulp.task('app', function() {
return gulp.src([
// './bower_components/angular/angular.min.js',
// './bower_components/angular-sanitize/angular-sanitize.min.js',
//'./bower_components/angular-ui-select/dist/select.min.js',
// './bower_components/angular-ui-router/release/angular-ui-router.min.js',
'./components/**/*.js'])
.pipe(plumber())
.pipe(count('## js-files selected'))
.pipe(concat('./app/all.min.js', {newLine: ';'}))
.pipe(ngAnnotate({
// true helps add where #ngInject is not used. It infers.
// Doesn't work with resolve, so we must be explicit there
add: true
}))
.pipe(gulp.dest('./dist'));
});
This will produce a concatenated build js file. I have kept the vendor js files separate but you can have it any way you like.
P.S - Any other task e.g Linting is done separately in conjunction with watch task.

gulp-concat does not concat one of my files on heroku

I'm using gulp to generate a config.js file for angular, then use another gulp task to concat all .js files together, the gulp tasks look like this:
gulp.task('config', function() {
var environment = process.env.NODE_ENV || 'development';
gulp.src('public/config/' + environment + '.json')
.pipe(ngConstant({
name: 'app.config'
}))
.pipe(concat('public/js/config.js'))
.pipe(gulp.dest('.'));
});
gulp.task('js', ['config'], function() {
gulp.src('public/js/*.js')
.pipe(concat('app.js'))
.pipe(gulp.dest('public/dist'));
});
gulp.task('default', ['config', 'js']);
If I run gulp locally, everything works file.
But when I push to heroku, using this post install script:
"postinstall": "bower install && gulp"
I can see gulp run successfully, after adding some debug, I can see the config.js file is even created correctly, but the generated app.js does not include config.js. Can anyone suggest what might be wrong here?
UPDATE: I found it works if I do gulp config && gulp js but not gulp, is this because gulp is async and config.js wasn't created when js job started to run? but i thought I have already specified the task dependencies?
The problem is: I'm not returning a stream from tasks, for example the config task should be like this:
gulp.task('config', function() {
var environment = process.env.NODE_ENV || 'development';
var stream = gulp.src('public/config/' + environment + '.json')
.pipe(ngConstant({
name: 'app.config'
}))
.pipe(concat('public/js/config.js'))
.pipe(gulp.dest('.'));
return stream; // THIS IS IMPORTANT!
});

Is it possible to build a self-contained Angular plugin to be embedded in other angular sites?

I really like Angular.
Having said that, I want to create a plugin in Angular that can be hosted in other websites - no matter what framework they're using. These frameworks can be Angular and it might be something else.
Surely, the latter it easier. I just add my Angular code and violla. It just works. The former is what I'm having troubles with - websites that do use Angular.
A simple setup created locally failed due to:
WARNING: Tried to load angular more than once.
Any suggestions on how I can overcome this issue ?
It sounds almost like you want to create an angular module that you may register on NPM.
In terms of the error you referenced, you may want to tweak your "loader" script. I have created a few public npm modules that use this format also with webpack to create the scripts. This is what my "loader" script looks like. It allows for script tag, commonJS, and AMD module loading.
import mooAccordionDirective from './mooAccordion.js';
import mooRepeatTranscludeModule from 'moo-utility-repeat-transclude';
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS
if (typeof angular === 'undefined') {
var angular = require('angular');
factory(angular);
module.exports = 'mooAngularAccordion';
} else {
factory(angular);
module.exports = 'mooAngularAccordion';
}
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['angular'], factory);
} else {
// Global Variables
factory(root.angular);
}
}(this, function (angular) {
'use strict';
// create your angular module and do stuff
var moduleName = 'mooAngular.accordion';
var mod = angular.module(moduleName, ['mooAngular.utilityRepeatTransclude']);
mooAccordionDirective(mod);
return moduleName; // the name of your module
}));
For more reference on how I built the entire project using Webpack+AngularJS+ES6 you can view my github page for the moo-angular-accordion project.
For you to use this script it would look like:
(function (root, factory) {
if (typeof module !== 'undefined' && module.exports) {
// CommonJS also this prevents your error you are getting.
if (typeof angular === 'undefined') {
var angular = require('angular');
factory(angular);
module.exports = 'myModuleExportString';
} else {
factory(angular);
module.exports = 'myModuleExportString';
}
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['angular'], factory);
} else {
// Global Variables
factory(root.angular);
}
}(this, function (angular) {
'use strict';
// create your angular module and do stuff
var moduleName = 'myModule';
var mod = angular.module(moduleName, ['otherDepModulesIfNeeded']);
mod.directive(/*... defined here ...*/);
return moduleName; // the name of your module
}));
Breakdown:
You define a IIEF which is called with this and your module function (factory) provided as arguments.
The logic checks to see if angular already exists in the global namespace (and if CommonJS support is available.
If angular exists, use it (so that it isn't defined twice), and pass that angular to your module definition (factory)
If not CommonJS, check AMD
If not AMD, load to root as a global (usable as a Script tag)
EDIT: You can also use Grunt, Gulp, or whatever build system you want to bundle your assets instead of Webpack, however the magical script above makes your module exportable in multiple formats (AMD, Script Tag, CommonJS, etc.).
#Sean Larkin's answer is correct, but for those of you using jspm and typescript, here'e what I did there.
1) Write your App module:
/// <reference path="typings/tsd.d.ts" />
import * as angular from "angular";
import modules from "./Modules"; // a simple exported array
// Create our angular module.
angular.module("module.name", modules);
2) Run this command to build a bundle:
jspm bundle-sfx App - angular app.min.js --globals "{ 'angular': 'angular' }" --minify
3) Now app.min.js is an ES5 module library easy to be loaded in a script tag or even another jspm consumer website.

Resources