前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Yeoman 生成的 Angular 脚手架详解

Yeoman 生成的 Angular 脚手架详解

作者头像
kl博主
发布2023-11-17 19:26:49
1920
发布2023-11-17 19:26:49
举报
文章被收录于专栏:kl的专栏

Yeoman 生成的 Angular 脚手架提供了 27 个任务配置和 3 个自定义任务。这三个自定义任务分贝为:

build 编译产品化的版本。

serve 编译,让后启动一个 web 服务器。

test 执行应用的单元测试。

default 构建一个优化过的,产品化的应用版本。

module .exports = function (grunt) {

grunt.registerTask( 'serve' , 'Compile then start a connect web server' , function (target) {

if (target === 'dist' ) {

return grunt.task.run([ 'build' , 'connect:dist:keepalive' ]);

}

grunt.task.run([

'clean:server' ,

'wiredep' ,

'concurrent:server' ,

'autoprefixer' ,

'connect:livereload' ,

'watch'

]);

});

grunt.registerTask( 'test' , [

'clean:server' ,

'concurrent:test' ,

'autoprefixer' ,

'connect:test' ,

'karma'

]);

grunt.registerTask( 'build' , [

'clean:dist' ,

'wiredep' ,

'useminPrepare' ,

'concurrent:dist' ,

'autoprefixer' ,

'concat' ,

'ngAnnotate' ,

'copy:dist' ,

'cdnify' ,

'cssmin' ,

'uglify' ,

'filerev' ,

'usemin' ,

'htmlmin'

]);

grunt.registerTask( 'default' , [

'newer:jshint' ,

'test' ,

'build'

]);

}

serve

grunt.registerTask( 'serve' , 'Compile then start a connect web server' , function (target) {

if (target === 'dist' ) {

return grunt.task.run([ 'build' , 'connect:dist:keepalive' ]);

}

grunt.task.run([

'clean:server' ,

'wiredep' ,

'concurrent:server' ,

'autoprefixer' ,

'connect:livereload' ,

'watch'

]);

});

如果 serve 的目标是 dist ,那么就运行 build,并且为 build 后的版本启动 web 服务器,这个服务器是持久运行的。主要用于测试发布版本。

在调试阶段,一般使用非 dist 目标,这个目标运行的任务为:

clean:server,

wiredep,

concurrent:server,

autoprefixer,

connect:livereload,

watch

clean:server

gruntjs/grunt-contrib-clean 用于清除文件和文件夹。

clean 的任务配置为:

clean: {

dist: {

files: [{

dot: true ,

src: [

'.tmp' ,

'<%= yeoman.dist %>/{,*/}*' ,

'!<%= yeoman.dist %>/.git*'

]

}]

},

server: '.tmp'

}

serve 任务只是用了 clean:server 目标,即删除 .tmp 目录。

wiredep

stephenplusplus/grunt-wiredep 插件基于 taptapship/wiredep 。用来根据 bower.json 在指定文件的占位符中注入 JavaScript 或者 CSS 依赖。

wiredep 的配置为:

wiredep: {

app: {

src: [ '<%= yeoman.app %>/index.html' ],

ignorePath: /\.\.\//

}

}

index.html 中两个占位符:

运行 grunt:wiredep 后,这两个占位符会根据 bower.json 中的依赖关系正确填充,如;

< link rel = "stylesheet" href = "bower_components/bootstrap/dist/css/bootstrap.css" />

< script src = "bower_components/jquery/dist/jquery.js" >

< script src = "bower_components/angular/angular.js" >

< script src = "bower_components/angular-touch/angular-touch.js" >

< script src = "bower_components/angular-bootstrap/ui-bootstrap-tpls.js" >

< script src = "bower_components/angular-ui-router/release/angular-ui-router.js" >

< script src = "bower_components/bootstrap/dist/js/bootstrap.js" >

bower.json 为:

