AngularJS + CoffeeScript 前端开发环境配置详解
栏目: CoffeeScript · 发布时间: 7年前
内容简介:AngularJS + CoffeeScript 前端开发环境配置详解
AngularJS 号称 '第一框架' ('The first framework') 确实是名不虚传。由其从jQuery中完全转入AngularJS后就有无法离开他的感觉了。虽然AngularJS的学习曲线很陡峭,入门的门槛相比较高,但这些付出都是值得的相信用过的朋友都会与我有同感吧。为何我如此
地偏爱AngularJS? 或者这样说吧,用AngularJS开发的话其实是给我了一种工业化开发的概念,我对软件工业化的浅显理解简单归结为几点就是:
- 自动化
- 智能化
- 注重质量
- 注重工艺
前端开发比后端开发要求开发人员做更多繁杂的事,例如:js和css 的压缩、依赖引入、更新,图片压缩、“糖果语言(coffeescript/less/sass)”的语法检查与编译、静态图片/静态网页压缩,单元测试、E2E测试、等等。这些锁事往往很耗时间。
再者,当引入AngularJS作为主前端框架的话,大量的js源文件管理对文件结构与模块结构合理规划就显得更为之重要。所幸的是,google 是AngularJS工业化的主力推手,为了增加前端开发人员的生产力他们也不遗余力地做了很多工作,,他能快速地为我们建立各种类型项目的脚手架(项目模板),以他们的“最佳实践”为基础快速地为我们完成这一系列繁琐的工作。
我在实际项目开发觉得官方提供的 angular 生成器并不是十分合用,在经历了好几个项目的磨合后我在 google 官方的 yeoman angular 脚手架项目上进行了一些定制与修改,也在此作一些分享,由于时间关系还没有去将其成一个generator 所以只能在此以博文方式共享了。
如果对Yeoman不了解也不用要,本文将会独立于yeoman 一步一步详细地解释如何部署一个可以用于生产AngularJS前端开发环境。
工具
以下这些可谓是前端开发必备了,如果不清楚具体用法那么就先请去他们的官网先脑补吧:
npm
Node的依赖包管理工具,可以到 [nodejs 官方下载| http://nodejs.org/download/ ]页面获取安装包。
** bower **
bower 是由twitter开发的客户端依赖包管理工具
npm install -g bower
** grunt **
自动化任务管理工具,是整个自动化工程的核心。
npm install -g grunt-cli
安装此三大 工具 后我们就可以着手开始了。
实现的目标功能
- 基于 CoffeeScript并支持自动编译
- 能支持 livereload(一但任何代码、资源发生更改浏览器会自动刷新)
- 自动编译 less
- 支持 ngdocs 从 CoffeeScript 自动提取注释生成 API文档网站
- 自动 连接、最小化靜态资源,包括:脚本、图片、网页
- 自动将bower引入的依赖包注入页面
- 配备 Karma 的单元测试
- 配备基于 protractor 的e2e测试
基本目录结构
以下是基本项目目录的构成以及每个目录的功能说明
项目目录/
├── app // 应用程序目录
│ ├── bower_components // bower 组件目录 (由 bower 生成)
│ ├── fonts // 字体
│ ├── images // 图片资源
│ ├── styles // 样式目录 可存放 .css 和 .less
│ └── scripts // 应用程序脚本
│ └── app.coffee // angularJS 应用程序文件
│ └── index.html // HTML HOME 文件
├── dist // 发布后的程序目录
├── test // 测试程序目录
│ ├── mocks // 存放mocks组件文件目录
│ ├── e2e // e2e测试文件目录
│ └── spec // 单元测试文件目录
├── node_modules // NodeJS 的组件目录 (由 npm 生成)
├── docs // 存放生成文档
├── .tmp // 临时文件目录 (由 grunt 任务自动生成)
├── .bowerrc // bower 路径规则指定文件
├── conffeelint.json // CoffeeScript 语法检查规则
├── Gruntfile.js // grunt 配置文件
├── karma.conf.js // karma 配置文件
├── protractor.conf.js // protractor 配置文件
├── package.json // nodes 依赖包描述文件
└── bower.json // bower 依赖包描述文件
流程及原理
此项目环境主要提供三种主要的运行方式,分别适用于项目生命周期中的不同的时期,更准备地说应该是适用于不同的场景。
生成模式 - build
将所有的文件生成至产品交付目录 dist
内,执行包括:
-
coffeescript/less
- 编译
- 连结
- 压缩
- 引用修正,包括 angular 动态注入修正
- 拷贝
-
输出必要的静态文件
- 网页
- 图片
- 字库
-
输出注释文档并生成文档网站
指令:grunt build
测试模式 - test
多用于开发期,进行自动化单元测试或是e2e测试,考虑到e2e测试的使用频率相对于单元测试要低,故此 test指令只默认执行所有单元测试,
而要执行e2e测试则需加入 e2e
参数作明确指定。
指令:
grunt test
- e2e -
grunt test:e2e
如果加入 keepalive
参数的话,test 指令将直接运行于后台,且会检测所有的文件变化,一但文件发生更改测试将会自动被重新执行。
这种情况多适用于测试程序的编写与调试。
grunt test:keepalive
调试模式 - debug
主要用于手工调试与HTML界面设计之用,当启用 debug 模式后,livereload 功能将会被自动载入,也就是所有 app
目录下的任何
变更都能被捕获且浏览器能自动刷新应用更改。
指令:grunt debug
Gruntfile.js 文件的设计
首先需要安装 load-grunt-tasks 和 time-grunt 两个插件
npm load-grunt-tasks --save-dev
npm time-grunt --save-dev
基本的 Gruntfile.js
'use strict';
module.exports = function (grunt) {
// 自动加载所有可用的grunt 任务
require('load-grunt-tasks')(grunt);
// 可以显示每个任务执行的实际时间,可以便于以我们优化任务
require('time-grunt')(grunt);
// 配置主要路径
var config = {
app: require('./bower.json').appPath || 'app',
dist: 'dist',
tmp: '.tmp',
tasks: grunt.cli.tasks
};
grunt.initConfig({
// 任务配置
});
配置 CoffeeScript
首先是令CoffeeScript能支持语法检查,需要安装 [coffeelint| http://www.coffeelint.org ] 插件:
npm install coffeelint --save-dev
此插件安装后可以与大名鼎鼎的 jshint一样将语法检查规则放在一个独立的文件内,本项目中就是项目根目录下的 coffeelint.json
,
如果需要增加更多的CoffeeScript语法检查规则可以修改此文件 。
在Gruntfile.js内的配置如下:
coffeelint: {
options: {
configFile: 'coffeelint.json'
},
all: ['<%= config.app %>/scripts/**/*.coffee'], //检查应用程序目录下的 CoffeeScript脚本
test: {
files: {
src: ['tests/**/*.coffee'] //检查所有测试脚本
}
}
}
然后是安装CoffeeScript编译插件: [coffee-script| http://github.com/jashkenas/coffeescript ]
npm install grunt-contrib-coffee --save-dev
由于我们编译出来的 javascript 不会直接使用,因为还要进行连接、压缩和拷贝过程,所以我们将所有的输出目录设置为 .tmp
目录。
在即使修改时也可以通过livereload 从.tmp目录直接将变更后的脚本直接加载到浏览器内,方便调试之用。
还有一点需要特别指出的是 coffee 选项中我将 sourceMap
设置为true,只有这个选项打开,当生成map文件后在浏览器调试时才能准确地将被压缩后的
文件正确地重新映射至未压缩的程序源文件。关于 source map的具体用法可以参考 [javascript source map的使用| http://www.cnblogs.com/Ray-liang/p/4018162.html ]
一文。
coffee: {
options: {
bare: false,
sourceMap: true,
sourceRoot: ''
},
dist: {
files: [
{
expand: true,
cwd: '<%= config.app %>/scripts',
src: '{,*/}*.{coffee,litcoffee,coffee.md}',
dest: '.tmp/scripts',
ext: '.js'
}
]
},
test: {
files: [
{
expand: true,
cwd: 'test/spec',
src: '{,*/}*.coffee',
dest: '.tmp/spec',
ext: '.js'
},
{
expand: true,
cwd: 'test/e2e',
src: '{,*/}*.coffee',
dest: '.tmp/e2e',
ext: '.js'
}
]
}
}
配置 Less
Grunt 提供了官方的less 编译安装包 [grunt-contrib-less| https://github.com/gruntjs/grunt-contrib-less ]
npm install grunt-contrib-less --save-dev
与配置coffee 编译器的原理一样我们需要将 styles 目录下的 .less文件预先编译成为 .css并存放在 .tmp/styles下,以备后处理
和livereload 之用。
less: {
all: {
files: [
{
expand: true,
flatten: true,
cwd: '<%= config.app %>/styles',
src: ['{,*/}*.less'],
dest: '.tmp/styles',
ext: '.css'
}
]
}
}
压缩与连接
在这部分我并没有直接采用 Grunt 官方的 uglify,concat 而是使用了 usemin 插件这是延续了 yo generator-angular 的做法。他是 yeoman项目的官方插件,这个插件同样是依赖于 uglify,concat 的,然而他增加了对文件自动引用的支持,可以从页面读出脚本文件的引用而不是通过hardcore的方式写在Gruntfile中。另外,他还能增加对bower_components内的依赖进行合成而取代人工合成,这是一个很棒的功能可以省去我们从bower_components下找输出文件的麻烦,只需要关注bower.json文件内管理包而不是在Gurntfile.js进行硬编码了。
usemin是一个合成包需要以下这些插件同时支持,为了节省篇幅以下的指令都是以 npm install [包] --save-dev
方式安装
- [grunt-usemin| https://github.com/yeoman/grunt-usemin ]
- [grunt-svgmin| https://github.com/sindresorhus/grunt-svgmin ]
- [grunt-contrib-cssmin| https://github.com/gruntjs/grunt-contrib-cssmin ]
- [grunt-contrib-htmlmin| https://github.com/gruntjs/grunt-contrib-htmlmin ]
- [grunt-contrib-imagemin| https://github.com/gruntjs/grunt-contrib-imagemin ]
- [grunt-contrib-uglify| https://github.com/gruntjs/grunt-contrib-uglify ]
- [grunt-contrib-concat| https://github.com/gruntjs/grunt-contrib-concat ]
以下配置是从 generate-angular 中拷贝过来用的:
// Reads HTML for usemin blocks to enable smart builds that automatically
// concat, minify and revision files. Creates configurations in memory so
// additional tasks can operate on them
useminPrepare: {
options: {
dest: '<%= config.dist %>'
},
html: [
'<%= config.app %>/index.html'
]
},
// Performs rewrites based on rev and the useminPrepare configuration
usemin: {
options: {
assetsDirs: [
'<%= config.dist %>',
'<%= config.dist %>/images'
]
},
html: ['<%= config.dist %>/{,*/}*.html'],
css: ['<%= config.dist %>/styles/{,*/}*.css']
},
// The following *-min tasks produce minified files in the dist folder
imagemin: {
dist: {
files: [
{
expand: true,
cwd: '<%= config.app %>/images',
src: '{,*/}*.{gif,jpeg,jpg,png}',
dest: '<%= config.dist %>/images'
}
]
}
},
svgmin: {
dist: {
files: [
{
expand: true,
cwd: '<%= config.app %>/images',
src: '{,*/}*.svg',
dest: '<%= config.dist %>/images'
}
]
}
},
htmlmin: {
dist: {
options: {
customAttrAssign: [/\?=/],
collapseBooleanAttributes: true,
collapseWhitespace: true,
removeAttributeQuotes: true,
removeCommentsFromCDATA: true,
removeEmptyAttributes: true,
removeOptionalTags: true,
removeRedundantAttributes: true,
useShortDoctype: true
},
files: [
{
expand: true,
cwd: '<%= config.dist %>',
src: ['{,*/}*.html', 'views/{,*/}*.html', 'templates/{,*/}*.html'],
dest: '<%= config.dist %>'
}
]
}
}
这里需要说明的是 app/index.html文件,也就是在配置中:
useminPrepare: {
html: [
'<%= config.app %>/index.html'
]
}
这个选项是给 usemin 插件去找脚本引用的,这里默认只是设定了 index.html 文件,因为这是一个Angular SPA项目,所以只有一个index.html文件作为主入口,如果你具有多个不同的视图模板,而且所引用的 script 都不要一样的话,可以将这些模板页明确地放在这个 html
数组选项中。
关于usemin的详细用法可以参考google的官方文档,以下只是对最常用的部分进行讲解,力求不去看官方那个庞大的英文文档也能快速地使用起来。
打开 index.html :
<!doctype html>
<html ng-app="app">
<head>
<meta charset="utf-8">
<title>Project Title</title>
<!-- build:css styles/vendor.css -->
<!-- bower:css -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="bower_components/fontawesome/css/font-awesome.css" />
<!-- endbower -->
<!-- endbuild -->
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<!-- endbuild -->
<!-- build:js scripts/vendor.js -->
<!-- bower:js -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:js({.tmp,app}) scripts/index.js -->
<!-- endbuild -->
<base target="_blank">
</head>
<body ng-strict-di>
<div ui-view></div>
</body>
</html>
<!--build:js--><!-- endbuild -->
和 <!--build:css--><!-- endbuild -->
实际上这不是注释,他们其实是 usemin 的专用配置标记。其中 <!-- bower:js--><!--endbower-->
是另一个插件 bowerInstall 的
配置标记,我会在下文再详细讲解。
这个标记其实很简单将他翻译过来就是: <!-- build:类型[js|css] 生成的目标文件>
, 源文件目录就是当前html所在的目录,如果要指定多个
源目录可以通过 <!-- build:类型({目录1,目录2}) 生成的目标文件>
的方式指定。
按照这个来理解的话,这里的设置就会输出三个文件:
- vendor.js //第三方依赖的合成压缩脚本
- index.js //项目内的的合成压缩脚本
- vendor.css //第三方依赖的合成压缩样式表
- main.css //项目内的合成压缩样式表
好吧,先来说说 vendor.*
,如果装了 bowerInstall 这个插件在 <!-- bower:类型 --><!-- endbower-->
内的引用是由 bowerInstall 自动加入的,他加入后会修改index.html源文件,我们不需要手工加入。而对于某些比较坑爹的第三包,这里指的坑爹是他的最终输出文件放在一些古怪的深层目录中,而不是在他的发布目录的根下,那么我们才需要手工加入引用。如 ace-builds 这个包,他的发布文件是在 ace-builds/src/ace.js,同时他又提供了ace-build/src-min/ace.js 文件,对于这类包我们就不得不手工将具体的引用文件加入到 <!-- bower-->
标记内,否则bowerInstall是不知道应该引用哪一个文件的。
而输出位置就是前面我们在 usemin选项中设定的:
useminPrepare {
options: {
dest: '<%= config.dist %>'
}
}
也就是 项目目录/dist
。
接下来是 main.css
和 index.js
,这两个是从不同的源来生成的, main.css
没有指定源,所以他会在当前的index.html所在位置中找 styles 目录也就是 项目目录/app/styles
,那么具体需要引用那些自定的css(之前通过 less生成的)就在此设定。
解释得更为清楚一点就是 假设有一个 app/styles/custom.less 文件,那么在 index.html内加入这个引用应该是:
<!-- build:css styles/main.css -->
<link rel="stylesheet" href="styles/main.css">
<link rel="stylesheet" href="styles/custom.css">
<!-- endbuild -->
虽然custom.css在设计期并不存在,但他会被less编译器最终输出,所以引用时只要名字对了就行了。
同样的 build:js
的设置也是这理,只是这里增加了 .tmp
作源搜寻目录,就是说在 .tmp
找不到的源文件 可以到 app/scripts
下找,反之亦然。
更多详情见请继续阅读下一页的精彩内容 : http://www.linuxidc.com/Linux/2015-09/123595p2.htm
以上所述就是小编给大家介绍的《AngularJS + CoffeeScript 前端开发环境配置详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 【前端学习笔记】前端安全详解
- 前端面试题—vue部分详解
- 前端 H5 横屏 独特处理方案详解
- AngularJS + CoffeeScript 前端开发环境配置详解
- 【前端基础进阶】JS原型、原型链、对象详解
- 【前端基础进阶】JS-Object 功能详解
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Design for Hackers
David Kadavy / Wiley / 2011-10-18 / USD 39.99
Discover the techniques behind beautiful design?by deconstructing designs to understand them The term ?hacker? has been redefined to consist of anyone who has an insatiable curiosity as to how thin......一起来看看 《Design for Hackers》 这本书的介绍吧!