Im facing a problem when I try to use browserify, angularjs and restangular.
When I try to require the npm or bower module, for example require('restangular), browserify returns empty object. This happens when i require any bower or npm modules. When I try to require any local file, everything is working fine.
file structure:
bower_components/
src/
-client
-app
app.js
backend
backend.module.js
-test
test.module.ls
test.js
node_modules/
app.js
(function() {
'use strict';
require('angular');
var rest = require('restangular');
console.log(rest);
module.exports = angular
.module('app', [
require('restangular').name,
require('./test/test.module').name,
]);
})();
package.json
"browserify": {
"transform": [
"browserify-shim"
]
},
"browser": {
"restangular": "./bower_components/restangular/dist/restangular.js"
},
"browserify-shim": {
"restangular": "restangular"
}
gulpfile.js
gulp.task('browserify', function() {
gulp.src(['./src/client/app/app.js'])
.pipe(plugins.browserify({
insertGlobals: true,
debug: true
}))
.pipe(plugins.concat('bundled.js'))
.pipe(gulp.dest('./src/client/js'))
});
Can you help me?
Thanks in advance.
Just modify your "browser" part in package.json:
"browserify-shim": {
"angular": {
"exports": "angular"
},
"restangular": {
"depends": [
"angular"
],
"exports": "restangular"
}
}
Hope it will work.
Try modifying your package.json file with this snippet.
"browser": {
"restangular": "./bower_components/restangular/dist/restangular.js"
},
"browserify-shim": {
"restangular": {
"depends": [
"angular",
"lodash:_"
],
"exports": "null"
}
}
Solution courtesy of #newtricks from this discussion
Related
Using the angular.mock.inject(...) function when trying to unit test an Angular (Ionic) 1 application throws the following error. The strange thing is that there is no specific error message, making particularly hard to debug. No matter what I try, it always seems to throw this same non-descript error without any message.
PhantomJS 2.1.1 (Linux 0.0.0) LoginController should pass FAILED
bower_components/angular/angular.js:4527:53
forEach#bower_components/angular/angular.js:321:24
loadModules#bower_components/angular/angular.js:4487:12
createInjector#bower_components/angular/angular.js:4409:30
WorkFn#bower_components/angular-mocks/angular-mocks.js:3160:60
loaded#http://localhost:9876/context.js:151:17
Removing the call to angular.mock.inject() allows the test to pass.
Here's the test in question:
describe('LoginController', function() {
var scope;
var controller;
beforeEach(angular.mock.module('mCommonJobs'));
beforeEach(angular.mock.inject(function($rootScope, $controller) {
scope = $rootScope.$new();
controller = $controller('LoginController', {
$scope: scope
});
}));
it('should pass', function() {
expect(true).toEqual(true);
});
});
My bower dependencies:
"dependencies": {
"angular-resource": "#1.5.0",
"ionic": "driftyco/ionic-bower#1.3.2",
"ngCordova": "^0.1.27-alpha",
"ng-cordova-oauth": "^0.3.0",
"ngstorage": "^0.3.11",
"angular-mocks": "^1.5.2"
},
"resolutions": {
"angular": "~1.5.x"
}
And the files set in the Karma test config:
files: [
//Angular source
'bower_components/angular/angular.js',
'bower_components/angular-animate/angular-animate.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/ionic/js/ionic.bundle.js',
'bower_components/ng-cordova-oauth/dist/ng-cordova-oauth.js',
'bower_components/ngCordova/dist/ng-cordova.js',
'bower_components/ngCordova/dist/ng-cordova-mocks.js',
'bower_components/ngstorage/ngStorage.js',
//App code
'app/**/*.module.js',
'app/**/*.js',
'app/*.js',
//Test files
'test/**/*.test.js'
],
This issue was resolved by not including all of ionic.bundle.js in the files config of karma, but by specifically including its parts.
I also explicitly forced all versions of angular-related dependencies to be the same version (special thanks to Phil in the comments.).
In the end, my bower.json had:
"dependencies": {
"angular-resource": "1.5.2",
"ionic": "driftyco/ionic-bower#1.3.2",
"ngCordova": "^0.1.27-alpha",
"ng-cordova-oauth": "^0.3.0",
"ngstorage": "^0.3.11",
"angular-mocks": "1.5.2"
},
and my karma config looked like:
files: [
//Angular source
'bower_components/angular/angular.js',
'bower_components/angular-animate/angular-animate.js',
'bower_components/angular-mocks/angular-mocks.js',
'bower_components/angular-resource/angular-resource.js',
'bower_components/angular-sanitize/angular-sanitize.js',
'bower_components/angular-ui-router/release/angular-ui-router.js',
'bower_components/ionic/js/ionic.js',
'bower_components/ionic/js/ionic-angular.js',
'bower_components/ng-cordova-oauth/dist/ng-cordova-oauth.js',
'bower_components/ngCordova/dist/ng-cordova.js',
'bower_components/ngCordova/dist/ng-cordova-mocks.js',
'bower_components/ngstorage/ngStorage.js',
//App code
'app/**/*.module.js',
'app/**/*.js',
'app/*.js',
//Test files
'test/**/*.test.js'
],
I have a problem where react-sortable-mixin is not respecting the browserify-shim global:Sortable declaration in my package.json file thus causing the Sortable module to be packaged up in my bundle. I have run into a similar problem with other modules so it may very well be a config problem on my part. I have created a small test package that simply requires React and react-sortbable-mixin in order to demonstrate the problem:
package.json
{
"name": "test",
"version": "1.0.0",
"description": "Just a test",
"main": "index.js",
"dependencies": {
"react": "^0.14.8",
"sortablejs": "^1.4.2"
},
"devDependencies": {
"browserify-shim": "^3.8.12"
},
"browserify": {
"transform": [
"browserify-shim"
]
},
"browserify-shim": {
"react": "global:React",
"sortablejs": "global:Sortable",
"sortablejs/react-sortable-mixin": {
"depends": "sortablejs:Sortable"
}
}
}
index.js
"use strict";
var React = require('react');
var SortableMixin = require('sortablejs/react-sortable-mixin');
react-sortable-mixin.js (Just the first part of the module...)
(function (factory) {
'use strict';
if (typeof module != 'undefined' && typeof module.exports != 'undefined') {
module.exports = factory(require('./Sortable'));
}
else if (typeof define === 'function' && define.amd) {
define(['./Sortable'], factory);
}
else {
/* jshint sub:true */
window['SortableMixin'] = factory(Sortable);
}
})(function (/** Sortable */Sortable) { ...
Here is the diagnostic output from browserify:
% BROWSERIFYSHIM_DIAGNOSTICS=1 browserify index.js -t browserify-shim -o bundle.js
{ file: '/home/jlafosse/test/index.js',
info:
{ package_json: '/home/jlafosse/test/package.json',
packageDir: '/home/jlafosse/test',
shim: undefined,
exposeGlobals: { react: 'React', sortablejs: 'Sortable' },
browser: undefined,
'browserify-shim':
{ react: 'global:React',
sortablejs: 'global:Sortable',
'sortablejs/react-sortable-mixin': { depends: 'sortablejs:Sortable' } },
dependencies: { react: '^0.14.8', sortablejs: '^1.4.2' } },
messages:
[ 'Resolved "sortablejs/react-sortable-mixin" found in package.json to "/home/jlafosse/test/sortablejs/react-sortable-mixin"',
'Found depends "sortablejs" as an installed dependency of the package',
{ resolved:
{ '/home/jlafosse/test/sortablejs/react-sortable-mixin':
{ exports: null,
depends: { sortablejs: 'Sortable' } } } } ] }
{ file: '/home/jlafosse/test/index.js',
info:
{ package_json: '/home/jlafosse/test/package.json',
packageDir: '/home/jlafosse/test',
resolvedPreviously: true,
shim: undefined,
exposeGlobals: { react: 'React', sortablejs: 'Sortable' },
browser: undefined,
'browserify-shim':
{ react: 'global:React',
sortablejs: 'global:Sortable',
'sortablejs/react-sortable-mixin': { depends: 'sortablejs:Sortable' } },
dependencies: { react: '^0.14.8', sortablejs: '^1.4.2' } },
messages: [] }
I know the global shimming works because React is not included in the bundle... however as mentioned above, Sortable is being included. Also if I simply require('sortablejs') instead of the sortablejs/react-sortable-mixin in my index.js file, Sortable WILL NOT be included in the bundle as expected so my thought is that either my config is wrong or the module format for react-sortable-mixin does not respect browserify-shim.
Any help is appreciated.
This isn't possible without modifying the contents of the Sortable library. Browserify Shim alters your bundle.js file to either include window.PackageName or the entire package, depending on the browserify-shim directive in your package.json.
In your situation, when you require('sortablejs/react-sortable-mixin'); you're expecting Browserify Shim to alter the contents of node_modules/sortablejs/react-sortable-mixin.js such that require('./Sortable') becomes window.Sortable inside that file. The problem is that Browserify Shim doesn't alter the contents of the node_modules directory so this isn't possible.
There are a couple options:
Rather than loading Sortable via CDN, load it globally via your bundle.js script to ensure it is only loaded once. Your index.js would change to:
window.Sortable = require('sortablejs');
var SortableMixin = require('sortablejs/react-sortable-mixin');
Fork your own standalone file for react-sortable-mixin.js and bundle this directly in your bundle so that Browserify Shim can act on it.
I'm using wiredep to automatically include ckeditor and ng-file-upload to my index template and karma.conf.js.
My project is bootstrapped by jhipster.
For ckeditor package, I have to include two files, ckeditor.js and ckeditor-angularjs.js, but wiredep won't copy these files... (i don't have these files into my index.html and my karma.conf.js).
in my bower.json, i have this declaration (after doing bower install ckeditor-angularjs --save):
"dependencies": {
"ckeditor-angularjs": "*"
}
My Gruntfile.js :
wiredep: {
app: {
src: ['src/main/webapp/index.html'],
exclude: [
/angular-i18n/ // localizations are loaded dynamically
]
},
test: {
src: 'src/test/javascript/karma.conf.js',
exclude: [/angular-i18n/, /angular-scenario/],
ignorePath: /\.\.\/\.\.\//, // remove ../../ from paths of injected javascripts
devDependencies: true,
fileTypes: {
js: {
block: /(([\s\t]*)\/\/\s*bower:*(\S*))(\n|\r|.)*?(\/\/\s*endbower)/gi,
detect: {
js: /'(.*\.js)'/gi
},
replace: {
js: '\'{{filePath}}\','
}
}
}
}
}
i tested with overrides option in bower.json but it wont work... :
"overrides": {
"bootstrap": {
"main": [
"dist/js/bootstrap.js",
"dist/css/bootstrap.css",
"less/bootstrap.less"
]
},
"ckeditor-angularjs": {
"main": [
"./src/main/webapp/bower_components/ckeditor/ckeditor.js",
"build/ckeditor-angularjs.min.js"
]
},
"ng-file-upload": {
"main": "ng-file-upload-all.js"
}
}
when I do this : grunt wiredep, I have this error :
Warning: Maximum call stack size exceeded Use --force to continue. Aborted due to warnings.
with --force -v param :
Warning: Error: angular is not installed. Try running `bower install`. Used --force, continuing.
Done, but with warnings.
I don't think that angular package is the problem...
Do you know how can I solve this ?
Thanks.
I have a stable product which uses angular 1.2.23. Of late, I decided to move to angular 1.4.3. After few compatibility issues with all the dependencies, my application is working fine, but all the unit testcases have started failing..After investing I realized that if I upgrade versions of all dependencies but keep angular at the previous version i.e 1.2.23, the testcases work fine..With angular 1.4.3, for some reason the injections of the dependencies in unit tests are failing.
Following is the list of the updated dependencies in bower.json.
"dependencies": {
"angular-cookies": "1.4.3",
"bootstrap": "3.0.3",
"angular-ui-router": "0.2.15",
"angular-gettext": "2.1.0",
"angular": "1.4.3",
"angular-ui-utils": "3.0.0",
"restangular": "1.4.0",
"angular-route": "1.4.3",
"momentjs": "2.10.6",
"angular-i18n": "1.4.3"
}
Following is the test file -
describe("Module: x.xyz", function () {
describe("Factory: xyz", function () {
var service;
beforeEach(function () {
module('x.xyz');
inject(function ($injector) {
service = $injector.get("xyz");
});
});
describe("Testing service(): ", function () {
describe('Testing getXYZDescription(): ', function () {
it('should return the description for the xyz event name passed if it is available', function () {
expect(service.getXYZDescription('abc')).toBe('abc');
});
});
});
});
});
When I run the above test case, I get service is undefined. Can anyone help?
I ran into a similar issue when upgrading from angular 1.3 to 1.4. In my case, I forgot to upgrade angular-mocks from 1.3 to 1.4. I suspect that mocking functionality was broken out into a separate module in the transition from 1.2 to 1.3, although I can't seem to find documentation to confirm that. In that case, you wouldn't have needed an angular-mocks dependency for your original app, but you would need to add the dependency when upgrading.
You should be able to fix this by adding "angular-mocks": "1.4.x" to your list of dependencies and a link to installed file in your karma config. For completeness, here's a minimal example:
karma.conf.js:
/*global module*/
module.exports = function (config) {
'use strict';
config.set({
basePath: '.',
frameworks: ['jasmine'],
files: [
'node_modules/angular/angular.js',
'node_modules/angular-mocks/angular-mocks.js',
'*.js'
],
autoWatch: true,
singleRun: false,
browsers: ['Chrome']
});
};
package.json:
{
"name": "angular-inject-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "karma start karma.conf.js"
},
"author": "",
"dependencies": {
"angular": "1.4.x",
"angular-mocks": "1.4.x",
"karma": "^0.13.x",
"karma-cli": "^0.1.x",
"karma-jasmine": "^0.3.x",
"karma-chrome-launcher": "^0.2.x"
}
}
test.js:
/*global angular, beforeEach, describe, expect, inject, it, module*/
angular.module('x', [])
.factory('xyz', function () {
"use strict";
return {
getXYZDescription: function (value) {
return value;
}
};
});
describe("Module: x.xyz", function () {
"use strict";
describe("Factory: xyz", function () {
var service;
beforeEach(function () {
module('x');
inject(function ($injector) {
service = $injector.get("xyz");
});
});
it('Should echo input', function () {
expect(service.getXYZDescription('abc')).toBe('abc');
});
});
});
Experimenting with ngReactGrid I've got stuck on an issue where the grid component (ngReactGrid.js:38) throws an error of React is undefined. What could cause this, as the requirejs setup file includes
"shim": {
"angular": {
exports: 'angular'
},
'react': {
exports: 'React'
},
"ngReactGrid": {
deps: ['angular', 'react']
}
}
http://plnkr.co/edit/MwxbGnx1xu3gxfhY7ENM
The same code outside of requirejs works as it should.
Checkout plnkr
require.config({
"baseUrl": "/js",
"paths": {
"angular": "https://code.angularjs.org/1.3.0-beta.5/angular",
"react": "http://fb.me/react-0.10.0",
"ngReactGrid": "https://rawgit.com/josebalius/ngReactGrid/master/build/js/ngReactGrid",
'app': 'http://run.plnkr.co/zmcl7fFM2eAPf9Ew/app'
},
"shim": {
"angular": {
exports: 'angular'
},
"ngReactGrid": {
deps: ['angular', 'react']
}
}
});
require(['app'], function( app) {
var $html = angular.element(document.getElementsByTagName('html')[0]);
angular.element().ready(function() {
angular.bootstrap($html, [app.name]);
});
});
Hope this will help