{

" name ": "argo" ,

" version ": "0.0.0" ,

" dependencies ": {

" angular ": "~1.2.0" ,

" angular-touch ": "~1.2.0" ,

" angular-bootstrap ": "~0.11.2" ,

" angular-ui-router ": "~0.2.11" ,

" bootstrap ": "~3.2.0"

},

" devDependencies ": {

" angular-mocks ": "~1.2.0" ,

" angular-scenario ": "~1.2.0"

},

" appPath ": "app"

}

concurrent:server

sindresorhus/grunt-concurrent 用于运行并行任务。对于耗时的任务(如 Coffee and Sass)或者运行 多个阻塞任务 (如 nodemon and watch ) 时很有用。

concurrent 任务配置为:

concurrent: {

server: [

'copy:styles'

]

}

concurrent:server 目标中,并行运行 copy:styles 。

copy:styles

gruntjs/grunt-contrib-copy 用于拷贝文件。

copy: {

styles: {

expand: true ,

cwd: '<%= yeoman.app %>/styles' ,

dest: '.tmp/styles/' ,

src: '{,*/}*.css'

}

}

expand: true 是为了启用扩展属性, cwd 修改 dest 和 src 的相对路径。所以, style 目标的作用是,将 <%= yeoman.app %>/styles 以及下级目录中的所有 css 文件以平板方式拷贝到 .tmp/styles/ 。

autoprefixer

nDmitry/grunt-autoprefixer 使用Can I Use数据库为 CSS 添加前缀。

options.browsers 用于指定浏览器的版本,如 ‘last 1 version’ 指定各浏览器的最后一个版本。

autoprefixer: {

options: {

browsers: [ 'last 1 version' ]

},

dist: {

files: [{

expand: true ,

cwd: '.tmp/styles/' ,

src: '{,*/}*.css' ,

dest: '.tmp/styles/'

}]

}

}

dist 目标表示为 .tmp/styles/ 目录以及下级目录中的所有 css 文件添加前缀,然后覆盖原文件。

connect:livereload

gruntjs/grunt-contrib-connect 用于启动一个静态 web 服务器。

