I am doing an front-end application using :
RequireJs
BackboneJs
Handlebars
To compile my template html to js for handlebars i used Grunt, and with those lines in the gruntfile.js
handlebars: {
compile: {
options: {
processName: function (fileName) {
return path.basename(fileName, '.handlebars');
},
namespace: "Handlebars.templates",
amd: true
},
files: {
'src/templates/compiled/example.js':'src/templates/raw/example.handlebars'
}
It work well, because in my example.js I have this first line :
define(['handlebars'], function(Handlebars) {
It seems like this line appear because of the amd: true, because if I remove, it does not work.
But the problem is, in Gulp how do I add this define on the compiled project ?
This link explains that.
Usage
1. Install development dependencies:
npm install --save-dev gulp-handlebars gulp-define-module
2. Add the require() statements and template task to your gulpfile
var gulp = require('gulp');
var defineModule = require('gulp-define-module');
var handlebars = require('gulp-handlebars');
gulp.task('templates', function() {
// Load templates from the templates/ folder relative to where gulp was executed
gulp.src('source/templates/**/*.hbs')
// Compile each Handlebars template source file to a template function
.pipe(handlebars())
// Define templates as AMD modules
.pipe(defineModule('amd'))
// Write the output into the templates folder
.pipe(gulp.dest('build/js/templates/'));
});
Related
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)))
}
I am facing below issue -
I have Yeomen generator and wiredep to inject bower dependencies in index.html file.
I have installed angular tree view by bower then noticed that lib files and css file of angular tree view are not getting injected in index file.
After debugging for while found that the lib file of angular tree view has one extras dot (angular.treeview.js) same with the css file as well
So how to inject that file in index.html
i have below task in inject.js file in gulp folder to inject file in index.html which is generated by yoemen
gulp.task('inject', ['scripts'], function () {
var injectStyles = gulp.src([
path.join(conf.paths.src, '/app/**/*.css')
], { read: false });
var injectScripts = gulp.src([
path.join(conf.paths.src, '/app/**/*.module.js'),
path.join(conf.paths.src, '/app/**/*.js'),
path.join('!' + conf.paths.src, '/app/**/*.spec.js'),
path.join('!' + conf.paths.src, '/app/**/*.mock.js')
])
.pipe($.angularFilesort()).on('error',conf.errorHandler('AngularFilesort'));
var injectOptions = {
ignorePath: [conf.paths.src, path.join(conf.paths.tmp, '/serve')],
addRootSlash: false
};
return gulp.src(path.join(conf.paths.src, '/*.html'))
.pipe($.inject(injectStyles, injectOptions))
.pipe($.inject(injectScripts, injectOptions))
.pipe(wiredep(_.extend({}, conf.wiredep)))
.pipe(gulp.dest(path.join(conf.paths.tmp, '/serve')));
}
I am using Yeomen and gulp.
Any help would be appreciated.
It doesn't have to do anything with your gulp task.
Wiredep uses bower.json file to inject dependency in your index file.
I case of any issue, like in your current scenario you just need to override your package, like you do for bootstrap.
add below code in bower.json
"overrides": {
"bootstrap": {
"main": [
"dist/css/bootstrap.css",
"dist/fonts/glyphicons-halflings-regular.eot",
"dist/fonts/glyphicons-halflings-regular.svg",
"dist/fonts/glyphicons-halflings-regular.ttf",
"dist/fonts/glyphicons-halflings-regular.woff",
"dist/fonts/glyphicons-halflings-regular.woff2"
]
},
"angular-treeview":{
"main":[
"angular.treeview.js",
"css/angular.treeview.css"
]
}
}
I hope it will help you.
Happy coding :)
So my AngularJS code looks like this:
define(['angular', 'text!./template.html'], function (angular, template) {
'use strict';
return angular.module('app.widget', [])
.directive('MyWidget', function(){
//.... use the template here
})
I'm using the text plugin for RequireJS to get the html template and use in in the AngularJS directive.
I want to use webpack and it's reading the AMD style code ok but it can't work with the text plugin.
Does anyone know how to get the text-loader for webpack to work with requirejs?
There are some solutions out there and a discussion thread but I can't get them to work.
In my webpack.config.js I've got
loaders: [
{ test: /^text\!/, loader: "text" }
]
Thanks
Actually you need dont need to specify node modules path. It works if you specify just the name of the actual loader like below
resolveLoader: {
alias: { "text": "text-loader" }
},
You need to install raw-loader, which is the webpack equivalent for loading raw files
npm i raw-loader
Then you need to alias the requireJS style with the raw-loader (resolveLoader is to be put in the root of the webpack config object)
resolveLoader: {
alias: {
'text': {
test: /\.html$/,
loader: "raw-loader"
},
}
}
Check this SO question: Webpack loader aliases?
A similar solution which worked for me with Webpack 2.2:
resolveLoader: {
alias: {
// Support for require('text!file.json').
'text': 'full/path/to/node_modules/text-loader'
}
}
And install text-loader:
npm install text-loader
I'm trying to setup an angularjs project according to Johnpapa's Angular Style Guide whilst using TypeScript and Gulp as a build tool. I believe Gulp is currently recommended over Grunt but I'm not very experienced with Gulp.
What I have:
My project currently looks like this:
src/
+- ts/ # contains .ts source files
+- typings/ # contains .d.ts typing definitions
+- html/ # contains .html files
dist/
+- bundle.js # single .js file containing compiled typescript and sourcemaps
Following the angular style guide I have created a separate .ts file for each angular element.
my-app.module.ts
----------------
angular.module('myApp', []);
for initialization of the module and another for a simple implementation of a controller:
my-controller.controller.ts
----------------------------
export class MyController {
testString = 'test';
}
angular
.module('myApp')
.controller('MyController', MyController);
typescript is configured using a simple tsconfig.json. (Note that filesGlob is not active yet - it will become available from TypeScript 2.0)
tsconfig.json
-------------
{
"exclude" : [
"node_modules"
],
"filesGlob" : [
"./src/typings/index.d.ts",
"./src/ts/**/*.ts",
"!./node_modules/**/*.ts"
],
"compilerOptions": {
"noImplicitAny": true,
"target": "es5",
"sourceMap" : true,
"outFile" : "./dist/bundle.js",
"removeComments": false
}
}
What I want:
I would ideally like to
Have Gulp monitor new or updated .ts files in ./src/ts/**/*.ts
Concatenate all the files from ./src/ts/**/*.ts. This is required for angular to work properly. Other methods I've tried using requirejs or browserify can't find the other .ts files without having to manually input references to these files.
Compile using the definitions from tsconfig.json. This would take into consideration the typings in ./src/typings/index.d.ts (for external modules including 'angular'). Also sourcemaps.
Possibly an uglify or babelify step to finish it.
What I tried:
I've tried following the manual from the typescriptlang handbook but this uses browserify and won't work with angular.
Gulp-typescript also has a note on concatenating files but the out option doesn't work like this:
var gulp = require('gulp');
var ts = require('gulp-typescript');
var tsProject = ts.createProject('tsconfig.json');
gulp.task('default', function () {
var tsResult = tsProject.src().pipe(ts(tsProject));
return tsResult.js.pipe(gulp.dest('dist'));
});
This configuration will output an empty file with only comments.
Another method mentioned in this question:
gulp.task('ts', function () {
gulp.src('./src/ts/**/*.ts')
.pipe(ts({
noImplicitAny: true,
out: 'output.js'
}))
.pipe(gulp.dest('./tmp/ts'));
});
gulp.task('default', ['ts'], function() {
gulp.src(['./tmp/ts/output.js'])
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(sourcemaps.write('/'))
.pipe(gulp.dest('./dist/'));
});
But this gave two issues: 1. Even though I only pointed at the .ts files in ./src/ts the typescript compiler started spewing errors from .ts in ./node_modules. 2. It still didn't manage to concatenate everything.
I'm at quite a loss here. Can anyone help me set up this build script? I'm surprised I couldn't find a similar working demo anywhere.
Solution:
I've configured the gulp environment based on the solution in this answer and removed the 'export' statement for classes / objects that are not inside a typescript module.
If that helps, here is a Angular Typescript Gulp Tutorial that has a basic TypeScript, Angular, Gulp, etc. setup that concatenate the app and the vendor/nodes files. There is the demo code on github.
/* File: gulpfile.js */
// grab our gulp packages
var gulp = require('gulp');
// Include plugins
var plugins = require("gulp-load-plugins")({
pattern: ['gulp-*', 'gulp.*', 'main-bower-files', 'del'],
replaceString: /\bgulp[\-.]/
});
var browserSync = require('browser-sync').create();
var reload = browserSync.reload;
// create a default task to build the app
gulp.task('default', ['jade', 'typescript', 'bowerjs', 'bowercss', 'appcss'], function() {
return plugins.util.log('App is built!')
});
In my example, we use Jade to HTML:
// Jade to HTML
gulp.task('jade', function() {
return gulp.src('src/**/*.jade')
.pipe(plugins.jade()) // pip to jade plugin
.pipe(gulp.dest('dist')) // tell gulp our output folder
.pipe(reload({stream: true}))
;
});
For TypeScript, we compiled into one single app.js file:
// TYPESCRIPT to JavaScript
gulp.task('typescript', function () {
return gulp.src('src/**/*.ts')
.pipe(plugins.typescript({
noImplicitAny: true,
out: 'app.js'
}))
.pipe(gulp.dest('dist/js/'))
.pipe(reload({stream: true}))
;
});
For bower, we merge all the js files in vendor.js and CSS in vendor.css:
// BOWER
gulp.task('bowerjs', function() {
gulp.src(plugins.mainBowerFiles())
.pipe(plugins.filter('**/*.js'))
.pipe(plugins.debug())
.pipe(plugins.concat('vendor.js'))
.pipe(plugins.uglify())
.pipe(gulp.dest('dist/js'));
});
gulp.task('bowercss', function() {
gulp.src(plugins.mainBowerFiles())
.pipe(plugins.filter('**/*.css'))
.pipe(plugins.debug())
.pipe(plugins.concat('vendor.css'))
.pipe(gulp.dest('dist/css'));
});
Custom CSS:
// APP css
gulp.task('appcss', function () {
return gulp.src('src/css/**/*.css')
.pipe(gulp.dest('dist/css/'))
.pipe(reload({
stream: true
}));
});
// CLEAN
gulp.task('clean', function(done) {
var delconfig = [].concat(
'dist',
'.tmp/js'
);
// force: clean files outside current directory
plugins.del(delconfig, {
force: true
}, done);
});
This is what reloads the browser when changes occur:
// Watch scss AND html files, doing different things with each.
gulp.task('serve', ['default'], function () {
// Serve files from the root of this project
browserSync.init({
server: {
baseDir: "./dist/"
}
});
gulp.watch("src/**/*.jade", ['jade']).on("change", reload);
gulp.watch("src/**/*.ts", ['typescript']).on("change", reload);
gulp.watch("src/**/*.css", ['appcss']).on("change", reload);
});
My tsconfig.json looks like this... I put the JS files that are automatically compiled from the text editor (Atom) into .tmp/js/atom ... some people put the .js in the same directory as the .ts but I find it confusing... less files is better for me:
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"outDir": ".tmp/js/atom"
},
"exclude": [
"node_modules",
"typings"
]
}
I am setting up an angular project with browserify.
I have a gulp task that take all vendor modules from bower_components directory and put them in a bundle:
gulp.task('dependencies', function () {
return browserify({
entries: [dependencies.js],
})
.transform(debowerify)
.bundle()
.pipe(source(config.filenames.release.dep))
//.pipe(streamify(uglify()))
.pipe(gulpif(release,
gulp.dest(config.paths.dest.release.scripts),
gulp.dest(config.paths.dest.build.scripts)));
The dependencies.js file contains this code:
'use strict';
// bower dependencies (can be edited in package.json)
var angular = require('angular');
require('angular-ui-router');
Everything works fine. Now I try to change the ui-router with angular-new-router.
My new dependencies.js (My gulp task doesn't change):
'use strict';
// bower dependencies (can be edited in package.json)
var angular = require('angular');
require('angular-new-router');
And for information here's my bower.json file:
{
"name": "test",
"private": true,
"dependencies": {
"angular": "~1.4.x",
"angular-new-router": "*",
"angular-ui-router": "*"
}
}
With this new config browserify return a weird error:
: Cannot find module
'./....\bower_components\angular-new-router\angular-new-router.js'
from
'D:\Devs\sharefun\WebApplication2\src\WebApplication2\client\modules'
at D:\Devs\sharefun\WebApplication2\src\WebApplication2\node_modules\browserify\node_modules\resolve\lib\async.js:55:21
at load (D:\Devs\sharefun\WebApplication2\src\WebApplication2\node_modules\browserify\node_modules\resolve\lib\async.js:69:43)
at onex (D:\Devs\sharefun\WebApplication2\src\WebApplication2\node_modules\browserify\node_modules\resolve\lib\async.js:92:31)
at D:\Devs\sharefun\WebApplication2\src\WebApplication2\node_modules\browserify\node_modules\resolve\lib\async.js:22:47
at Object.oncomplete (fs.js:107:15)
What I find weird is that browserify is looking for bower_components\angular-new-router\angular-new-router.js instead of bower_components\angular-new-router\index.js
you kind of have the answer, specify full path to index.js. try
require(angular-new-router/index.js);
or
import 'angular-new-router/index.js'; for ES6
to anyone who is having this problem now it might be useful to know that new router package is not updated anymore but you can get it from angular project.
the latest example working with angular 1.5, components() and child routes can be found here:
http://plnkr.co/edit/N3YP3dKMuljpZ6mWsVBT?p=preview