Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
利用Grunt打造前端工作流
Search
hui.liu
June 29, 2013
Technology
1.2k
5
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
利用Grunt打造前端工作流
hui.liu
June 29, 2013
More Decks by hui.liu
See All by hui.liu
Redux and React Server Rendering
hulufei
1
120
How to build an online IDE with React
hulufei
0
550
Other Decks in Technology
See All in Technology
なぜ「決定性」が 決定的に重要なのか? Durable Execution 基盤の数理的理解 #serverlessjp / ServerlessDays Tokyo 2026
ytaka23
3
1.2k
おい、エージェントを使って終わらせろ
nwiizo
3
900
「今盗んで、後で解く」に備える ― AWSのポスト量子暗号入門
yama3133
1
210
「ピッケル本」日本語版は4.0(第6版)が出版されるべき / pickaxe4-nagoyark05
kakutani
2
290
データ_AIの事業の勝敗をわけるもの
nek0128
1
480
ボードゲームの遊び相手をFoundation Modelsで作る / iOSDC Japan 2026
genda
0
160
Making AI Agents Safe and Fast- Jev, Obsidian, and the Meta-Harness
x5gtrn
PRO
0
140
エージェントはローカル、検証はMicroVM — Lambda MicroVMsでつくるServerless CI
fujioka6789
3
770
Why Agent Cost Needs Observability
nttcom
0
150
Von-Neumann Machines, Dreams & The Futures of IT
ufried
0
130
CI/CDではもう遅い - 人とAIが迂回しないDevSecOps Verify基盤の再設計 -
kintotechdev
0
130
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.7k
Featured
See All Featured
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
550
Visualization
eitanlees
153
17k
Public Speaking Without Barfing On Your Shoes - THAT 2023
reverentgeek
1
570
Typedesign – Prime Four
hannesfritz
42
3.2k
Navigating Team Friction
lara
192
16k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
420
Mozcon NYC 2025: Stop Losing SEO Traffic
samtorres
1
560
Utilizing Notion as your number one productivity tool
mfonobong
4
600
Agile that works and the tools we love
rasmusluckow
331
22k
How to make the Groovebox
asonas
2
2.5k
The Limits of Empathy - UXLibs8
cassininazir
1
690
Transcript
利用Grunt打造前端工作流 刘辉 / @hulufei www.hulufei.com VIPSHOP ・ Front-End
前端的日常
F2E 开发 份内苦逼的事 F5 F5 Ctrl + F5 Ctrl +
F5 ....... 代码检查 测试 文件合并 文件压缩 发布 + csslint + jshint + test + concat css + concat js + min js + min css + min html + min image + rever(版本号)
Be A Ninja
None
None
= Workflow
专注偷懒二十年
None
None
Grunt Plugins contrib-coffee contrib-concat contrib-csslint contrib-jshint contrib-cssmin contrib-htmlmin contrib-imagemin contrib-qunit
contrib-uglify contrib-less and more http://gruntjs.com/plugins
None
Install & Start Using Grunt npm install -g grunt grunt-cli
+ Two Files Gruntfile.js packgage.json
Minify With Grunt
Install Plugin npm install grunt-contrib-uglify --save-dev
package.json { "name": "my-project-name", "version": "0.1.0", "devDependencies": { "grunt": "~0.4.1",
"grunt-contrib-uglify": "~0.2.2" } } "grunt-contrib-uglify": "~0.2.2"
Gruntfile.js Gruntfile.coffee module.exports = -> @initConfig uglify: dist: src: 'src/myfile.js'
dest: 'dist/myfile.min.js' @loadNpmTasks 'grunt-contrib-uglify' @registerTask 'default', ['uglify'] module.exports = function(grunt) { // Project configuration. grunt.initConfig({ uglify: { build: { src: 'src/myfile.js' , dest: 'build/myfile.min.js' } } }); // Load the plugin grunt.loadNpmTasks( 'grunt-contrib-uglify' ); // Default task(s). grunt.registerTask( 'default', ['uglify']); }; 'default'
Run Task grunt uglify or grunt
None
Grunt Tasks • Basic Task • Multi Task
Basic Task grunt.registerTask('foo', 'optional description', function(arg1, arg2) { console.log(arg1); console.log(arg2);
}); No Configuration grunt foo:hello:world // => hello // => world registerTask
Multi Task // Configuration grunt.initConfig({ foo: { target1: { //
target1 options and files go here. }, target2: { // target2 options and files go here. } } }); grunt.registerMultiTask('foo', function() { grunt.log.writeln(this.target); grunt.log.writeln(this.data); }); grunt foo:target1 // => target1 // => {} registerMultiTask target1 target2
Files
Files - 通配符 • * 匹配任何字符,除了 / • ? 匹配单个字符,除了
/ • ** 匹配任何字符,包括 /,所以用在目录路径里面 • {} 逗号分割的“或”操作(逗号后面不要有空格) • ! 排除某个匹配 // foo目录下所有 th 开头的js文件 { src: 'foo/th*.js' , dest: ... } // foo目录下所有 a 或者 b 开头的js文件 { src: 'foo/{a,b}*.js' , dest: ... } // 也可以分开写成 这样 { src: ['foo/a*.js' , 'foo/b*.js' ], dest: ... } // foo目录下所有js文件 { src: ['foo/*.js'], dest: ... } // foo目录下所有js文件,除了bar.js { src: ['foo/*.js', '!foo/bar.js' ], dest: ... }
Files - 三种格式(1) Compact Format 每个 target 只能指定一对src-dest grunt.initConfig({ jshint:
{ foo: { src: ['src/aa.js', 'src/aaa.js'] } }, concat: { bar: { src: ['src/bb.js', 'src/bbb.js'], dest: 'dest/b.js', } } }); src dest
Files - 三种格式(2) Files Object Format 每个 target 可以指定多对src-dest 放在
files 对象里面 grunt.initConfig({ concat: { foo: { files: { 'dest/a.js': ['src/aa.js', 'src/aaa.js'], 'dest/a1.js': ['src/aa1.js', 'src/aaa1.js'] } }, bar: { files: { 'dest/b.js': ['src/bb.js', 'src/bbb.js'], 'dest/b1.js': ['src/bb1.js', 'src/bbb1.js'] } } } });
Files - 三种格式(3) Files Array Format 每个 target 可以指定多对src-dest 放在
files 数组里面 另:可以为每个 src-dest 对象指定额外的 属性,比如filter 等 grunt.initConfig({ concat: { foo: { files: [ { src: [ 'src/aa.js', 'src/aaa.js'], dest: 'dest/a.js' }, { src: [ 'src/aa1.js', 'src/aaa1.js'], dest: 'dest/a1.js' } ] }, bar: { files: [ { src: [ 'src/bb.js', 'src/bbb.js'], dest: 'dest/b/', nonull: true }, { src: [ 'src/bb1.js', 'src/bbb1.js'], dest: 'dest/b1/', filter: 'isFile' } ] } } }); filter nonull
You Got It
None
Team Workflow 最小化配置・可复用・可维护
Gruntfile.js packgage.json lib/ ... config.json + npm install Usage: Maintained:
module.exports = function(grunt) { grunt.initConfig({ project: grunt.file.readJSON('config.json') }); }; Load
Config
Template module.exports = function(grunt) { grunt.initConfig({ cssmin: { vips: {
src: ['**/*.css'], dest: '<%= dir %>/css/public/' } } }); }; <%= dir %>
Change Config grunt.config('dir', 'value')
None
None
Commands List grunt taste 构建更改的文件,但是不提交 grunt build:all 构建整个开发分支, 不提交 grunt
build:noimage 构建整个开发分支,除了图片, 不提交 grunt build:changelog 构建CHANGELOG内的文件, 不提交 grunt push -m 'comment' 构建分支并提交,更改文件写入 CHANGELOG grunt sync -m 'comment' push,最后同步更改的文件到开 发服务器 grunt sync:tpl 同步所有模板文件到开 发服务器 grunt sync:s2 同步所有静态文件到开发服务器 grunt sync:changelog 同步CHANGELOG记录的对应分支的文件到开发服务器 grunt vipserver 映射s2静态资源到本地, 监控模板文件更改自动同步到开发服务器 grunt switch:hosts 切换指定hosts grunt co svn checkout配置的所有静态资源分支 grunt lint lint更改的css/js文件 grunt monitor 监听文件更改,自动lint对应的文件 grunt tcl 生成一个CHANGELOG文件的模板 grunt deploy Build for deploy Build Sync Local Helper workflow for vipshop
None
None
Thank You Q&A