connect: {

options: {

port: 9000 ,

// Change this to '0.0.0.0' to access the server from outside.

hostname: 'localhost' ,

livereload: 35729

},

livereload: {

options: {

open: true ,

middleware: function (connect) {

return [

connect.static( '.tmp' ),

connect().use(

'/bower_components' ,

connect.static( './bower_components' )

),

connect.static(appConfig.app)

];

}

}

}

options.hostname 和 options.port 用于指定服务器的主机名和端口。 options.hostname 默认为 0.0.0.0 ,可以设置为 ‘*’,让它可以从任何地方访问。

options.open 指定为 true 时表示打开默认的服务器 URL,指定为字符串时,则打开该字符串指定的地址。

options.livereload 设置为 true 或者端口号,表示使用 connect-livereload 在你的页面中注入 live reload 脚本。这不会执行 live reloading,它试图和 grunt-contrib-watch 或者其他根据文件的修改触发 live reload 的服务器结合使用。

options.keepalive 设置为 true 表示让服务器无限期的执行。而这个任务之后的其任务不再执行。默认情况下,grunt 任务执行完成,web 服务器会停止。

options.middleware 类型为 Function 或者数组,用来添加 Connect 中间件。如果是函数,该函数返回中间件数组。Default: Array of connect middlewares that use options.base for static files and directory browsing,如:

connect: {

server: {

options: {

middleware: [

function myMiddleware (req, res, next) {

res.end( 'Hello, world!' );

}

],

},

},

}

我们的例子中, connect.livereload 目标中使用的是函数方式,返回 3 个使用 connect.static 方法构建的中间件。分别把 .tmp , /bower_components , appConfig.app 作为 static 资源。

watch

gruntjs/grunt-contrib-watch 用于监视文件的变化,然后运行指定的任务。

watch: {

bower: {

files: [ 'bower.json' ],

tasks: [ 'wiredep' ]

},

js: {

files: [ '<%= yeoman.app %>/scripts/{,*/}*.js' ],

tasks: [ 'newer:jshint:all' ],

options: {

livereload: '<%= connect.options.livereload %>'

}

},

jsTest: {

files: [ 'test/spec/{,*/}*.js' ],

tasks: [ 'newer:jshint:test' , 'karma' ]

}

styles: {

files: [ '<%= yeoman.app %>/styles/{,*/}*.css' ],

tasks: [ 'newer:copy:styles' , 'autoprefixer' ]

},

gruntfile: {

files: [ 'Gruntfile.js' ]

},

livereload: {

options: {

livereload: '<%= connect.options.livereload %>'

},

files: [

'<%= yeoman.app %>/{,*/}*.html' ,

'.tmp/styles/{,*/}*.css' ,

'<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}'

]

}

}

options.livereload 目标中通过 options.livereload 启用实时加载,使用的是 connect 任务的 livereload 配置。当 livereload.files 中指定的文件发生变化时,live reloading 服务器就会被触发。See also how to enable livereload on your HTML . 在这里,我们是通过 connect.livereload 目标为页面注入 live reloading 脚本。

除了 livereload 之外,还有

bower 监视 bower.json 文件,一旦文件发生变化,运行 wiredep 任务。

js 监视 <%= yeoman.app %>/scripts/{,*/} 下的所有 js 文件,如果有变化,则运行 newer:jshint:all 任务,而且会触发 live reloading 服务器。

jsTest 监视 test/spec/{,*/} 下的 js 文件,如果有变化,则运行 ‘newer:jshint:test’ 和 ‘karma’ 两个任务。

styles 监视 <%= yeoman.app %>/styles/ 下的文件,如果有变化,运行 ‘newer:copy:styles’ 和 ‘autoprefixer’ 两个任务。

gruntfile 监视 Gruntfile 文件,没有任务。

newer

tschaub/grunt-newer 配置任务只对新的文件运行任务。 newer 任务不要求特殊的配置,你只需要在任务前加上 newer: 。

对于同时有 src 和 dest 的任务, src 中的文件的修改时间会和 dest 中修改时间比较,如果有一个多多个更新的文件,则任务会重新运行,如:

grunt.initConfig({

uglify: {

all: {

files: {

'dest/app.min.js' : [ 'src/**/*.js' ]

     }

}

}

});

grunt.loadNpmTasks( 'grunt-contrib-uglify' );

grunt.loadNpmTasks( 'grunt-newer' );

grunt.registerTask( 'minify' , [ 'newer:uglify:all' ]);

minify 任务只有在 src/**/*.js 中的一个或多个文件比 dest/app.min.js 更新时, uglify:all 任务才会运行。

对于只有 src 没有 dest 的配置, newer 只会使用比上次成功运行的时间新的文件。如:

jshint: {

options: {

jshintrc: '.jshintrc'

},

all: {

src: 'src/**/*.js'

}

}

grunt.registerTask( 'lint' , [ 'newer:jshint:all' ]);

第一次运行 grunt lint 时, jshint:newer:all 会使用所有 src 下的文件,之后,只有你修改过的文件才会运行 jshint 。

结合 watch 使用时,当 src 中的文件变化时,会使用新的文件运行任务,如:

js: {

files: [ '<%= yeoman.app %>/scripts/{,*/}*.js' ],

tasks: [ 'newer:jshint:all' ],

options: {

livereload: '<%= connect.options.livereload %>'

}

}

当 files 中的文件有变化时,针对新的文件运行指定的任务,如这里的 jshint:all 。

build

build 任务由以下 14 个子任务组成。

grunt.registerTask( 'build' , [

'clean:dist' ,

'wiredep' ,

'useminPrepare' ,

'concurrent:dist' ,

'autoprefixer' ,

'concat' ,

'ngAnnotate' ,

'copy:dist' ,

'cdnify' ,

'cssmin' ,

'uglify' ,

'filerev' ,

'usemin' ,

'htmlmin'

]);

清除 .tmp 和 <%= yeoman.dist %>/{,*/}* ,但保留 <%= yeoman.dist %>/.git* 文件或者文件夹。

根据 bower 的依赖关系替换 index.html 中的占位符。

利用 useminPrepare 任务生成的配置合并文件,指定输出路径为 <%= yeoman.dist %> 。包括 bower_components 中的 js 和 css,以及 .temp/ 下用户自定义的 css 以及 .tmp/ 或者 app/ 下的 js。

并行运行 concurrent:dist 目标中的三个子任务:

将 <%= yeoman.app %>/styles 以及下级目录中的所有 css 文件拷贝到 .tmp/styles/ 。

将 <%= yeoman.app %>/images 中的图片压缩到 <%= yeoman.dist %>/images 中。

将 <%= yeoman.app %>/images/{,*/}/ 下的所有 svg 图片压缩到 <%= yeoman.dist %>/images 中。

.tmp/styles/ 目录以及下级目录中的所有 css 文件添加前缀,然后覆盖原文件。

使用的是 useminPrepare 任务生成的配置合并 css 和 js 文件。

将 index.html 中有 wiredep 插入的 css 合并为 .tmp/styles/vendor.css 文件中。

将 中的 css (路径为 .temp 目录下)合并到 .tmp/styles/main.css 中。

将 wiredep 插入的 js 文件合并到 .tmp/scripts/vendor.js 中。

将 中的 js 文件(存在于 .tmp 或者 app 目录下)合并到 .temp/scripts/scripts.js 中。

将 .tmp/concat/scripts 目录下除了 oldieshim.js 之外的所有 js 文件加上 angular 注解后覆盖原来的文件。

将 <%= yeoman.app %>/ 的所有 html、图片、字体文件、.htaccess 拷贝到 <%= yeoman.dist %> 下。

将 <%= yeoman.dist %>/*.html 中的本地路径修改为 CDN 路径。

使用 useminPrepare 生成的配置最小化 CSS。压缩后置于 '<%= yeoman.dist %>'/styles/ 中。

使用 useminPrepare 生成的配置混淆 JavaScript。混淆后置于 '<%= yeoman.dist %>'/scripts 中。

使用 filerev 重命名 <%= yeoman.dist %>/ 下所有 js、css、图片和字体文件。

将 <%= yeoman.dist %>/{,*/}*.html 和 <%= yeoman.dist %>/styles/{,*/}*.css 中的 usemin 块替换为 '<%= yeoman.dist %>','<%= yeoman.dist %>/images' 中优化后并且 revved 的版本。

