我唯一的区别是我没有 mocha 作为记者,我在 karma.conf.js 的框架中确实有 chai
gulpfile.js(注意:我的手表用于代码更改,我在部署之前构建和测试,所以这不会自动运行)。
gulp.task('Tests', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
coverageReporter: {
type : 'html',
dir: RootDir.docs + DocumentationPath.CodeCoverage,
},
singleRun: true
}, function() {
done();
});
业力.conf.js
module.exports = function(config) {
var SourceCode = [
'app/app.js',
...
];
var Libraries = [
'app/bower_components/angular/angular.js',
...
];
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha', 'chai'],
// list of files / patterns to load in the browser
files: Libraries.concat(SourceCode),
// list of files to exclude
exclude: [
],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
'app/**/*.js': ['coverage']
},
// test results reporter to use available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'coverage'],
coverageReporter: {
type : 'html',
dir : 'docs/coverage/'
},
logLevel: 'LOG_DEBUG',
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['PhantomJS'], // 'Chrome',
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: true
})
}
我完整的 gulpfile.js。这已经针对各种项目进行了修改,并不是所有的东西都被使用了。它还使用我们遵循的源代码结构。该工具在开发人员机器上监控和准备我们的发布目录,同时作为数据的本地副本。
var gulp = require('gulp');
var AppSync = require('browser-sync').create();
var mainBowerFiles = require('main-bower-files');
var concat = require('gulp-concat');
var del = require('del');
var fs = require('fs');
var GoogleCDN = require('gulp-google-cdn');
var Graph = require('gulp-angular-architecture-graph');
var csslint = require('gulp-csslint');
var header = require('gulp-header');
var hhint = require('gulp-htmlhint');
var hlint = require('gulp-htmllint');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant');
var istanbul = require('gulp-istanbul');
var jscs = require('gulp-jscs');
var stylish = require('gulp-jscs-stylish');
var jshint = require('gulp-jshint');
var jsonlint = require('gulp-jsonlint');
var karma = require('karma').Server;
var mocha = require('gulp-mocha');
var minifyCss = require("gulp-minify-css");
var minifyHtml = require("gulp-minify-html");
var notify = require("gulp-notify");
var plumber = require('gulp-plumber');
var run = require('gulp-run');
var size = require('gulp-size');
var sourcemaps = require('gulp-sourcemaps');
var stripdebug = require('gulp-strip-debug');
var uglify = require('gulp-uglify');
var util = require('gulp-util');
var watch = require('gulp-watch');
// Get Information using NodeJs file system from files for the Application
var getApplicationName = function() { return ReadLocalFile( RootDir.config + 'Application', __dirname); };
var getBuildGraphic = function() { return ReadLocalFile( RootDir.config + 'BuildGraphic', ''); };
var getCopyright = function() { return ReadLocalFile( RootDir.config + 'Copyright', 'Copyright (c) 2015 - Steven Scott'); };
var getVersion = function() { return ReadLocalFile( RootDir.config + 'Version', '0.0.1'); };
var getAppInfo = function() {
var Text = [
"/**",
" * " + getApplicationName(),
" * Version: " + getVersion(),
" * " + getCopyright(),
" */",
""
];
return Text.join('\n');
};
var getBuildInfo = function() {
var Text = [
'',
util.colors.yellow.bold(getBuildGraphic()),
getApplicationName(),
getCopyright(),
'Build (' + util.colors.green(getVersion()) + ')',
'',
];
return Text.join('\n');
}
var NoOp = function() { };
var OnErrorHandler = function(err) {
util.log(util.colors.white.bold(err + '!'));
this.emit('end');
};
var Paths = {
CDN: 'CDN',
Images: 'images/',
JavaScript: 'js/',
JSON: 'data/',
Libraries: 'ExternalLibraries/',
Modules: 'Modules/',
Styles: 'css/'
};
var RootDir = { config: './', dist: 'dist/', docs: 'docs/', home: 'app/' };
var DocumentationPath = { API: 'API.v' + getVersion() + '/', CodeCoverage: 'Coverage/', Graphs: 'Diagrams.v' + getVersion() + '/' };
var SourcePath = {
BowerComponents: ['bower_components/**'],
ExtraFiles: ['favicon.ico'],
ExtraStyleFiles: ['ExternalLibraries/ui.Grid/*.woff','ExternalLibraries/ui.Grid/*.ttf', 'ExternalLibraries/ui.Grid/*.svg'],
HTML: ['*.html'],
HTMLPages: ['Modules/**/*.html'],
Images: ['graphics/**/*.gif','graphics/**/*.jpg','graphics/**/*.png',
'Modules/**/*.gif', 'Modules/**/*.jpg', 'Modules/**/*.png'
],
JSON: ['Modules/**/*.json'],
Libraries: ['bower_components/angular-order-object-by/src/ng-order-object-by.js'],
LibStyles: [],
SourceCode: ['Modules/**/*.js'],
Styles: ['Modules/**/*.css'],
TestFiles: ['UnitTests/**/*.test.js'],
};
var ApplicationName = getApplicationName();
var BuildLogo = getBuildInfo();
var SourceCopyright = getAppInfo();
// ================ Gulp Tasks ================
// Package Bower Files into 1 Library
gulp.task('BowerFiles', function() {
del([ RootDir.home + Paths.CDN + "*.js", RootDir.dist + Paths.CDN + "*.js" ]);
// mainBowerFiles is used as a src for the task, usually you pipe stuff through a task
return gulp.src(mainBowerFiles(), {cwd: RootDir.home})
// Then pipe it to wanted directory
.pipe(gulp.dest(RootDir.home + Paths.CDN))
.pipe(gulp.dest(RootDir.dist + Paths.CDN))
});
// Convert Bower local files to CDN
gulp.task('BowerToCDN', ['BowerFiles'], function() {
var CDNOptions = {
};
return gulp.src('index.html', {cwd: RootDir.home})
.pipe(GoogleCDN(require(RootDir.config + 'bower.json'), CDNOptions))
.pipe(gulp.dest(RootDir.dist));
});
// Remove Temporary files (bak, log, etc...)
gulp.task('DeleteBackupFiles', function(callback) {
return del([
RootDir.config + '**/*.bak',
RootDir.config + 'lcov.info',
RootDir.config + '*.log'
], callback)
;
});
// Document the API
gulp.task('Document-API', function() {
var reportOptions = {
err: true, // default = true, false means don't write err
stderr: true, // default = true, false means don't write stderr
stdout: true // default = true, false means don't write stdout
};
del([ RootDir.docs + DocumentationPath.JavaScript ]);
return run('node_modules\\.bin\\jsdoc' +
' -c node_modules/angular-jsdoc/common/jsdoc.conf.json ' + // config file
' -t node_modules/angular-jsdoc/default ' + // template file
' -d ' + RootDir.docs + DocumentationPath.API +
' ./README.md ' +
' -r ' + RootDir.home + Paths.Modules
).exec();
});
// -=-=-=- Documentation - Do not wait to complete -=-=-=-
gulp.task('Documentation',['Document-API'], function() {
del([ RootDir.docs + DocumentationPath.Graphs ]);
return gulp.src(SourcePath.SourceCode, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(Graph({dest: RootDir.docs + DocumentationPath.Graphs})
);
});
// -=-=-=- HTML Pages -=-=-=-
gulp.task('HTMLPages', ['BowerToCDN'], function() {
del([ RootDir.dist + "*.html" ]);
gulp.src(SourcePath.HTML, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(hlint())
//.pipe(hhint('htmlhint.json'))
.pipe(hhint.reporter()) // FailReporter to fail build step
.pipe(minifyHtml())
.pipe(gulp.dest(RootDir.dist))
;
del([ RootDir.dist + Paths.Modules + "**/*.html" ]);
return gulp.src(SourcePath.HTMLPages, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(hlint())
.pipe(hhint('htmlhint.json'))
.pipe(hhint.reporter()) // FailReporter to fail build step
.pipe(minifyHtml())
.pipe(gulp.dest(RootDir.dist + Paths.Modules))
;
});
gulp.task('Images', function () {
del([ RootDir.home + Paths.Images + "*.png" ]);
del([ RootDir.dist + Paths.Images + "*.png" ]);
return gulp.src(SourcePath.Images, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(imagemin( {
progressive: true,
svgoPlugins: [{removeViewBox: false}],
use: [pngquant()]
}))
.pipe(gulp.dest(RootDir.home + Paths.Images))
.pipe(gulp.dest(RootDir.dist + Paths.Images))
;
});
// -=-=-=- JSON Data -=-=-=-
gulp.task('JSONChanges', function(callback) {
del([ RootDir.dist + Paths.JSON]);
return gulp.src(SourcePath.JSON, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(jsonlint())
.pipe(jsonlint.reporter())
.pipe(gulp.dest(RootDir.dist + Paths.JSON))
;
});
// -=-=-=- External Libraries -=-=-=-
gulp.task('Libraries-CSS', function() {
del([ RootDir.home + Paths.Libraries + 'ExternalLibraries.min.css' ]);
return gulp.src(SourcePath.LibStyles, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
// .pipe(minifyCss())
.pipe(concat('ExternalLibraries.min.css'))
.pipe(gulp.dest(RootDir.home + Paths.Libraries))
.pipe(gulp.dest(RootDir.dist + Paths.Styles))
;
});
gulp.task('Libraries', ['Libraries-CSS', 'BowerToCDN'], function() {
del([ RootDir.dist + Paths.JavaScript + 'ExternalLibraries.min.js' ]);
return gulp.src(SourcePath.Libraries, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(concat('ExternalLibraries' + '.min.js'))
.pipe(header(SourceCopyright))
.pipe(size( { showFiles: false, gzip: true, title: 'Min ExternalLbraries' } ))
.pipe(gulp.dest(RootDir.home + Paths.JavaScript))
.pipe(gulp.dest(RootDir.dist + Paths.JavaScript))
;
});
// -=-=-=- Misc. File Moves -=-=-=-
gulp.task('OtherFileChanges', function() {
gulp.src(SourcePath.ExtraFiles, {cwd: RootDir.home} )
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(gulp.dest(RootDir.dist))
;
return gulp.src(SourcePath.ExtraStyleFiles, {cwd: RootDir.home} )
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(gulp.dest(RootDir.dist))
;
});
// -=-=-=- Source Code Processing -=-=-=-
gulp.task('SourceCode-CSS', function() {
del([ RootDir.home + Paths.Styles + ApplicationName + ".min.css" ]);
del([ RootDir.dist + Paths.Styles + ApplicationName + ".min.css" ]);
return gulp.src(SourcePath.Styles, {cwd: RootDir.home})
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(csslint('csslint.json'))
.pipe(csslint.reporter())
.pipe(concat(ApplicationName + '.min.css'))
.pipe(gulp.dest(RootDir.home + Paths.Styles))
.pipe(minifyCss())
.pipe(gulp.dest(RootDir.dist + Paths.Styles));
;
});
// -=-=-=- Source Code Changed -=-=-=-
gulp.task('SourceCode', ['Documentation', 'JSONChanges', 'OtherFileChanges', 'SourceCodeTests'], function() {
util.log(BuildLogo);
del([ RootDir.home + Paths.JavaScript + ApplicationName + ".min.js" ]);
del([ RootDir.dist + Paths.JavaScript + ApplicationName + ".min.js" ]);
return gulp.src(SourcePath.SourceCode, {cwd: RootDir.home})
.pipe(jshint())
.pipe(jscs( 'jscs.json'))
.on('error', NoOp) // Don't Stop on Errors
.pipe(stylish.combineWithHintResults()) // combine with jshint results
.pipe(jshint.reporter('jshint-stylish'))
.pipe(plumber( { errorHandler: OnErrorHandler } ))
.pipe(concat(ApplicationName + '.min.js'))
.pipe(header(SourceCopyright))
.pipe(size({ showFiles: false, gzip: true, title: ApplicationName } ))
.pipe(gulp.dest(RootDir.home + Paths.JavaScript) )
.pipe(sourcemaps.init())
.pipe(stripdebug())
.pipe(uglify())
.pipe(size({ showFiles: false, gzip: true, title: 'Min ' + ApplicationName } ))
.pipe(sourcemaps.write())
.pipe(gulp.dest(RootDir.dist + Paths.JavaScript) )
;
});
gulp.task('SourceCodeTests', function(done) {
karma.start({
configFile: __dirname + '/karma.conf.js',
coverageReporter: {
type : 'html',
dir: RootDir.docs + DocumentationPath.CodeCoverage,
},
singleRun: true
}, function() {
done();
});
});
// -=-=-=- Job Tasks -=-=-=-
// Browser Sync - Auto Reload/Refresh
gulp.task('BrowserSyncStartup', ['SourceCode', 'SourceCode-CSS', 'Libraries', 'HTMLPages'], function() {
return AppSync.init({
server: {
baseDir: [RootDir.config],
index: 'index.html',
directory: false, // Set to True for Browsing Files, not launching index
routes: {
'/API': RootDir.docs + DocumentationPath.API,
'/app': RootDir.home,
'/Coverage': RootDir.docs + DocumentationPath.CodeCoverage + 'PhantomJS 1.9.8 (Windows 7 0.0.0)/'
}
},
port: 3000,
startPath: '/app'
});
});
/* Watch Tasks */
gulp.task('WatchBowerFiles', ['BowerToCDN'], function() { });
gulp.task('WatchHTMLPages', ['HTMLPages'], function() { AppSync.reload(); });
gulp.task('WatchGraphics', ['Images'], function() { AppSync.reload(); });
gulp.task('WatchLibraries', ['Libraries'], function() { AppSync.reload(); });
gulp.task('WatchSourceCodeCSS', ['SourceCode-CSS'], function() { AppSync.reload(); });
gulp.task('WatchSourceCode', ['SourceCode', 'Documentation'], function() { AppSync.reload(); });
gulp.task('WatchSourceCodeTests', ['SourceCodeTests'], function() { AppSync.reload(); });
// A development task to run anytime a file changes
gulp.task('WatchSource', ['BrowserSyncStartup'], function() {
gulp.watch([RootDir.home + SourcePath.HTML, RootDir.home + SourcePath.HTMLPages], ['WatchHTMLPages']);
gulp.watch(RootDir.home + SourcePath.Images, ['WatchGraphics']);
gulp.watch(RootDir.home + SourcePath.Libraries, ['WatchLibraries']);
gulp.watch(RootDir.home + SourcePath.SourceCode, ['WatchSourceCode']);
gulp.watch(RootDir.home + SourcePath.Styles, ['WatchSourceCodeCSS']);
gulp.watch(RootDir.home + SourcePath.TestFiles, ['WatchSourceCodeTests']);
});
// The default task (called when you run `gulp` from cli) runs a sequence of the above tasks
gulp.task('default',['SourceCodeTests', 'WatchSource', 'DeleteBackupFiles']);
// Write a step of the build on the console
function ShowStepOnConsole(MsgText) {
if(MsgText.length > 0)
{
var ConsoleMessage = [
'Process',
util.colors.magenta.bold(MsgText),
].join(' ');
util.log(ConsoleMessage);
}
}
// Return with a Syncronys Call the contents of a file
function ReadLocalFile( FileName, DefaultWhenNotFound)
{
if ( fs.existsSync(FileName) ) {
return fs.readFileSync(FileName);
}
else {
return DefaultWhenNotFound;
}
}