前言
刚进入我司的时候我也是个啥都不懂得菜鸟,对于angularJs的印象也就是停留于他的指令,并且他的指令可以作为 标签使用,这样可以极大的减少代码量,【实习的时候曾和大牛短暂接触过,看了这段代码】。
我司的angularJs项目是分模块化的,在我刚进入公司的时候,我直接就可以新建模版引擎以及对应的controller、router、service方法,每一个js都可以被依赖注入,后期在深入的时候可以去写component、directive,这样一个好处是方便上手,可以在短时间内操作页面的更删改查,项目结构清晰,减少代码耦合;但同时也有它的弊端,那就是完全不知道一个项目是如何搭建起来的。现在我开始着手搭建一个新的项目,我就来记录一下我是如何将这个项目搭建起来的。
npm
1 dependencies以及devDependencies的区别
*dependencies 项目运行时所需要的文件
*devDependencies 开发时需要而线上运行时不需要的文件
1 npm中主要用到的cli
* npm init : 初始化package.json文件,有些有括号的则说明是默认有的,不填也可以
在这个里面有一个用法
"scripts": {
"buildpc": gulp,
"test": "echo 22222"
}
在cmd中执行时可以npm run test/buildpc,这样就可以去执行对应的程序。
* npm install/i --save:安装到dependencies
* npm install/i --save-dev:安装到devDependencies
* npm search :搜索npm模块,但是这个search速度很慢,可以在谷歌中搜索然后直接下载,在搜索的结果中也会有这个项目的git地址
2 我在这个项目中主要用到的devDependencies【按照它们的作用去划分】
del:
"del": //删除文件
css:
"gulp-sass": //编译为css
"gulp-clean-css": //压缩为min.css
"gulp-rename": //重命名
html:
"gulp-htmlmin": //压缩html
"gulp-flatten": //去掉文件夹层次,将他们提到同级目录下
js:
"jshint" + "gulp-jshint": //js语法检查,后者是依赖于前者的,
"gulp-concat": //合并js,
"gulp-uglify": //混淆js,合并到同一行,
"gulp-flatten": //重命名,改为.min.js,
others:
"browser-sync": //自动刷新浏览器,
"http-proxy-middleware": //中转站,将ajax请求转发到test域名,
gulp-others:【暂时未用】
"gulp-bower": "0.0.13",
"gulp-cdn-replace": "^0.3.0",
"gulp-filter": "^4.0.0",
"gulp-rev": "^7.1.2",
"gulp-rev-collector": "^1.0.5",
"gulp-useref": "^3.1.2",
bower
1 为什么要使用bower
便于查看项目依赖的文件以及版本号,同时也可以查看依赖文件本身所依赖的文件
2 常用的cli
* bower init : 初始化package.json文件,有些有括号的则说明是默认有的,不填也可以
* bower install/i --save:安装到dependencies
* bower install/i --save-dev:安装到devDependencies
* bower search :搜索bower模块,速度还行
* bower register :注册bower,release版本后才能bower install
* bower unregister :
3 angularJs项目中所需要用到的bower
"angular": "^1.5.8",//angularJs.min.js
"angular-ui-router": "^0.3.1",//ui-router
gulpfile
1 简单的小栗子
gulp.task('step1', function () {
console.log('This is step1');
});
gulp.task('step2', ['step1'], function () {
console.log('This is step2');
});
gulp.task('step3', [ 'step1', 'step2'], function () {
console.log('This is step3');
});
//[ 'step1', 'step2']这里的是并发执行
gulp.task('step4', function () {
return gulp.src([
'src/*.model.js',
'src/*.service.js'
])//这里的src会按照先后顺序去执行编译,而不是并发执行
.pipe(gulp.dest('dist'));//gulp.dest输出dist目录
});
2 在一个gulpfile中有多个项目去编译
var ENV_PC = 'pc';
var ENV_MOBILE = 'mobile';
var env = 'pc';
// pc
var pcPaths = {
app: 'apps/' + env,
libs: 'bower_components',
dist: 'dist/' + env,
filters: 'filters',
models: 'models',
services: 'services'
};
gulp.task('build:pc', ['clean'], function() {
env = ENV_PC;
gulp.start('step1');
});
gulp.task('build:mobile', ['clean'], function() {
env = ENV_MOBILE;
gulp.start('step1');
});
gulp.task('step1', function () {
console.log(111, env);
});
3 CLI
* gulp :默认执行default的task
* gulp <任务名>: 执行特定任务
4 项目中的gulpfile.js文件
'use strict';
var proxyHost = 'http://127.0.0.1:8000';//输入自己的测试地址
var cdnDomain = '';
var templateConfig = {
cdnPrefix: 'http://127.0.0.1:8000/'//输入自己的cdn地址
};
var htmlminConfig = {
collapseWhitespace: true
};
var gulp = require('gulp');
var jshint = require('gulp-jshint');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var flatten = require('gulp-flatten');
var filter = require('gulp-filter');
var htmlmin = require('gulp-htmlmin');
var cleanCSS = require('gulp-clean-css');
var del = require('del');
var sass = require('gulp-sass');
var rev = require('gulp-rev');
var revCollector = require('gulp-rev-collector');
var cdn = require('gulp-cdn-replace');
var browserSync = require('browser-sync').create();
var proxyMiddleware = require('http-proxy-middleware');
var proxy = proxyMiddleware('/ajax', {
target: proxyHost,
changeOrigin: true,
pathRewrite: {
'^/ajax': ''
}
});
const ENVIRONMENT = {
PC: 'pc',
MOBILE: 'mobile'
}
var path = {};
function initEnvironment(env) {
path = {
app: 'apps/' + env,
libs: 'bower_components',
dist: 'dist/' + env,
filters: 'filters',
models: 'models',
services: 'services'
};
}
gulp.task('watch', ['build'], function() {
gulp.watch(path.libs + '/**/*', ['build:vendor']);
gulp.watch([
path.app + '/scss/*.scss'
], ['build:css']);
gulp.watch([
path.app + '/components/*.component.js',
path.app + '/components/*.controller.js',
path.app + '/directives/*.directive.js',
path.app + '/pages/*.controller.js',
path.app + '/pages/*.router.js',
path.app + '/pages/*.js',
path.filters + '/*.filter.js',
path.models + '/*.model.js',
path.services + '/*.service.js'
], ['build:js']);
//gulp.watch(path.assets + '/fonts/*', ['build:fonts']);
gulp.watch(path.app + '/images/*', ['build:images']);
gulp.watch(path.app + '/**/*.html', ['build:html']);
});
gulp.task('lint', function() {
return gulp.src([
path.app + '/components/*.component.js',
path.app + '/components/*.controller.js',
path.app + '/directives/*.directive.js',
path.app + '/pages/*.controller.js',
path.app + '/pages/*.router.js',
path.app + '/pages/*.js',
path.filters + '/*.filter.js',
path.models + '/*.model.js',
path.services + '/*.service.js'
])
.pipe(jshint())
.pipe(jshint.reporter('default'));
});
gulp.task('build', [
'build:js',
'build:css',
//'build:fonts',
'build:images',
'build:vendor',
'build:html',
'build:others'
]);
// css task
gulp.task('build:css', function() {
return gulp.src([
path.app + '/scss/*.scss'
])
.pipe(concat('turnado.css'))
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest(path.dist + '/assets/css'))
.pipe(cleanCSS())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(path.dist + '/assets/css'))
});
// vendor task
gulp.task('build:vendor', function() {
return gulp.src(path.libs + '/**/*')
.pipe(gulp.dest(path.dist + '/vendor'));
});
//js task
gulp.task('build:js', ['lint'], function() {
return gulp.src([
path.app + '/components/*.component.js',
path.app + '/components/*.controller.js',
path.app + '/directives/*.directive.js',
path.app + '/pages/*.controller.js',
path.app + '/pages/*.router.js',
path.app + '/pages/*.js',
path.filters + '/*.filter.js',
path.models + '/*.model.js',
path.services + '/*.service.js'
])
.pipe(concat('turnado.js'))
.pipe(gulp.dest(path.dist + '/assets/js/'))
.pipe(uglify())
.pipe(rename({suffix: '.min'}))
.pipe(gulp.dest(path.dist + '/assets/js/'));
});
//html task
//html index task
gulp.task('build:html:index', function() {
return gulp.src([
path.app + '/pages/index.html'
])
.pipe(cdn({
dir: path.dist,
root: {
js: cdnDomain,
css: cdnDomain
}
}))
.pipe(gulp.dest(path.dist));
});
//html views task
gulp.task('build:html:views', function() {
return gulp.src([
path.app + '/pages/*/*.html'
])
.pipe(flatten())
.pipe(cdn({
dir: path.dist,
root: {
js: cdnDomain,
css: cdnDomain
}
}))
.pipe(gulp.dest(path.dist + '/views'));
});
//html shared task
gulp.task('build:html:shared', function() {
return gulp.src([
path.app + '/shared/*.html'
])
.pipe(flatten())
.pipe(cdn({
dir: path.dist,
root: {
js: cdnDomain,
css: cdnDomain
}
}))
.pipe(gulp.dest(path.dist + '/views/shared'));
});
// components task
gulp.task('build:html:components', function() {
return gulp.src([
path.app + '/components/**/*.html'
])
.pipe(flatten())
.pipe(cdn({
dir: path.dist,
root: {
js: cdnDomain,
css: cdnDomain
}
}))
.pipe(gulp.dest(path.dist + '/views/components'));
});
gulp.task('build:html', [
'build:html:index',
'build:html:views',
'build:html:shared',
'build:html:components'
]);
// images task
gulp.task('build:images', function() {
return gulp.src([
path.app + '/images/**/*'
])
.pipe(gulp.dest(path.dist + '/assets/images'));
});
gulp.task('build:others', function() {
return gulp.src([
'robots.txt',
'baidu_verify_*.html',
'.htaccess'
])
.pipe(gulp.dest(path.dist));
});
gulp.task('debug', ['watch'], function () {
browserSync.init({
startPath: '/',
server: {
baseDir: path.dist
},
//browser: 'google chrome',
middleware: [proxy]
});
gulp.watch(path.dist + '/**/*').on('change', browserSync.reload);
});
gulp.task('clean', function () {
return del(path.dist);
});
gulp.task('default', ['clean'], function() {
gulp.start('build:pc');
gulp.start('build:mobile');
});
gulp.task('build-pc', ['clean'], function() {
initEnvironment(ENVIRONMENT.PC);
gulp.start('build');
});
gulp.task('build-mobile', ['clean'], function() {
initEnvironment(ENVIRONMENT.MOBILE);
gulp.start('build');
});
gulp.task('debug-pc', ['clean'], function() {
initEnvironment(ENVIRONMENT.PC);
gulp.start('debug');
});
gulp.task('debug-mobile', ['clean'], function() {
initEnvironment(ENVIRONMENT.MOBILE);
gulp.start('debug');
});
index.html
引入需要用的js、css文件
index.js
(function() {
angular.module('mall', [
'ui.router',
'angular-carousel'
])
.constant('xx', {
xx: 2,
xx: 1
})//定义常量,减少硬编码
angular.module('admin.services', []);//处理业务逻辑
angular.module('admin.models', []);//底层ajax请求
angular.module('admin.directives', []);//指令,处理dom操作
angular.module('admin.components', []);//组件
angular.module('admin.filters', []);//过滤器
})();
angular
.module('mall')
.controller('MainCtrl', MainCtrl)
.config(mainConfig)
.run(mainRun);
MainCtrl.$inject = ['$rootScope', '$scope'];
function MainCtrl($rootScope, $scope) {
var vm = this;
}
mainConfig.$inject = ['$urlRouterProvider', '$locationProvider'];
function mainConfig($urlRouterProvider, $locationProvider) {
$locationProvider.hashPrefix('!');
$locationProvider.html5Mode(false);
$urlRouterProvider.otherwise("/home");//定义入口文件
}
mainRun.$inject = ['$rootScope', '$state'];
function mainRun($rootScope, $state) {
$rootScope.$state = $state;
}
组件,作为标签元素使用,directive的一种,将需要依赖于scope的directive写成组件是有好处的
第一是使项目中的directive更有独立性
第二是可以避免directive文件在controller加载完成之前就compile,这样directive中的scope依赖的变量成为局部变量