压缩 <%= yeoman.dist %> 下的所有 html 以及视图文件夹所有的 html,将压缩后的文件置于 <%= yeoman.dist %>/ 下。

clean:dist

清除 .tmp 和 <%= yeoman.dist %>/{,*/}* ,但保留 <%= yeoman.dist %>/.git* 文件或者文件夹。

clean: {

dist: {

files: [{

dot: true ,

src: [

'.tmp' ,

'<%= yeoman.dist %>/{,*/}*' ,

'!<%= yeoman.dist %>/.git*'

]

}]

},

server: '.tmp'

}

wiredep

根据 bower 的依赖关系替换 index.html 中的占位符。

useminPrepare

根据 <%= yeoman.app %>/index.html 中的 usemin 块生成 JS 和 CSS 的压缩配置,并指定输出路径为 <%= yeoman.dist %> 。

useminPrepare: {

html: '<%= yeoman.app %>/index.html' ,

options: {

dest: '<%= yeoman.dist %>' ,

flow: {

html: {

steps: {

js: [ 'concat' , 'uglifyjs' ],

css: [ 'cssmin' ]

},

post: {}

}

}

}

}

index.html 中 usemin 块:

< link rel = "stylesheet" href = "styles/main.css" >

useminPrepare 为实现优化修改 Grunt 配置,定义 js 的优化流程为 concat —> uglifyjs ,css 的优化流程为 cssmin 。优化的 html 文件为 <%= yeoman.app %>/index.html ,优化后的文件路径为 <%= yeoman.dist %> 。

