本文是2016.01.01的新年礼物。
本文并非javascript、node、bower、grunt、gulp、systemjs等等技术的入门文档,阅读本文需要你对上述知识有比较系统的了解,最好有实战经验。可以先参考如下文章:
个人最近比较侧重基于javascript的大前端,感叹技术发展的日新月异。当前我自己的架构库中已将上文提到的npm+bower+grunt的方式都标记为deprecated。尤其是bower,在使用最新的javascript库时,你就会发现其非常的out了,当前我的构建方案已经全部升级为npm+gulp的方式,bower+grunt只保留极少构建部分过渡使用。
项目构建升级更新
回顾一下之前我对npm+bower+grunt的白话文定义:
名称 | 描述 |
---|---|
npm | bower和grunt运行的基础环境,如同jvm与java应用程序的关系 |
bower | SPA项目用到的组件,如jquery,d3等等 |
grunt | 可编程的自动化构建工具 |
上述表中,其时npm和bower是有很多功能重叠的,npm同样可以做到bower能做到的事,但是现在明显感受到bower在支持上的落后,故将其淘汰,由npm完成所有的组件管理。同时,用gulp替代grunt完成项目自动构建。
新的定义
名称 | 描述 |
---|---|
npm | gulp运行的基础环境,如同jvm与java应用程序的关系;SPA项目用到的组件,如jquery,d3等等 |
gulp | 可编程的自动化构建工具 |
bower和grunt只在遗留项目中继续使用,标记为deprecated。
目录结构
- app
- node_modules
- gulefile.js
- package.json
- tsconfig.json
说明:
名称 | 类型 | 描述 |
---|---|---|
app | dir | spa应用源码目录 |
node_modules | dir | node库文件 |
gulefile.js | js file | 当前项目的gulp构建代码 |
package.json | json file | 当前项目的npm 配置文件 |
tsconfig.json | json file | typescript编译使用的配置文件 |
gulefile.js和tsconfig.json是相对于javascript 前端 基于 npm、bower、grunt的标准项目构建 中的方案新增的内容,下面会在相应的技术组成部分给出例子。
技术组成
关于gulp
说明
Gulp是一个基于npm的构建系统,它能通过自动执行常见任务,比如编译预处理CSS,压缩JavaScript和刷新浏览器,来改进网站开发的过程。通过本门课程的学习,我们将知道如何使用Gulp来改变开发流程,从而使开发更加快速高效,其作用与grunt非常相似。
我觉得其最大的特点是:
- 基于stream方式处理,不用再像使用grunt时各种temp目录横飞
- 代码大于配置(code over configuration),这是口号,主要功能都是基于代码的,但其实还是可以使用配置文件
一句话概括:gulp就是用来替代grunt的!!
安装
(安装指令略,熟悉npm只需在package.json加入对应内容即可)
直接在npm的package.json中加入下面的内容即可:
"devDependencies": {
"gulp": "^3.9.0",
"gulp-concat": "^2.6.0",
"gulp-copy-rex": "^1.2.5",
"gulp-cssnano": "^2.0.0",
"gulp-grunt": "^0.5.3",
"gulp-htmlmin": "^1.3.0",
"gulp-if": "^2.0.0",
"gulp-ignore": "^2.0.1",
"gulp-minify-html": "^1.0.5",
"gulp-processhtml": "^1.1.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
"gulp-rimraf": "^0.2.0",
"gulp-uglify": "^1.5.1",
}
gulpfile.js
var gulp = require("gulp"),
gulpif = require('gulp-if'), //提供条件判断
gulpIgnore = require('gulp-ignore'), //根据条件忽略部分内容
//minifycss = require('gulp-minify-css'), //CSS压缩
cssnano=require('gulp-cssnano'), //CSS压缩 代替minifycss
//htmlmin=require('gulp-htmlmin'),//压缩html,原本是用来替代gulp-minify-html,但发现其存在问题
minifyHtml = require("gulp-minify-html"),//压缩html
concat = require('gulp-concat'), // 文件合并
uglify = require('gulp-uglify'), //js压缩插件
rename = require('gulp-rename'), // 重命名
replace = require('gulp-replace'), //对指定文件进行内容替换
processhtml=require('gulp-processhtml'), //对html中的内容进行处理
copy=require('gulp-copy-rex'),
rimraf=require('gulp-rimraf');//清理目录,用来替代gulp-clean
require('gulp-grunt')(gulp); // add all the gruntfile tasks to gulp
var outputDir='dist';//输出目录
var appConfig = {
app: require('./package.json').appPath || 'app',
dist: 'dist',
processConfig: {
js: {
compress: false,
concat: false
},
html: {
compress: false,
concat: false
},
css: {
compress: false,
concat: false
}
},
getSrcDir:function(src){
return this.app+src;
}
};
gulp.task('clean', function(cb) {//这里使用了并行任务等待
//del(['minified/css', 'minified/js'], cb);
rimraf(appConfig.dist, cb);
cb();//任务执行结束
});
gulp.task('process-css', function() {
return gulp.src(appConfig.getSrcDir('/**/*.css')) //压缩的文件
.pipe(gulpif(appConfig.processConfig.css.concat,concat("app.css")))
.pipe(gulpif(appConfig.processConfig.css.compress, cssnano())) //压缩
.pipe(gulp.dest(appConfig.dist)); //输出文件夹
});
gulp.task('process-html', function () {
var processhtml_opts = { /* plugin options */ };
var process_condition = function (file) {
// TODO: add business logic
return true;
}
gulp.src(appConfig.getSrcDir('/**/*.html')) // 要压缩的html文件
.pipe(gulpif(appConfig.processConfig.html.compress, minifyHtml())) //压缩
.pipe(processhtml(processhtml_opts))
//.pipe(gulpif(process_condition, uglify(), beautify()))
.pipe(gulp.dest(appConfig.dist));
});
gulp.task("process-js",function(){
return gulp.src([appConfig.getSrcDir("/**/*.js")])
.pipe(gulpif(appConfig.processConfig.js.concat,concat("app.js")))
.pipe(gulpif(appConfig.processConfig.js.compress, uglify()))
.pipe(gulp.dest(appConfig.dist));
});
gulp.task('grunt-all',['grunt-for-gulp']);//调用grunt中的任务,详见Gurntfile.js
gulp.task("default",["clean"],function(){
gulp.start('copy','process-css', 'process-js','process-html'); // 要执行的任务
});
gulp.task('copy', function () {
var files = {
css_files: {
source: [
'./bower_components/bootstrap/dist/css/bootstrap.min.css'
],
dist: appConfig.dist+'/styles',
opts:null
},
font_files: {
source: ['./bower_components/bootstrap/dist/fonts/*.*'],
dist: appConfig.dist+'/fonts',
opts:null
},
bootstrap_js_files:{
source: ['./bower_components/bootstrap/dist/js/bootstrap.min.js'],
dist: appConfig.dist+'/lib/bootstrap',
opts:null
},
jquery_js_files:{
source: ['./bower_components/jquery/dist/jquery.min.js'],
dist: appConfig.dist+'/lib/jquery',
opts:null
},
angular2_js_files:{
source: ['./node_modules/angular2/**/*.js'],
dist: appConfig.dist+'/lib/angular2',
opts:null
}
};
for (var item in files){
copy(files[item].source,files[item].dist,files[item].opts);
}
});
关于TypeScript
说明
TypeScript是微软近年提供的非常给力的“语法“(我没将其认为是语言,其号称为javascript的超集,其代码最终都可以通过编译器翻译成javascript),总会提前提供es的最新特性(包括还没诞生的es7)。对于我来说,则认为其完全颠覆了以往微软给人的印象,这里我感受到了“开源的微软“,赞一个。
安装
- 一定要注意node typescript 的版本,最好安装最新的,至少满足>=1.7,现在已经有1.8了
npm i -g typescript@next //安装最新的typescript
tsc --version //查看typescript版本
npm install tsd -g //tsd格式的描述信息方便开发工具进行智能提示
tsd install jquery angular --save //tsd安装范例
//同时候TSD工具还会为我们在typing目录下生产一个tsd.d.ts文件,它会为我们引入这些模板文件,使得IDE能够识别出这样模板文件:
tsconfig.json
{
"compilerOptions": {
"target": "ES5", //编译为es5的代码
"module": "system",//模块化方式,还有commonjs,amd等
"moduleResolution": "node",//使用node处理
"sourceMap": false,//是否生成sourcemap文件
"emitDecoratorMetadata": true,
"experimentalDecorators": true,//开启装饰器,好像es7才会正式提供,这里可以提前尝试,强烈建议使用
"removeComments": false,//编译后的代码中移除注释
"noImplicitAny": false
},
"exclude": [//排除有下面的目录
"node_modules",
"bower_components"
]
}
Lamda
参数列表 => 语句或语句块
其中“参数列”中可包含任意个参数(与委托对应),如果参数列中有0个或1个以上参数,则必须使用括号括住参数列,如下:
() => Console.Write("0个参数")
i => Console.Write("1个参数时参数列中可省略括号,值为:{0}",i)
(x,y) => Console.Write("包含2个参数,值为:{0}*{1}",x,y)
而“语句或语句块”中如果只有一条语句,则可以不用大括号括住否则必须使用,如下:
i => Console.Write("只有一条语句")
i => { Console.Write("使用大括号的表达式"); }
//两条语句时必须要大括号
i => { i++;Console.Write("两条语句的情况"); }
关于systemjs
说明:
systemjs 是一个最小系统加载工具,用来创建插件来处理可替代的场景加载过程,包括加载 CSS 场景和图片,主要运行在浏览器和 NodeJS 中。它是 ES6 浏览器加载程序的的扩展,将应用在本地浏览器中。通常创建的插件名称是模块本身,要是没有特意指定用途,则默认插件名是模块的扩展名称。
个人理解:systemjs于commonjs、requirejs等等都是为了实现javascript项目的模块化,也是当前的新技术,所以也把它放在这里,后续angular2等等会用到systemjs。
安装
npm install systemjs --save
构建部分并不用到systemjs,所以该部分内容暂时忽略,编写中的anguliar2实战手册会对其进行具体介绍。
其他注意事项
关于WebStorm
- webstorm 10配置TypeScript,在Languages & Frameworks > TypeScript中设置 command option: -m amd -t ES5
- webstorm 10的版本tsc默认还在1.4,需要手动修改,
- 建议升级webstorm到最新版本11以上,不然其对typescript和angular的支持始终比较蛋疼