I'm having an angular project bundled with browserify using Gulp. Here is the tree
|--app
|--src
--js
-main.js
-otherFiles.js
|--spec
--mainspec.js <-- jasmin spec file
|--public
--js
--main.js
I'm having a gulp file which takes my source, main.js file, and browserifies it along with a gulp-jasmine tasks
gulp.task('js', function() {
return gulp.src('src/js/main.js')
.pipe(browserify({}))
.pipe(gulp.dest('public/js'));
});
gulp.task('specs', function () {
return gulp.src('spec/*.js')
.pipe(jasmine());
});
Along with some watch tasks etc.
Now, in my mainspec.js file, angular is not recognized, considering my test code:
describe("An Angular App", function() {
it("should actually have angular defined", function() {
expect(angular).toBeDefined();
});
});
And I'm getting an ReferenceError: angular is not defined error on terminal. I tried to require('angular'); on the first line but with no luck, getting a new error ReferenceError: window is not defined. I know there is something wrong with the setup and the test file not being able to reach the browserified files, but I can't just figure out the solution.
Any ideas?
Thanks in advance.
You need to define all aspects in your config file
function getKarmaConfig(environment) {
return {
frameworks : ['jasmine'],
files : [
// Angular + translate specified for build order
environment + '/js/jquery.min.js',
environment + '/js/angular.js',
environment + '/js/angular-translate.min.js',
environment + '/js/**/*.js',
'bower_components/angular-mocks/angular-mocks.js',
'test/unit/**/*.js'
],
exclude : [
],
browsers : ['PhantomJS'],
reporters : ['dots', 'junit','coverage'],
junitReporter: {
outputFile: 'test-results.xml'
},
preprocessors : {
'prod/js/*.js': ['coverage']
},
coverageReporter:{
type: 'html',
dir: 'coverage'
}
};
};
and define a gulp test task like this
gulp.task('test', ['build_prod'], function () {
var testKarma = getKarmaConfig(environment);
testKarma.action = 'run';
testKarma.browsers = ['PhantomJS'];
return gulp.src('./fake')
.pipe(karma(testKarma));
});
You just need to define src perfectly as per your structure. This will work :)
Related
I have been trying to get this to work maybe I'm missing something. I am using ng-constant and setting up different environments end point as mentioned in the ng-constants issue
However I am using gulp and the configuration looks like
gulp.task('environmentsapi', function () {
return ngConstant({
stream: true,
development: {
constants: {
"ENV": {"api": "http://1.1.1.1:8082/"}
}
},
production: {
constants: {
"ENV": {"api": "https://productionapplink/"}
}
}
})
// Writes config.js to dist/ folder
.pipe(gulp.dest('dist/scripts/config'));
});
I cant figure out how to call the different end points in the different gulp tasks like the example in the link ngconstant:development etc. How can i run this within the task environmentsapi, since this task is shared in all environment builds. Please let me know how to do this.
gulp.task('build', function () {
runSequence('clean', ['sass', 'scripts', 'bower_components', 'environmentsapi' //How can I run ngconstant:development here? ], 'wiredep')
});
Simply create new tasks that set flags!
Here I'm using the development flag that defaults to true.
var development = true;
gulp.task('prod', function () {
development = false;
});
gulp.task('environmentsapi', function () {
const apiEndpoint = development ? 'http://1.1.1.1:8082/' : 'https://productionapplink/';
return ngConstant({
stream: true,
constants: {
'ENV': {api: apiEndpoint}
}
});
});
Now, using gulp build will build your application with the ENV.api set to 'http://1.1.1.1:8082/', your development endpoint.
And calling gulp prod build will make your output use an ENV.api set to 'https://productionapplink/'.
As discussed in the comments section, the solution above is quite perfect when you only have two environments, but it quickly gets out of hand when the number of environment grows.
In that case, I suggest using a different approach, the Pirate way, using yargs.
Here would be your new gulpfile.js:
const argv = require('yargs').argv;
const endpoints = {
'dev': 'http://1.1.1.1:8082/',
'prod-org': 'https://productionapplink.org/',
'prod-com': 'https://productionapplink.com/',
'prod-gov': 'https://productionapplink.gov/'
};
gulp.task('enviornmentsapi', function () {
const apiEnpdoint = typeof argv.env === 'undefined' ? endpoints.dev : endpoints[argv.env];
return ngConstant({
stream: true,
constants: {
ENV: { api: apiEnpdoint }
}
}).pipe(gulp.dest('dist/scripts/config'));
});
Use it like follows:
gulp build uses the default api URL: 'http://1.1.1.1:8082/'
gulp build --env=prod-org uses 'https://productionapplink.org/'
gulp build --env=prod-com uses 'https://productionapplink.com/'
I hope this could work for you this time!
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have gulp file set up to watch for changes. I'm developing an application in ReactJS using Redux architecture. What I've noticed is that the gulp does not watch for any changes in the SCSS files.
/*eslint-disable */
var path = require('path');
var runSequence = require('run-sequence');
var install = require('gulp-install');
var spawn = require('child_process').spawn;
var $ = require('gulp-load-plugins')({
pattern: [
'gulp',
'gulp-*',
'gulp.*',
'merge-stream',
'del',
'browserify',
'watchify',
'vinyl-source-stream',
'vinyl-transform',
'vinyl-buffer',
'glob',
'lodash',
'less-plugin-*',
'mochify'
],
replaceString: /^gulp(-|\.)/,
rename: {
'merge-stream': 'mergeStream',
'del': 'delete'
}
});
var env = require('env-manager')({
argv: process.argv,
dir: path.join(__dirname, 'environments'),
base: 'base.js',
pattern: '{env}.js',
defaults: {
'env': 'development'
}
});
$.util.log($.util.colors.magenta('Running in ' + env.name + ' environment'));
require('gulp-tasks-registrator')({
gulp: $.gulp,
dir: path.join(__dirname, 'tasks'),
args: [$, env],
verbose: true,
panic: true,
group: true
});
$.gulp.task('clean', ['clean:server', 'clean:client'], function task(done) {
done();
});
$.gulp.task('install', function () {
return $.gulp.src([ './package.json']).pipe(install());
});
$.gulp.task('build', function task(done) {
return runSequence(
//'lint',
// 'install',
'clean',
'build:server',
'build:client:images',
'build:client:fonts',
[
'build:client:scripts',
'build:client:styles'
],
'build:client:html',
done
);
});
$.gulp.task('run-wrapper', function(done) {
var server = spawn('node', ['serviceWrapper.js'], {stdio: ['inherit']});
server.stderr.on('data', function(data){
process.stderr.write(data);
});
server.stdout.on('data', function(data) {
process.stdout.write(data);
});
server.unref();
});
$.gulp.task('default', function task(done) {
runSequence('build', ['serve', 'run-wrapper','watch'], done);
});
$.gulp.task('run', function task(done) {
runSequence('serve', done);
});
/*eslint-enable */
In what you've provided, there's no watch task or Sass task (though you do call a task named watch so if running gulp (the default task) isn't giving you an error you must have defined the task named watch somewhere).
There are two Sass plugins for gulp, one using Ruby Sass (gulp-ruby-sass) and one using LibSass (gulp-sass). You can read about the difference here, but in short gulp-sass will probably be faste. The best way to find out is to try one and then the other and compare gulp's console logs (where it says "finished task after x ms").
Here's a SASS-watching example, edited very slightly from the example in the gulp-sass readme (assumes that gulp-sass is in your package.json, in which case it will have been imported by your gulp-load-plugins call). $.s added to match the code you provided
$.gulp.task('sass', function () {
return gulp.src('yourstylespath/*.scss') // grab the .scss files
.pipe(sass().on('error', sass.logError)) // compile them into css, loggin any errors
.pipe(gulp.dest('yourcompiledcsspath')); // save them in yourcompiledcsspath
});
$.gulp.task('sass:watch', function () {
gulp.watch('yourstylespath/*.scss', ['sass']); // "run the task 'sass' when there's a change to any .scss file in yourstylespath
});
Side notes:
Considering all the packages you're using that don't follow the "gulp-packagename" naming scheme, it might be more efficient to just write them out individually like this (of course depends on how many packages you're using)
var delete = require('del'),
mergeStream = require('merge-stream'),
...;
Looks like your run task could just be this? $.gulp.task('run', ['serve']);
I have a JavaEE project that uses RequireJS to load a few third party frameworks. One of those frameworks is OpenLayers3. Openlayers3 natively creates a global "ol" variable. However, OpenLayers3 is written to be AMD compatible and works as a module through RequireJS. I also am using an OpenLayers3 plugin called "olLayerSwitcher" which is not optimized for AMD. Instead, it depends on the "ol" variable being global.
My require config looks like the following:
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
The project is uses Backbone and includes a Router module (/src/main/webapp/js/controller/AppRouter.js):
/*jslint browser : true*/
/*global Backbone*/
define([
'backbone',
'utils/logger',
'views/MapView'
], function (Backbone, logger, MapView) {
"use strict";
var applicationRouter = Backbone.Router.extend({
routes: {
'': 'mapView'
},
initialize: function () {
this.LOG = logger.init();
this.on("route:mapView", function () {
this.LOG.trace("Routing to map view");
new MapView({
mapDivId: 'map-container'
});
});
}
});
return applicationRouter;
});
The Router module depends on a View module (/src/main/webapp/js/views/MapView.js):
/*jslint browser: true */
define([
'backbone',
'utils/logger',
'ol',
'utils/mapUtils',
'olLayerSwitcher'
], function (Backbone, logger, ol, mapUtils, olLayerSwitcher) {
"use strict";
[...]
initialize: function (options) {
this.LOG = logger.init();
this.mapDivId = options.mapDivId;
this.map = new ol.Map({
[...]
controls: ol.control.defaults().extend([
new ol.control.ScaleLine(),
new ol.control.LayerSwitcher({
tipLabel: 'Switch base layers'
})
])
});
Backbone.View.prototype.initialize.apply(this, arguments);
this.render();
this.LOG.debug("Map View rendered");
}
});
return view;
});
The View module attempts to pull in both OpenLayers3 as well as the third-party OpenLayers plugin.
When the project is built and deployed, it works fine in-browser. When the View module is loaded, OpenLayers and the third-party plugin are pulled in just fine and everything renders properly.
However, when I attempt to test this in Jasmine is where all of this falls apart.
For Jasmine, I am using the Jasmine-Maven plugin. It pulls in JasmineJS, PhantomJS and RequireJS along with my libraries and runs my specs. The issue is that when run via Jasmine, the MapView module attempts to load both the OpenLayers3 library as well as the third party plugin (olLayerSwitcher) but fails because the third party plugin can't find "ol".
The test:
define([
"backbone",
"sinon",
'controller/AppRouter'
], function (Backbone, sinon, Router) {
describe("Router", function () {
beforeEach(function () {
this.router = new Router();
this.routeSpy = sinon.spy();
this.router.bind("route:mapView", this.routeSpy);
try {
Backbone.history.start({silent: true});
} catch (e) {
}
this.router.navigate("elsewhere");
});
it("does not fire for unknown paths", function () {
this.router.navigate("unknown", true);
expect(this.routeSpy.notCalled).toBeTruthy();
});
it("fires the default root with a blank hash", function () {
this.router.navigate("", true);
expect(this.routeSpy.calledOnce).toBeTruthy();
expect(this.routeSpy.calledWith(null)).toBeTruthy();
});
});
});
The error from Jasmine:
[ERROR - 2015-08-08T21:27:30.693Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - msg: ReferenceError: Can't find variable: ol
:262 in error
[ERROR - 2015-08-08T21:27:30.694Z] Session [4610ead0-3e14-11e5-bb2b-dd2c4b5c2c7b] - page.onError - stack:
global code (http://localhost:58309/js/vendor/ol3- layerswitcher/1.0.1/ol3-layerswitcher.js:9)
:262 in error
JavaScript Console Errors:
* ReferenceError: Can't find variable: ol
The relevant section from the ol3-layerswitcher plugin on line 9 is:
[...]
ol.control.LayerSwitcher = function(opt_options) {
[...]
So it does depend on "ol" being a thing at this point.
The Jasmine-Maven plugin creates its own spec runner HTML and the relevant portion looks like this:
<script type="text/javascript">
if(window.location.href.indexOf("ManualSpecRunner.html") !== -1) {
document.body.appendChild(document.createTextNode("Warning: Opening this HTML file directly from the file system is deprecated. You should instead try running `mvn jasmine:bdd` from the command line, and then visit `http://localhost:8234` in your browser. "))
}
var specs = ['spec/controller/AppRouterSpec.js'];
var configuration = {
paths: {
"sinon": ['/webjars/sinonjs/1.7.3/sinon'],
"jquery": ["/webjars/jquery/2.1.4/jquery"],
"backbone": ['/webjars/backbonejs/1.2.1/backbone'],
"underscore": ['/webjars/underscorejs/1.8.3/underscore'],
"text": ['/webjars/requirejs-text/2.0.14/text'],
"log4js": ['/webjars/log4javascript/1.4.13/log4javascript'],
"ol": ['/webjars/openlayers/3.5.0/ol'],
"olLayerSwitcher": ['/js/vendor/ol3-layerswitcher/1.0.1/ol3-layerswitcher']
},
shim: {
"olLayerSwitcher": {
deps: ["ol"],
exports: "olLayerSwitcher"
},
'sinon' : {
'exports' : 'sinon'
}
}
};
if (!configuration.baseUrl) {
configuration.baseUrl = 'js';
}
if (!configuration.paths) {
configuration.paths = {};
}
if (!configuration.paths.specs) {
var specDir = 'spec';
if (!specDir.match(/^file/)) {
specDir = '/'+specDir;
}
configuration.paths.specs = specDir;
}
require.config(configuration);
require(specs, function() {
jasmine.boot();
});
I am able to create a customer HTML runner but am not sure what the problem is so I wouldn't know what needs changing.
This doesn't seem to be a PhantomJS issue as I can load the tests in-browser and am experiencing the same issue.
I'd appreciate if anyone has any thoughts on what could be happening here. I really do not want to hack up the third-party module to transform it into a RequireJS module as the Jasmine testing is the last-leg of implementing this completely and I'm completely stuck here.
I am using Jasmine 2.3.0 and RequireJS 2.1.18
I apologize for not linking out more but this is a new account and I don't have enough rep for it.
It will be tough to figure out the problem without a running version of your setup.
However, if you're able to customize the SpecRunner.html for jasmine generated by the maven plugin, simply include the jasmine(/ any other library causing an issue) in the SpecRunner html - <script src="/<path_to_lib>">.
In my experience, its usually not worth the effort , to make libraries used in source amd compliant and play nicely with every other library for testing setup.
I'm trying to setup this configuration, but I need help. I'm trying to use: https://github.com/accordionpeas/grunt-mocha-require-phantom.
My structure:
build-dev/ <-- Generated by grunt
vendor/
js/
jquery.js
require.js
js/
model/
cache.js <-- File to be tested
tests/
cache.js <-- Test for a file
tests.js <-- like test-bootstrap.js
My gruntfile config is:
mocha_require_phantom:
devel:
options:
base: 'build-dev/js'
main: 'tests'
requireLib: '../vendor/js/require.js'
files: ['tests/**/*.js']
port: 3001
My tests.js (test-bootstrap.js) is:
require.config({
paths: {
jquery: '../vendor/js/jquery',
chai: '/node_modules/chai/chai'
},
baseUrl: '/'
});
mocha.setup({
ui: 'bdd'
});
require([testPathname], function() {
if (window.mochaPhantomJS) {
return mochaPhantomJS.run();
} else {
return mocha.run();
}
});
My tests/cache.js is:
define(['chai', 'model/cache'], function(chai, cache) {
var should;
should = chai.should();
return describe('test suite 1', function() {
return it('should work', function() {
return cache.test().should.be.equal(5);
});
});
});
The problem is it's not working. It can't load model/cache. I was trying to change baseUrl in tests.js (like test-bootstrap.js). I was also trying to change baseUrl in grunt. I was trying to add path: model: ../../js/model, but it was ignored.
I need to call for a model as model/cache, how do I have to set up things to make it work? Should I use another plugin - which one?
Edit: Fixed typos.
I'm having problem with Browserify requiring a vendor library.
The vendor library I'm using is better-dom, which is also built with Browserify. I installed it from bower and when I'm trying to built, I got:
Error: Cannot find module './utils' from '<...>/bower_components/better-dom/dist'
Apparently Browserify is trying to parse and process the requires statements in the pre-built library. I tried browserify-shim and modulify with no luck, other attempts are also included below. Any help is appreciated, thanks in advance.
My configuration:
package.json:
...
"browser": {
"DOMLegacy": "./bower_components/better-dom/dist/better-dom-legacy.js",
"DOM": "./bower_components/better-dom/dist/better-dom.js"
},
...
Gulpfile.js:
gulp.task('scripts', function() {
var bundle = browserify({
noparse: ["<...>bower_components/better-dom/dist/better-dom.js"]
});
bundle.add('./js/all.js');
// bundle.external("./bower_components/better-dom/dist/better-dom-legacy.js");
// bundle.external("./bower_components/better-dom/dist/better-dom.js");
// bundle.transform({ modulify: {
// "./bower_components/better-dom/dist/better-dom-legacy.js": "DOMLegacy",
// "./bower_components/better-dom/dist/better-dom.js": "DOM"
// }});
// bundle.require(
// "./bower_components/better-dom/dist/better-dom-legacy.js",
// { expose: "DOMLegacy" });
// bundle.require(
// "./bower_components/better-dom/dist/better-dom.js",
// { expose: "DOM" }
// );
return bundle.bundle()
.on('error', function(e) {
console.log(e.toString());
this.emit('end');
})
.pipe(source('all.js'))
.pipe(gulp.dest(paths.assets));
});
I just found out there is a bug in browserify 5 with the noparse option.
Workaround: use the old name of this option: noParse (still working in browserify 5)
var bundle = browserify({
noParse: ["<...>bower_components/better-dom/dist/better-dom.js"]
});
It should fix your build.