将 index.html 中有 wiredep 插入的 css 合并为 .tmp/styles/vendor.css 文件中。将 中的 css (路径为 .temp 目录下)合并到 .tmp/styles/main.css 中。压缩后放到 <%= yeoman.dist %>/

将 wiredep 插入的 js 文件合并到 .tmp/scripts/vendor.js 中,将进一步混淆后的文件生成到 <%= yeoman.dist %>/scripts/vendor.js 中。将 中的 js 文件(存在于 .tmp 或者 app 目录下)合并到 .temp/scripts/scripts.js 中,混淆后的文件生成到 <%= yeoman.dist %>/scripts/scripts.js 中。

concurrent:dist

并行运行 concurrent:dist 目标中的三个子任务。

concurrent: {

dist: [

'copy:styles' ,

'imagemin' ,

'svgmin'

]

}

copy:styles 将 <%= yeoman.app %>/styles 以及下级目录中的所有 css 文件拷贝到 .tmp/styles/ 。

imagemin 将 <%= yeoman.app %>/images 中的图片压缩到 <%= yeoman.dist %>/images 中。

svgmin 将 <%= yeoman.app %>/images/{,*/}/ 下的所有 svg 图片压缩到 <%= yeoman.dist %>/images 中。

imagemin

使用 gruntjs/grunt-contrib-imagemin 进行图片压缩。

imagemin: {

dist: {

files: [

{

expand: true ,

cwd: '<%= yeoman.app %>/images' ,

src: '{,*/}*.{png,jpg,jpeg,gif}' ,

dest: '<%= yeoman.dist %>/images'

}

]

}

}

压缩的图片存在于 <%= yeoman.app %>/images 压缩后的图片放置在 <%= yeoman.dist %>/images 。所以这个任务的目的是将 <%= yeoman.app %>/images 中的图片压缩到 <%= yeoman.dist %>/images 中。

svgmin

sindresorhus/grunt-svgmin 用来压缩 SVG。

svgmin: {

dist: {

files: [{

expand: true ,

cwd: '<%= yeoman.app %>/images' ,

src: '{,*/}*.svg' ,

dest: '<%= yeoman.dist %>/images'

}]

}

}

将 <%= yeoman.app %>/images/{,*/}/ 下的所有 svg 图片压缩到 <%= yeoman.dist %>/images 中。

autoprefixer

dist 目标表示为 .tmp/styles/ 目录以及下级目录中的所有 css 文件添加前缀,然后覆盖原文件。

concat

gruntjs/grunt-contrib-concat 用于拼接文件。

我们这里使用的是 useminPrepare 任务生成的配置,合并后的文件生成到临时目录( .tmp )目录下。

ngAnnotate

mzgol/grunt-ng-annotate 用来将 Angular 添加、删除或者重建 Angular 中的依赖注入。

有如下 Angular 模块,在未标注之前:

angular.module( "MyMod" ).controller( "MyCtrl" , function (

});

标注之后:

angular.module( "MyMod" ).controller( "MyCtrl" , [ "scope, timeout) {

}]);

添加标注后可以安全地对代码进行压缩。

我们的 ngAnnotate 的任务配置如下:

ngAnnotate: {

dist: {

files: [{

expand: true ,

cwd: '.tmp/concat/scripts' ,

src: [ '*.js' , '!oldieshim.js' ],

dest: '.tmp/concat/scripts'

}]

}

}

将 .tmp/concat/scripts 目录下除了 oldieshim.js 之外的所有 js 文件加上注解后覆盖原来的文件。

copy:dist

