I have multiple entries in my Webpack config:
entry: {
'polyfills': './src/polyfills.ts',
'vendor': './src/vendor.ts',
'app': './src/main.ts'
},
When I run npm start (webpack-dev-server --inline --progress --port 8080 --bail) the \<my-app>Loading...</my-app> in my index.html turns into scripts in this order:
<script type="text/javascript" src="http://localhost:8080/common.js"> <!--I also have CommonsChunkPlugin-->
</script><script type="text/javascript" src="http://localhost:8080/vendor.js"></script>
<script type="text/javascript" src="http://localhost:8080/polyfills.js"></script>
<script type="text/javascript" src="http://localhost:8080/app.js"></script>
But when I run webpack -p --progress --profile --bail it's in this order:
common, app, polyfil, then vendor
Order is important. My app.js code won't work if run before polyfil.js or vendor.js. How do I control the order?
You can use the 'manual' option these days :
new HtmlWebpackPlugin({
chunks: ['polyfill', 'vendor', 'bundle'],
chunksSortMode: 'manual',
}),
You can create a helper in order to accomplish it:
function packageSort(packages) {
// packages = ['polyfills', 'vendor', 'app']
var len = packages.length - 1;
var first = packages[0];
var last = packages[len];
return function sort(a, b) {
// polyfills always first
if (a.names[0] === first) {
return -1;
}
// app always last
if (a.names[0] === last) {
return 1;
}
// vendor before app
if (a.names[0] !== first && b.names[0] === last) {
return -1;
} else {
return 1;
}
}
}
And in your webpack config file:
plugins.index = new HtmlWebpackPlugin({
template: 'src/index.html',
filename: 'index.html',
chunksSortMode: packageSort(['polyfills', 'vendor', 'app'])
});
Thanks #EdmarMiyake for pointing me in the direction of chunksSortMode. I tried setting it to 'dependency' first, but that didn't seem to work. In the end I resorted to this:
function packageSort(packages) {
return function sort(left, right) {
var leftIndex = packages.indexOf(left.names[0]);
var rightindex = packages.indexOf(right.names[0]);
if ( leftIndex < 0 || rightindex < 0) {
throw "unknown package";
}
if (leftIndex > rightindex){
return 1;
}
return -1;
}
};
and
new HtmlWebpackPlugin({
template: 'src/index.html',
chunksSortMode: packageSort(['common', 'polyfills', 'vendor', 'app'])
}),
This function could be even better: you give the list of the element you want to place at first in your html file
function packageSort(packages) {
return function sort(left, right) {
var leftIndex = packages.indexOf(left.names[0]);
var rightindex = packages.indexOf(right.names[0]);
if (rightindex < 0) {
return -1;
}
if ( leftIndex < 0) {
return 1;
}
if (leftIndex > rightindex){
return 1;
}
return -1;
}
};
Related
I am trying to use KendoUI datetimepicker in my angular(1.x) project. When I directly reference the KendoUI js file in my index.html page, it works fine. But when i try to add a reference to it via gulp, it keeps on throwing the following error:
Uncaught ReferenceError: module is not defined at kendo.ui.core.js:1
In my package.json, I have
"kendo-ui-core": "2017.2.621"
And this is what i have in my gulp file:
/// <reference path="node_modules/moment/moment.js" />
/// <reference path="node_modules/moment/src/moment.js" />
/// <binding BeforeBuild='clean' AfterBuild='build' Clean='clean' />
var gulp = require("gulp"),
rimraf = require("rimraf"),
less = require('gulp-less'),
cssmin = require('gulp-cssmin'),
concat = require("gulp-concat-sourcemap"),
rename = require('gulp-rename'),
jshint = require('gulp-jshint'),
ignore = require('gulp-ignore'),
cacheBuster = require('gulp-cache-bust'),
templateCache = require('gulp-angular-templatecache');
var paths = {
webroot: "./build/",
approot: "./app/"
};
paths.fonts = "./fonts/**/*";
paths.less = "./less/**/*.less";
paths.images = "./images/**/*";
paths.js = paths.approot + "**/*.js";
paths.specs = paths.approot + "**/*.spec.js";
paths.views = paths.approot + "**/*.html";
gulp.task("clean", function (cb) {
rimraf(paths.webroot, cb);
});
gulp.task('jshint', function () {
return gulp.src(paths.js)
.pipe(ignore.exclude('*.spec.js'))
.pipe(jshint('jshint.config.json'))
.pipe(jshint.reporter('gulp-jshint-file-reporter', {
filename: __dirname + '/jshint-output.log'
}));
//.pipe(jshint.reporter("fail")); // Throw error and fail build
});
gulp.task("build:js", function () {
return gulp.src([
paths.approot + "**/*.module.js",
paths.approot + "**/*.config.js",
paths.js,
"!" + paths.specs
])
.pipe(concat('app.js', { sourcesContent: true }))
.pipe(gulp.dest(paths.webroot + "app/"));
});
gulp.task("build:views", function () {
return gulp.src([paths.views])
.pipe(templateCache({ root: "app", module: "goalEnvision" }))
.pipe(gulp.dest(paths.webroot + "app/"));
});
gulp.task("build:fonts", function () {
return gulp.src([
paths.fonts,
'node_modules/bootstrap/dist/fonts/*',
'node_modules/bootstrap-less/fonts/*'
])
.pipe(gulp.dest(paths.webroot + "fonts/"));
});
gulp.task("build:less", function () {
return gulp.src(["./less/**/app.less"]) //compile app + theme less files
.pipe(less({
paths: [
'.',
'node_modules/angucomplete-alt/angucomplete-alt.css'
//'./node_modules/bootstrap-less',
]
}))
.pipe(gulp.dest(paths.webroot + "css/"));
});
gulp.task("build:images", function () {
return gulp.src([paths.images])
.pipe(gulp.dest(paths.webroot + "images/"));
});
gulp.task("build:index.html", function () {
return gulp.src("index.html")
.pipe(gulp.dest(paths.webroot));
});
gulp.task("build:favicon.ico", function () {
return gulp.src("favicon.ico")
.pipe(gulp.dest(paths.webroot));
});
gulp.task("build:cache-bust", ["build:index.html", "build:js", "build:less", "build:libs.js", "build:libs.css"], function () {
return gulp.src(paths.webroot + "index.html")
.pipe(cacheBuster())
.pipe(gulp.dest(paths.webroot));
});
gulp.task('build:libs.js', function () {
gulp.src([
'node_modules/jquery/dist/jquery.min.js',
'node_modules/angular/angular.min.js',
'node_modules/angular-dynamic-locale/dist/tmhDynamicLocale.min.js',
'node_modules/angular-xeditable/dist/js/xeditable.min.js',
'node_modules/angular-file-upload/dist/angular-file-upload.min.js',
'node_modules/angular-loading-bar/build/loading-bar.min.js',
'node_modules/ng-img-crop/compile/minified/ng-img-crop.js',
'node_modules/angular-ui-router/release/angular-ui-router.min.js',
'node_modules/angular-local-storage/dist/angular-local-storage.min.js',
'node_modules/highcharts/highcharts.js',
'node_modules/highcharts-ng/dist/highcharts-ng.min.js',
'node_modules/angular-ui-bootstrap/dist/ui-bootstrap.js',
'node_modules/angular-ui-bootstrap/dist/ui-bootstrap-tpls.js',
'node_modules/angular-translate/dist/angular-translate.min.js',
'node_modules/angular-animate/angular-animate.min.js',
'node_modules/angular-toastr/dist/angular-toastr.min.js',
'node_modules/angular-toastr/dist/angular-toastr.tpls.min.js',
'node_modules/jquery-ui-dist/jquery-ui.min.js',
'node_modules/angular-ui-sortable/dist/sortable.min.js',
'node_modules/angular-touch/angular-touch.js',
'node_modules/sweetalert/dist/sweetalert.min.js',
'node_modules/angular-sweetalert/SweetAlert.min.js',
'node_modules/moment/min/moment.min.js',
'node_modules/angular-bootstrap-datetimepicker/src/js/datetimepicker.js',
'node_modules/angular-bootstrap-datetimepicker/src/js/datetimepicker.templates.js',
'node_modules/bootstrap-toggle/js/bootstrap-toggle.min.js',
//inkluderas i common/components/guide behövde ändra i källkoden för att disabla automatisk scrolling
//'node_modules/angular-tour/dist/angular-tour-tpls.js',
'node_modules/angular-moment/angular-moment.min.js',
'node_modules/angular-sanitize/angular-sanitize.js',
'node_modules/angular-bootstrap-confirm/dist/angular-bootstrap-confirm.js',
'node_modules/angular-hotkeys/build/hotkeys.min.js',
'node_modules/angucomplete-alt/dist/angucomplete-alt.min.js',
'node_modules/angular-sticky-plugin/dist/angular-sticky.min.js',
'node_modules/kendo-ui-core/js/kendo.ui.core.js',
//Tried with different permutation/combination of these files as well
//'node_modules/kendo-ui-core/js/kendo.core.js',
//'node_modules/kendo-ui-core/js/kendo.popup.js',
//'node_modules/kendo-ui-core/js/kendo.calendar.js',
//'node_modules/kendo-ui-core/js/kendo.datepicker.js',
//'node_modules/kendo-ui-core/js/kendo.timepicker.js',
//'node_modules/kendo-ui-core/js/kendo.datetimepicker.js',
//'node_modules/kendo-ui-core/js/kendo.angular.js',
])
.pipe(concat('libs.js', { sourcesContent: true }))
.pipe(gulp.dest(paths.webroot + "/libs"));
});
gulp.task('build:libs.css', function () {
gulp.src([
'node_modules/angular-toastr/dist/angular-toastr.css',
'node_modules/sweetalert/dist/sweetalert.css',
'node_modules/angular-bootstrap-datetimepicker/src/css/datetimepicker.css',
'node_modules/angular-xeditable/dist/css/xeditable.css',
'node_modules/ng-img-crop/compile/minified/ng-img-crop.css',
'node_modules/angular-loading-bar/build/loading-bar.css',
'node_modules/bootstrap-toggle/css/bootstrap-toggle.css',
'node_modules/angular-tour/dist/angular-tour.css'
])
.pipe(concat('libs.css', { sourcesContent: true }))
.pipe(gulp.dest(paths.webroot + "/libs"));
});
gulp.task("build:webconfig", function () {
return gulp.src("Web.config")
.pipe(gulp.dest(paths.webroot));
});
gulp.task("build", ["jshint", "build:js", "build:less", "build:fonts", "build:images", "build:libs.js", "build:libs.css", "build:views", "build:index.html", "build:favicon.ico", "build:cache-bust", "build:webconfig"]);
gulp.task('watchAndBuild', function () {
gulp.watch(paths.js, ['build']);
gulp.watch(paths.views, ['build']);
});
The exact line where it throws error relates to
I think I am not including the kendoui files in the correct manner. What changes do I need to get it working?
The only way I was able to solve this error was by including a direct reference to the kendo ui js file in the index.html. Hope it will help others.
I have a site, which technically consists of a number of separate SPAs.
App/Admin
App/Signup
App/MainApp
How should I organize the App folder and the gulp build to make this into 3-4 separate files / modules that are loaded when required.
Since I had to spend a whole day getting this to work, I will answer my own question.
First, prepare a loader site. This would be the main site that is actually loaded that is responsible from loading all the other sites.
App/main.js - Contains the requirejs setup
In this we would run app.setRoot('shell', 'entrance');
App/shell.js - contains the router config
return router.map([
{ route: 'Admin/*all', moduleId: "Admin/index", nav: true },
{ route: 'Signup/*all', moduleId: "Signup/index", nav: true },
{ route: '*all', moduleId: "MainApp/index", nav: true }
])
.buildNavigationModel()
.activate();
App/shell.html - contains the router usage and common header/footer/loading shield
<div style="height: 100%" data-bind="css: { loading: isLoading }">
<!-- ko compose: 'loading.html'--><!-- /ko -->
<div class="header">...</div>
<!-- ko router: { transition:'entrance' } --><!-- /ko -->
</div>
App/*.js - Files shared among all the SPAs
App/MainApp/index.js - Contains the sub router for that SPA
define(["require", "exports", "plugins/router"], function (require, exports, router) {
"use strict";
var childRouter = router.createChildRouter()
.makeRelative({
moduleId: 'MainApp',
fromParent: false //<!----- FALSE for MainApp, TRUE for other SPA
})
.map([
{ route: '', moduleId: "viewmodels/test", nav: true },
])
.mapUnknownRoutes("viewmodels/err", 'err')
.buildNavigationModel();
return (function () {
function class_1() {
this.router = childRouter;
}
return class_1;
}());
});
App/MainApp/index.html - Uses the router, and performs any rendering of submenues or whatever. Here the bare minimum:
<div data-bind="router: { }"></div>
App/Admin/index.js
Is identical to the MainApp.js, except for the fromParent set to true and moduleId set to the SPAs name.
This should work fine in debug mode now.
The gulp setup becomes:
gulpfile.js
var durandal = require('gulp-durandal');
gulp.task('build', [], function () {
return gulp.start(['build-admin', 'build-signup', 'build-mainapp', 'build-base']);
});
function buildModule(name) {
var path = name + '/';
return durandal({
baseDir: 'App',
output: name + '.js',
minify: true,
almond: false,
verbose: false,
moduleFilter: function (moduleName) {
return moduleName.indexOf(path) > -1;
},
rjsConfigAdapter: function (config) {
config.stubModules = config.exclude;
config.exclude = ["main"];
config.stubModules.push('text');
return config;
}
})
.pipe(gulp.dest('dist'));
}
gulp.task('build-admin', [], function () {
return buildModule('Admin');
});
gulp.task('build-signup', [], function () {
return buildModule('Signup');
});
gulp.task('build-mainapp', [], function () {
return buildModule('MainApp');
});
gulp.task('build-base', [], function () {
return durandal({
baseDir: 'App',
output: 'main.js',
minify: true,
verbose: false,
moduleFilter: function (moduleName) {
return moduleName.indexOf('Admin/') === -1 && moduleName.indexOf('MainApp/') === -1 && moduleName.indexOf('Signup/') === -1;
},
rjsConfigAdapter: function (config) {
config.stubModules = config.exclude;
config.exclude = [];
return config;
}
})
.pipe(gulp.dest('dist'));
});
This will now result in
dist/main.js
dist/Admin.js
dist/MainApp.js
dist/Signup.js
In your default.html (or whatever you call it), you need to tell it how to load these files:
<script>window.require = {
bundles: { 'MainApp': ['MainApp/index'],'Signup': ['Signup/index'], 'Admin': ['Admin/index'] }
};</script>
<script type="text/javascript" data-main="main" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.2.0/require.min.js"></script>
The reason for this being in the html files rather than the main.js, is that the bundles are only used for the compiled version.
Is it possible to do the following in a grunt task?
grunt.registerTask('build', 'Building app', function () {
grunt.task.run([
'clean:dist',
'wiredep',
'useminPrepare',
'ngtemplates',
'concat:generated',
'ngAnnotate',
'copy:dist',
'cdnify',
'cssmin'
]);
// Replace "vendor-*.js" references to "vendor.js"
require('./custom_modules/changeref/changeref')(grunt, this.async, {
filePath: './dist/*.html',
find: /(vendor-).*\.js/ig,
replaceBy: 'vendor.js'
});
grunt.task.run([
'uglify',
'filerev',
'usemin',
'htmlmin'
]);
});
Basically, I require a node module with a function that load some .html files and replace some references inside them. The idea is to be able to do this between the two groups of tasks. I have tested it and it seems my custom function gets executed BEFORE the grunt tasks are run.
This is the changeref.js module:
'use strict';
var path = require('path');
module.exports = function(grunt, async, options) {
var files;
grunt.verbose.writeln('Checking options...');
options = options || {
filePath: options.filePath || './*.html',
find: options.find,
replaceBy: options.replaceBy || ''
};
if ( !options ) { throw new Error('options is undefined'); }
if ( !options.find ) { throw new Error('options.find is undefined'); }
grunt.verbose.writeflags(options, 'Running changeref with options: ');
files = grunt.file.expand({ filter: 'isFile' }, options.filePath);
files = files.map(function (fp) {
return { path: fp, body: grunt.file.read(fp) };
});
if ( files.length ) {
grunt.verbose.writeln('Your "filePath" pattern has found ' + files.length + ' file(s).');
} else {
grunt.verbose.warn('Not a single file was found.');
}
// File iteration
// files.forEach(function (file, index) {
grunt.util.async.forEach(files, function (file, cbInner) {
grunt.verbose.writeln('Processing ' + file.path + '...');
var fileContent,
strFound = function () {
var match;
// The find patter is a REGEXP
if ( typeof options.find === "object" ) { match = file.body.match(options.find); }
// The find pattern is a string
else { match = file.body.indexOf(options.find); }
if ( match && match.length ) {
return ((match.length !== 0) || (match !== -1));
}
return false;
};
if ( !strFound() ) {
grunt.verbose.warn("Your pattern hasn't match anything and the current file will remain untouched.");
return;
}
fileContent = file.body.replace(options.find, options.replaceBy);
grunt.verbose.writeln('Preparing to write file ' + file.path);
// Write the destination file.
grunt.file.write(file.path, fileContent);
cbInner();
}, async());
};
How can I follow the order described in my example?
Your issue is that grunt.task.run does NOT run the tasks, it just adds them to the stack of tasks to be executed once the current task is finished. So your code gets executed as part of the current task, and only then do all the other tasks run.
To achieve your goal, just turn your code into your own task (it's pretty painless) and just call them in sequence:
grunt.registerTask("yourReplace", function() {
// Replace "vendor-*.js" references to "vendor.js"
require('./custom_modules/changeref/changeref')(grunt, this.async, {
filePath: './dist/*.html',
find: /(vendor-).*\.js/ig,
replaceBy: 'vendor.js'
});
});
grunt.registerTask("build", ['clean:dist', 'cssmin', 'yourReplace', 'uglify']);
I'm getting ko is undefined error in knockout.simpleGrid 3.0 when using requirejs to load dependencies. Here is my require.config.js
var require = {
baseUrl: "/",
paths: {
"bootstrap": "Scripts/lib/bootstrap/bootstrap",
"crossroads": "Scripts/lib/crossroads/crossroads",
"jquery": "Scripts/lib/jquery/jquery-2.1.4",
"knockout": "Scripts/lib/knockout/knockout-3.3.0",
"koSimpleGrid": "Scripts/lib/knockout/knockout.simpleGrid.3.0",
"koProjections": "Scripts/lib/knockout/knockout-projections",
"signals": "Scripts/lib/crossroads/signals",
"hasher": "Scripts/lib/crossroads/hasher",
"text": "Scripts/lib/require/text"
},
shim: {
"bootstrap": { deps: ["jquery"] },
"koSimpleGrid": { deps: ["knockout"] }
}
}
here is the code which is causing the error.
ko.simpleGrid = {
// Defines a view model class you can use to populate a grid
viewModel: function (configuration) {
this.data = configuration.data;
this.currentPageIndex = ko.observable(0);
this.pageSize = configuration.pageSize || 5;
// If you don't specify columns configuration, we'll use scaffolding
this.columns = configuration.columns || getColumnsForScaffolding(ko.unwrap(this.data));
this.itemsOnCurrentPage = ko.computed(function () {
var startIndex = this.pageSize * this.currentPageIndex();
return ko.unwrap(this.data).slice(startIndex, startIndex + this.pageSize);
}, this);
this.maxPageIndex = ko.computed(function () {
return Math.ceil(ko.unwrap(this.data).length / this.pageSize) - 1;
}, this);
}
};
I tried passing the ko as parameter to knockout.simpleGrid but still it gives the same error on this line
this.currentPageIndex = ko.observable(0);
I'm following this tutorial on using angularjs alongside laravel: http://angular-tips.com/blog/2014/11/working-with-laravel-plus-angular-part-2/. However, if I define a route in config.routes.js which points to a controller, any controller, my app crashes. In the console the error "Error: too much recursion" comes up, along with a useless stack trace.
All my files are exactly the same as in the tutorial, I only changed the name of the route and the controller, but that shouldn't make a difference.
I googled around a bit and it seems this error might be caused by using a wrong version of jquery. I use angularjs 1.3.0 and I have no idea which jquery version my app is using, but I used npm install angular, so it'd be weird if that installed a wrong version, right?
I'm completely lost on why this happens and also very frustrated, so any help would be greatly appreciated.
Thanks.
EDIT: Added code:
app/js/config.routes.js
angular.module('app').config(function($routeProvider, $locationProvider)
{
$locationProvider.html5Mode(true).hashPrefix('!');
$routeProvider.when('/transactions',
{
templateUrl: 'features/transactions/transactions.tpl.html',
controller: 'Transactions'
});
});
app/js/transactions/transactions.js:
angular.module('app').controller('Transactions', function($scope, $http)
{
$http.get('/api/transactions').then(function(result)
{
$scope.shows = result.data;
});
});
transactions.tpl.html is empty.
app.js:
angular.module('app', ['ngRoute']);
EDIT 2: added gulp.js
The only thing I changed here is, is that I added the 'webserver' task.
var gulp = require('gulp');
var fs = require('fs');
var plugins = require('gulp-load-plugins')();
var es = require('event-stream');
var del = require('del');
var publicFolderPath = '../public';
var paths = {
appJavascript: ['app/js/app.js', 'app/js/**/*.js'],
appTemplates: 'app/js/**/*.tpl.html',
appMainSass: 'app/scss/main.scss',
appStyles: 'app/scss/**/*.scss',
appImages: 'app/images/**/*',
indexHtml: 'app/index.html',
vendorJavascript: ['vendor/js/angular.js', 'vendor/js/**/*.js'],
vendorCss: ['vendor/css/**/*.css'],
finalAppJsPath: '/js/app.js',
finalAppCssPath: '/css/app.css',
specFolder: ['spec/**/*_spec.js'],
publicFolder: publicFolderPath,
publicJavascript: publicFolderPath + '/js',
publicAppJs: publicFolderPath + '/js/app.js',
publicCss: publicFolderPath + '/css',
publicImages: publicFolderPath + '/images',
publicIndex: publicFolderPath + '/angular.html',
publicJsManifest: publicFolderPath + '/js/rev-manifest.json',
publicCssManifest: publicFolderPath + '/css/rev-manifest.json'
};
gulp.task('scripts-dev', function() {
return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
.pipe(plugins.if(/html$/, buildTemplates()))
.pipe(plugins.sourcemaps.init())
.pipe(plugins.concat('app.js'))
.pipe(plugins.sourcemaps.write('.'))
.pipe(gulp.dest(paths.publicJavascript));
});
gulp.task('scripts-prod', function() {
return gulp.src(paths.vendorJavascript.concat(paths.appJavascript, paths.appTemplates))
.pipe(plugins.if(/html$/, buildTemplates()))
.pipe(plugins.concat('app.js'))
.pipe(plugins.ngAnnotate())
.pipe(plugins.uglify())
.pipe(plugins.rev())
.pipe(gulp.dest(paths.publicJavascript))
.pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
.pipe(gulp.dest(paths.publicJavascript));
});
gulp.task('styles-dev', function() {
return gulp.src(paths.vendorCss.concat(paths.appMainSass))
.pipe(plugins.if(/scss$/, plugins.sass()))
.pipe(plugins.concat('app.css'))
.pipe(gulp.dest(paths.publicCss));
});
gulp.task('styles-prod', function() {
return gulp.src(paths.vendorCss.concat(paths.appMainSass))
.pipe(plugins.if(/scss$/, plugins.sass()))
.pipe(plugins.concat('app.css'))
.pipe(plugins.minifyCss())
.pipe(plugins.rev())
.pipe(gulp.dest(paths.publicCss))
.pipe(plugins.rev.manifest({path: 'rev-manifest.json'}))
.pipe(gulp.dest(paths.publicCss));
});
gulp.task('images', function() {
return gulp.src(paths.appImages)
.pipe(gulp.dest(paths.publicImages));
});
gulp.task('indexHtml-dev', ['scripts-dev', 'styles-dev'], function() {
var manifest = {
js: paths.finalAppJsPath,
css: paths.finalAppCssPath
};
return gulp.src(paths.indexHtml)
.pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
.pipe(plugins.rename(paths.publicIndex))
.pipe(gulp.dest(paths.publicFolder));
});
gulp.task('indexHtml-prod', ['scripts-prod', 'styles-prod'], function() {
var jsManifest = JSON.parse(fs.readFileSync(paths.publicJsManifest, 'utf8'));
var cssManifest = JSON.parse(fs.readFileSync(paths.publicCssManifest, 'utf8'));
var manifest = {
js: '/js/' + jsManifest['app.js'],
css: '/css/' + cssManifest['app.css']
};
return gulp.src(paths.indexHtml)
.pipe(plugins.template({css: manifest['css'], js: manifest['js']}))
.pipe(plugins.rename(paths.publicIndex))
.pipe(gulp.dest(paths.publicFolder));
});
gulp.task('lint', function() {
return gulp.src(paths.appJavascript.concat(paths.specFolder))
.pipe(plugins.jshint())
.pipe(plugins.jshint.reporter('jshint-stylish'));
});
gulp.task('testem', function() {
return gulp.src(['']) // We don't need files, that is managed on testem.json
.pipe(plugins.testem({
configFile: 'testem.json'
}));
});
gulp.task('clean', function(cb) {
del([paths.publicJavascript, paths.publicImages, paths.publicCss, paths.publicIndex], {force: true}, cb);
});
gulp.task('watch', ['indexHtml-dev', 'images'], function() {
gulp.watch(paths.appJavascript, ['lint', 'scripts-dev']);
gulp.watch(paths.appTemplates, ['scripts-dev']);
gulp.watch(paths.vendorJavascript, ['scripts-dev']);
gulp.watch(paths.appImages, ['images-dev']);
gulp.watch(paths.specFolder, ['lint']);
gulp.watch(paths.indexHtml, ['indexHtml-dev']);
gulp.watch(paths.appStyles, ['styles-dev']);
gulp.watch(paths.vendorCss, ['styles-dev']);
});
gulp.task('webserver', ['indexHtml-dev', 'images-dev'], function() {
plugins.connect.server({
root: paths.tmpFolder,
port: 5000,
livereload: true,
middleware: function(connect, o) {
return [ (function() {
var url = require('url');
var proxy = require('proxy-middleware');
var options = url.parse('http://localhost:8000/api');
options.route = '/api';
return proxy(options);
})(), historyApiFallback ];
}
});
});
gulp.task('default', ['watch']);
gulp.task('production', ['scripts-prod', 'styles-prod', 'images', 'indexHtml-prod']);
function buildTemplates() {
return es.pipeline(
plugins.minifyHtml({
empty: true,
spare: true,
quotes: true
}),
plugins.angularTemplatecache({
module: 'app'
})
);
}