copy: {

dist: {

files: [{

expand: true ,

dot: true ,

cwd: '<%= yeoman.app %>' ,

dest: '<%= yeoman.dist %>' ,

src: [

'*.{ico,png,txt}' ,

'.htaccess' ,

'*.html' ,

'views/{,*/}*.html' ,

'images/{,*/}*.{webp}' ,

'fonts/*'

]

}, {

expand: true ,

cwd: '.tmp/images' ,

dest: '<%= yeoman.dist %>/images' ,

src: [ 'generated/*' ]

}]

}

}

将 <%= yeoman.app %>/ 的所有 html、图片、字体文件、.htaccess 拷贝到 <%= yeoman.dist %> 下。

cdnify

callumlocke/grunt-cdnify 将指定文件中的本地路径修改为 CDN 路径,CDN 可以通过 options.base 配置,默认为 Google 提供的 CDN。

cdnify: {

dist: {

html: [ '<%= yeoman.dist %>/*.html' ]

}

}

将 <%= yeoman.dist %>/*.html 中的本地路径修改为 CDN 路径。

cssmin

使用 useminPrepare 生成的配置,你也可以自定义:

cssmin: {

dist: {

files: {

'<%= yeoman.dist %>/styles/main.css' : [

'.tmp/styles/{,*/}*.css'

]

}

}

}

uglify

使用 useminPrepare 生成的配置,混淆后的文件默认生成到通过 useminPrepare 中指定的目标目录。

你也可以自定义:

uglify: {

dist: {

files: {

'<%= yeoman.dist %>/scripts/scripts.js' : [

'<%= yeoman.dist %>/scripts/scripts.js'

]

}

}

}

filerev

yeoman/grunt-filerev 通过文件内容的哈希重命名文件名。

// Renames files for browser caching purposes

filerev: {

dist: {

src: [

'<%= yeoman.dist %>/scripts/{,*/}*.js' ,

'<%= yeoman.dist %>/styles/{,*/}*.css' ,

'<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' ,

'<%= yeoman.dist %>/styles/fonts/*'

]}

}

使用 filerev 重命名 <%= yeoman.dist %>/ 下所有 js、css、图片和字体文件。

usemin

usemin: {

html: [ '<%= yeoman.dist %>/{,*/}*.html' ],

css: [ '<%= yeoman.dist %>/styles/{,*/}*.css' ],

options: {

assetsDirs: [ '<%= yeoman.dist %>' , '<%= yeoman.dist %>/images' ]}

}

usemin 使用 useminPrepare 阶段准备的配置优化,将 <%= yeoman.dist %>/{,*/}*.html 和 <%= yeoman.dist %>/styles/{,*/}*.css 中的 usemin 块替换为 '<%= yeoman.dist %>','<%= yeoman.dist %>/images' 中优化后并且 revved 的版本。 options.assetsDirs 重定义了 revved 版本的查找路径。

htmlmin

gruntjs/grunt-contrib-htmlmin 压缩 html。

htmlmin: {

dist: {

options: {

collapseWhitespace: true ,

conservativeCollapse: true ,

collapseBooleanAttributes: true ,

removeCommentsFromCDATA: true ,

removeOptionalTags: true},

files: [{

expand: true ,

cwd: '<%= yeoman.dist %>' ,

src: [ '*.html' , 'views/{,*/}*.html' ],

dest: '<%= yeoman.dist %>'

}]

}

}

压缩 <%= yeoman.dist %> 下的所有 html 以及视图文件夹所有的 html,将压缩后的文件置于 <%= yeoman.dist %>/ 下。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-01-19,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
图片处理
图片处理(Image Processing,IP)是由腾讯云数据万象提供的丰富的图片处理服务,广泛应用于腾讯内部各产品。支持对腾讯云对象存储 COS 或第三方源的图片进行处理,提供基础处理能力(图片裁剪、转格式、缩放、打水印等)、图片瘦身能力(Guetzli 压缩、AVIF 转码压缩)、盲水印版权保护能力,同时支持先进的图像 AI 功能(图像增强、图像标签、图像评分、图像修复、商品抠图等),满足多种业务场景下的图片处理需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档