gulp或者grunt中有哪些神一般的task?
generator-gulp-angular (Swiip/generator-gulp-angular · GitHub)這是一個Yeoman Generator,最近項目里稍微改了一下在用。其中有兩個task我覺得很實用。一個是Inject,代碼如下
"use strict";
var gulp = require("gulp");
var $ = require("gulp-load-plugins")();
var wiredep = require("wiredep").stream;
module.exports = function(options) {
gulp.task("inject", ["scripts", "styles"], function () {
var injectStyles = gulp.src([
options.tmp + "/serve/app/**/*.css",
"!" + options.tmp + "/serve/app/vendor.css"
], { read: false });
var injectScripts = gulp.src([
options.src + "/app/**/*.js",
"!" + options.src + "/app/**/*.spec.js",
"!" + options.src + "/app/**/*.mock.js"
])
.pipe($.angularFilesort()).on("error", options.errorHandler("AngularFilesort"));
var injectOptions = {
ignorePath: [options.src, options.tmp + "/serve"],
addRootSlash: true
};
return gulp.src(options.src + "/*.html")
.pipe($.inject(injectStyles, injectOptions))
.pipe($.inject(injectScripts, injectOptions))
.pipe(wiredep(options.wiredep))
.pipe(gulp.dest(options.tmp + "/serve"));
});
};
這個task其實信息量還是有點大的,首先是 gulp-load-plugins 這個插件,它可以自動載入所有devDependencies插件,這樣就不需要在開頭寫一堆require了。
接下來是gulp-inject,這個插件通過在文件中尋找特定的tag,將指定的文件插入到目標文件中,比如Less、Sass的import,CMD的Module,html的JS及css依賴
然後是wiredep,通過檢查bower.json注入依賴,類似於gulp-inject,不過需要bower的包做的比較好,有些支持不是很好。gulp-angular-filesort,調整angular各模塊的依賴順序。這個文件擴展一下適用還是比較廣的,大部分模塊化的項目都可以用到,可以說是這個generator裡面比較出彩的一部分了。第二個是Build,這是一個task的集合,我這裡拿出其實兩個比較重要的:partials和html
gulp.task("partials", function () {
return gulp.src([
options.src + "/app/**/*.html",
options.tmp + "/serve/app/**/*.html"
])
.pipe($.minifyHtml({
empty: true,
spare: true,
quotes: true,
loose: true
}))
.pipe($.angularTemplatecache("templateCacheHtml.js", {
module: "foo",
root: "/app"
}))
.pipe(gulp.dest(options.tmp + "/partials/"));
});
partials這個task的作用是將所有Angular的template合併起來,最後通過angular的templateCache服務將原本的Html載入,優點是減少請求數,在app不大的時候能顯著的提高載入速度。
gulp.task("html", ["otherStyles", "partials"], function () {
var partialsInjectFile = gulp.src(options.tmp + "/partials/templateCacheHtml.js", {read: false});
var partialsInjectOptions = {
starttag: "&",
ignorePath: options.tmp + "/partials",
addRootSlash: false
};
var htmlFilter = $.filter("*.html");
var jsFilter = $.filter("**/*.js");
var cssFilter = $.filter("**/*.css");
var assets;
return gulp.src(options.tmp + "/serve/*.html")
.pipe($.inject(partialsInjectFile, partialsInjectOptions))
.pipe($.replace("/bower", "../bower"))
.pipe(assets = $.useref.assets())
.pipe($.rev())
.pipe(jsFilter)
.pipe($.ngAnnotate())
.pipe($.stripDebug())
.pipe($.uglify({preserveComments: $.uglifySaveLicense})).on("error", options.errorHandler("Uglify"))
.pipe(jsFilter.restore())
.pipe(cssFilter)
.pipe($.csso())
.pipe(cssFilter.restore())
.pipe(assets.restore())
.pipe($.useref())
.pipe($.revReplace())
.pipe(htmlFilter)
.pipe($.minifyHtml({
empty: true,
spare: true,
quotes: true,
conditionals: true,
loose: true
}))
.pipe(htmlFilter.restore())
.pipe(gulp.dest(options.dist + "/"))
.pipe($.size({title: options.dist + "/", showFiles: true}));
});
html基本就是最後的打包流程了,包括注入資源的合併,html、css、js壓縮,版本號自動添加,Angular依賴注入修正等,基本上中小型項目需要做的都做了。
這個generator還提供其他的很多功能,由於項目限制就沒有使用了,總之這是一個結構清晰、代碼風格也比較規範的workflow,是比較適合初學者學習的,缺點就是經常來個大更新,之前版本的代碼完全不能兼容,要升級的話還是有點麻煩,具體代碼可以參見項目的Repo。
以上。介紹兩個插件。
這兩個插件,是因為我花了近一天的時間各種搜索和試用,一直沒找到合適的,尼瑪然後就自己寫了個。
所以,我覺得,應該還是挺有用的,因為我一直沒找到其他順手的啊。1、gulp-merge-link 用來合併JS和CSS引用的。 e.g gulp.task("merge",function(){gulp.src("*.css").pipe(
merge({
"css/all.css":["**/*.css"],
"js/all.js":["**/*.js"]
},{debug:true}
)).pipe(gulp.dest("dist"))})
執行gulp merge前:
&
&
&
&
&
&
執行後:
&
&
&
&
類似插件: gulp-preprocess 不過它實現的是在HTML中聲明,我特別討厭這種在原代碼中聲明的方式,個人感覺很不爽
2、gulp-sprite2
至於為什麼叫2,不是因為很二。。。因為是在gulp-css-spriter基礎上改了一丟丟,所以取名為2,
另外也因為雪碧圖插件一堆堆的,各種重名只有加個2了, gulp-css-spriter是我覺得在這一堆堆里算是最好用的了,但是還有有兩點很不爽, 1)過濾採用的是在css文件中聲明的方式,我說過了,我對於這種語法很不爽! 2)不能實現分組。 介於此,在原基礎上,參數options添加了ignore屬性, 1)過濾:ignore:[ "img/*.gif" ] 2)分組:創建多個task, 好了,求贊。。。我就這點樂趣了。。。這個 task 寫完後感覺挺有趣的. 這個 task 可以讓 gulp 監測 gulpfile 自身的改動, 並且重新啟動自己 :D. 完蛋了, 人工智慧崛起後這種程序好可怕的趕腳.
這個 task 的用途是用 gulp watch 文件的改動並啟動相應的 task ( 我們用 gulp 做增量開發基本都會這麼搞 ). 有趣的地方在於如果 gulpfile 自身發生了改動, 那麼 gulp 將會重新啟動自己. 為了達到這個目的, 這裡需要做兩層 watch, 通過 gulp watch 去啟動 child process 的 deep-watch, 這樣當 gulp 自身改變了以後, 他重啟的部分是 deep-watch. 愚蠢的人類啊, 以為逃出 Matrix 來到 Sion 就是現實了?
var Path = require("path");
var Chalk = require("chalk");
var gulp = require("gulp");
var watch = require("gulp-watch");
// ... some other codes ...
var tasks = {
// ...
};
var gulpfiles = ["**/gulpfile.js", "**/tasks/*.js"].concat(ignores);
function dowatch ( taskName ) {
watch( paths[taskName], function ( file ) {
if ( file.event !== "unlink" ) {
gulp.start(taskName);
}
}).on("error", function (e) {
console.warn(e.message);
});
}
gulp.task("deep-watch", function() {
for ( var name in tasks ) {
dowatch(name);
}
});
gulp.task("watch", function() {
// reload if gulpfile changed
var p;
function restart () {
if ( p ) {
p.kill();
console.log( Chalk.yellow.bold("gulpfile changed, deep-watch restart!") );
}
var spawn = require("child_process").spawn;
p = spawn("gulp", ["deep-watch"], {stdio: "inherit"});
}
watch( gulpfiles, restart ).on("error", function (e) {
console.log( Chalk.red(e.message) );
});
restart();
});
我覺得官方文檔的很多秘籍非常好
gulp-docs-zh-cn/recipes at master · lisposter/gulp-docs-zh-cn · GitHub (中文版本)
貼出目錄來
- 自動發布工作流
- 整合 streams 來處理錯誤
- 刪除文件和文件夾
- 使用 watchify 加速 browserify 編譯
- 增量編譯打包,包括處理整所涉及的所有文件
- 將 buffer 變為 stream (內存中的內容)
- 在 gulp 中運行 Mocha 測試
- 僅僅傳遞更改過的文件
- 從命令行傳遞參數
- 只重新編譯被更改過的文件
- 每個文件夾生成單獨一個文件
- 串列方式運行任務
- 擁有實時重載(live-reloading)和 CSS 注入的伺服器
- 通過 stream 工廠來共享 stream
- 指定一個新的 cwd (當前工作目錄)
- 分離任務到多個文件中
- 使用外部配置文件
- 在一個任務中使用多個文件來源
- Browserify + Uglify2 和 sourcemaps
- Browserify + Globs
- 同時輸出一個壓縮過和一個未壓縮版本的文件
- Swig 亦即 YAML front-matter 模板
既然問gulp和grunt,自然想到:
https://www.npmjs.com/package/gulp-grunt
https://www.npmjs.com/package/grunt-gulp這兩個插件作者不一樣,名字怎麼這麼像呢?前者讓你在gulp里調用grunt的任務,後者能在grunt里開gulp的任務。神器啊。自己有一個task: hanan198501/grunt-cptpl · GitHub不能說神,但是極大方便了前端 template 的管理。這款task使前端開發也可以像後端一樣,把模板文本存放在單獨的文件中(而不是放在dom節點但或者手工js拼接字元串), 然後將其編譯成javascript文件。使我們的開發工作從繁瑣的dom操作和JS拼串中解放出來,提高我們的開發效率。最主要的,模板文件作為單獨文件存放,可以使我們的項目代碼邏輯更加清晰,更具可維護性。都支持啥模板引擎?
grunt-cptpl支持各大主流模板引擎:artTemplate、 Handlebars 、Hogan 、 Underscore、 juicer、 doT、 kissy、 baiduTemplate。 對於不在此列的引擎,提供了自定義編譯方法介面。
這玩意都做了啥?grunt-cptpl會讀取每個模板文件的文本內容,用指定模板引擎的預編譯方法將其包裹起來,生成一個新的javascript文件。這個javascript文件文件裡面的內容,其實就是模板引擎的預編譯方法調用,傳入的參數為模板文件的文本內容。這樣我們就有了一個編譯好的模板函數,要渲染的時候把數據傳給它就好了。
歡迎一試哈~
剛剛寫了一個,用於express的自動構建,可以一行指令新建一個新的頁面及路由。
gulp.task("new_view",function(name){
return gulp.src("templates/page.handlebars")
.pipe(template({name: name?name:"new"}))
.pipe(rename({
basename:name
}))
.pipe(gulp.dest("views"));
})
gulp.task("new_router",function(name){
return gulp.src("templates/router.js")
.pipe(template({name: name?name:"new"}))
.pipe(rename({
basename:name
}))
.pipe(gulp.dest("routes"));
})
gulp.task("new_less",function(name){
return gulp.src("templates/style.less")
.pipe(template({name: name?name:"new"}))
.pipe(rename({
basename:name
}))
.pipe(gulp.dest("src/less"));
})
gulp.task("inject_app",function(name){
return gulp.src("app.js")
.pipe(replace("//newFilesRouter", "//newFilesRouter
var router_"+name+" = require("./routes/"+name+"");"))
.pipe(replace("//newRouter", "//newRouter
app.use("/"+name+"", router_"+name+");"))
.pipe(gulp.dest("./"))
})
gulp.task("new",function (name,router) {
if(router)
return runsequence(["new_view","new_less","new_router","inject_app"]);
else
return runsequence(["new_view","new_less"]);
})
這些task可以生成對應名稱的頁面,樣式文件和配置路由,同時在app.js中註冊路由。
執行代碼npm new --name newpage --router
useref,合併html中指定的js,css
browser-sync,更改頁面自動刷新瀏覽器,雙屏必備,那一個酸爽補充一下:
gulp-connect-proxy 代理外部的介面
如果基於現成的介面開發,就省了 mock 數據這一步,更方便;
我當前的個人項目的開發模式 python/php/ruby/postgrest + gulp/grunt, 一邊都是後端的介面先開發完,然後開始開發前端,這個代理插件給我帶來了極大的方便,
有人說直接在後端伺服器上開發,那就沒法使用 gulp-server-livereload(@droiz)這種好用的自刷新的組件(或者其他的前端工具了)了,我還是偏喜歡前後端開發環境分離
var Proxy = require("gulp-connect-proxy");
...
// A local web server for dev convenience
gulp.task("server", function() {
connect.server({
root: "./dist",
port: 22532,
middleware: function (connect, opt) {
opt.route = "/proxy";
var proxy = new Proxy(opt);
return [proxy];
}
});
});
自己有一個task,不算神,但日常來說還是挺方便。livereload+sass自動編譯+簡易webserver。
從編輯器複製來的,湊活看吧,,,
var gulp = require("gulp"),
sass = require("gulp-sass"), sourcemaps = require("gulp-sourcemaps"), server = require("gulp-server-livereload");gulp.task("start", function() {
gulp.src("stylesheet/style.scss") .pipe(sourcemaps.init()) .pipe(sass().on("error", sass.logError)).pipe(sourcemaps.write("./map"))
.pipe(gulp.dest("./stylesheet"));gulp.src("stylesheet/style2.scss")
.pipe(sourcemaps.init()) .pipe(sass().on("error", sass.logError)) .pipe(sourcemaps.write("./map")).pipe(gulp.dest("./stylesheet"));
});gulp.task("default", ["webserver"], function() {
gulp.watch(["stylesheet/style.scss", "stylesheet/style2.scss"], ["start"]) .on("change", function(event) { console.log("rebuild "+event.path);});
});gulp.task("webserver", function() {
gulp.src("./") .pipe(server({ defaultFile: "index.html",livereload: {
enable: true, filter: function(filePath, cb) { cb( !(/node_modules/.test(filePath)) );}
} }));});
沒人回答?好,我來。
不是glup黨,所以說說我用的grunt。0 concat 基礎工具。一般來說我覺得它很有用,在開發環境中
1 cssmin 這個task比較牛,自動優化合併css,不是單單的壓縮,還有自動生成css patch,比如你寫transition類css3,會自動為你補上瀏覽器前綴。grunt-contrib 主力維護項目,之前還為它repo過issue
2 requirejs 如果是用AMD 的requirejs 做模塊載入器,首選它作為js壓縮工具,內置的r.js 是專門為requirejs設計的js合併壓縮parser,將define都合併到一個文件里。
3 imagemin node圖片壓縮首選,有幾級level優化,追求pref
4 還有個工具忘記叫什麼名字了, 之前用過, 用來檢索所有項目 HTML 和 CSS 文件, 分析CSS依賴, 自動刪除掉沒有用的CSS, 尤其是大項目, 做這樣的優化很有必要, 在開發過程中, 有些CSS有可能在改了又改之後就沒有地方需要了。jsconf 上有介紹過這個必須是[grunt-usemin](yeoman/grunt-usemin · GitHub)啊,功能很強大,但是配置沒人看得懂!!
front-end-separate(前後端分離腳手架)
front-end-separate
一個前後端分離的腳手架工具(自主研發)
為什麼選擇grunt而不是gulp
如果你也和我一樣喜歡grunt這種配置的方式,那麼我相信這個腳手架覺對十分適合你
所有靜態資源都md5全並壓縮打包,css,js,img,html
已在生產環境驗證
基於express和grunt的前後端分離框架
模板引擎使用的是nunjucks,好處是可以實現模版繼承,又不像jade一樣把html標籤都簡化了
express提供路由服務
項目中app為原代碼文件(開發用),dist為打包後的文件(用於線上)
開發使用app,線上使用dist,支持一鍵cdn部署,加速你的項目
項目啟動時,修改任何express代碼,可以實現自動重啟–基於nodemon
支持sass圖片精靈(自動打包精靈圖片,再也不用手動去拼湊了)
基於grunt md5 打包合併
線上輸出的html已經壓縮成一行(讓你的代碼更有Geeker范)
###怎麼使用:
clone 代碼
啟動命令行:
如果沒有安裝grunt,請先全局安裝grunt bash $ npm i grunt-cli -g 安裝npm包(可能需要一段時間,請耐心等待)
$ npm i
開發模式(可以打開瀏覽器localhost:3001開始開發,埠配置文件里可以更改)
$ grunt
打包
$ grunt build
打包成CDN模式(config/config.js中可配置cdn路徑)
$ grunt buildCdn
browserSync(可以實現更改靜態資源自動刷新了)
$ grunt serve
瀏覽器輸入localhost:3001,你就可以看到漂亮的頁面了
打包命令 grunt build 會生成dist文件夾,裡面可以看到js、css都加了md5綴
tip:scss推薦用Webstorm自帶的File watch功能,非常方便(安裝node-sass即可)
-關於圖片精靈
$ grunt sprite 執行即可得到精靈圖片,如需配置請去config/grunt/sprite.js下配置更多的圖片精靈
在scss中引用@import 「sprite」 樣式中寫如:@include sprite($index_bg); 即可使用;
如果大家喜歡的話,請點一下star此項目或follow一下本人,即是對本人最大的支持
我會繼續完善這個項目的,並一直維護下去,如果有任何問題,歡迎在issues裡面提出
感謝大家支持!
——Nobody
在node中使用gulp,自動刷新browserSync,應該要怎麼引入 入口文件app.js ? -&> nodemon !
// 程序入口
gulp.task("nodemon", function (cb) {
var called = false;
return nodemon({
script: "app.js",
ext: "js",
ignore: ["public/**"],
env: {"NODE_ENV": "development"}
})
.on("start", function onStart() {
if(!called){cb();}
called = true;
})
.on("restart", function() {
setTimeout(function() {
console.log("-------- restart --------");
reload({stream: false});
}, 1000);
});
});
// 監聽變化
gulp.task("browser-sync", ["nodemon"], function(){
browserSync.init({
files: ["public/**","views/**"],
proxy: "http://localhost:3000",
port: 4000,
browser: ["/Applications/Google Chrome Canary.app/"],
notify: true,
});
});
前人的基礎上修改了一下,能做到:
1. 監聽 項目 靜態資源模塊以外 js文件變化(如:修改route文件),重啟服務 自動刷新頁面。2. 監聽 模板文件,靜態資源文件變化,自動刷新頁面。其他 task 可以根據項目情況,自主選擇加入。默默打個廣告(內心:宣傳的好機會!)
前幾天寫了一個gulp插件,作用是自定義可帶參數的task命令(不是來自命令行的參數)感覺應該有點用,不要臉地推一下首先是 github 地址:GitHub - CJY0208/gulp-foal: Allow you to run task with param (NOT from cmd) when gulp"s running.上用法示例"use strict";
var gulp = require("gulp");
var clean = require("gulp-clean");
var foal = require("gulp-foal");
//使用 foal.task(...) 來定義一個 foal 任務
foal.task("clean_some", function(cleanPath) {
//為了順序執行 foal 任務,請別省略 return 語句
return gulp.src(cleanPath)
.pipe(clean());
});
gulp.task("default", function(cb) {
//使用 foal.run(...) 來執行帶參數(當然也可以不帶)的 foal 任務
foal.run(clean_some("test_path"), cb);
});
foal.run(task1("param"), [task2("param"), task3()], task4("param"), cb);
gulp-sequence地址: GitHub - teambition/gulp-sequence: Run a series of gulp tasks in order
關於foal.task(...)
foal 任務默認被綁定在全局環境下, 如果不希望這樣,可以指定bindToFoal參數foal.task("test", {
bindToFoal: true
}, function(param) {/*...*/});
foal.run(foal.test(param));
我做了一個簡單的方案,針對單頁面的js和css打包處理,對當前項目侵入少,我的方案https://github.com/saopang/gulp-page,支持base64,支持雪碧圖,md5改了3處源碼,js支持簡單的合併壓縮混淆方案,也支持webpack打包,支持es6,歡迎star,京東的jdf和百度的fis和騰訊的tmt都是基於項目的打包方案,適合他們公司自己,但使用起來麻煩而且對國內開源項目沒有信心,網上的方案五花八門 。總結了下用useref的可配置性不強,用gulprev配合其他插件的md5會有文件冗餘,而且很多的sourcemap也有問題,我的方案是單獨放到一個dist目錄,發布到線上就刪掉maps目錄,既不會泄露源碼又方便調試。主要是對網上很多方案失望,不適合自己的項目,所以自己做了一個,歡迎大家提建議!
後端nodejs,項目構建工具grunt,模塊打包webpack。
之前,每次改動伺服器js代碼後,都要手動重啟伺服器,真是疼;
之前,每次改動邏輯代碼後,都要重新打包js,真是疼;之前,每次改動css後,都要刷新瀏覽器,真是疼;現在,一切都是自動化,一切都是所見即所得,以下 ,是我的app項目自動化配置。
文件壓縮跟加密webpack都能幹,grunt主要是監測文件改動。var path = require("path");
var webpack = require("webpack");var webpackConfig = require("./project/webpack.config.js");module.exports = function (grunt) {
grunt.initConfig({ pkg: grunt.file.readJSON("package.json"), react: { dynamic_mappings: { files: [ { expand: true, cwd: "project/js", src: ["*.js"], dest: "project/src", ext: ".js" } ] } },uglify: {
options: { banner: "/*! &<%= pkg.name %&> &<%= grunt.template.today("yyyy-mm-dd") %&> */" }, build: { // Grunt will search for "**/*.js" under "lib/" when the "uglify" task // runs and build the appropriate src-dest file mappings then, so you // don"t need to update the Gruntfile when files are added or removed. files: [ { expand: true, // Enable dynamic expansion. cwd: "project/", // Src matches are relative to this path. src: ["bundle.js"], // Actual pattern(s) to match. dest: "project/", // Destination path prefix. ext: ".min.js", // Dest filepaths will have this extension. } ] } },
jshint: {
files: ["project/src/*.js"], options: { globals: { exports: true } } },cssmin: {
options: { banner: "/*! &<%= pkg.name %&> &<%= grunt.template.today("yyyy-mm-dd") %&> */" }, dynamic_mappings: { // Grunt will search for "**/*.js" under "lib/" when the "uglify" task // runs and build the appropriate src-dest file mappings then, so you // don"t need to update the Gruntfile when files are added or removed. files: [ { expand: true, // Enable dynamic expansion. cwd: "project/css", // Src matches are relative to this path. src: ["*.css"], // Actual pattern(s) to match. dest: "project/build", // Destination path prefix. ext: ".css", // Dest filepaths will have this extension. } ] } },
filerev: {
options: { algorithm: "md5", length: 16 }, files: { expand: true, cwd: "project/", src: ["bundle.js"], dest: "project" } },express: {
options: { port: 3000, background: true }, dev: { options: { script: "./project/app.js", } } },webpack: {
options: webpackConfig, dev: { devtool: "sourcemap", debug: true } },watch: {
connect: { files: ["project/*.js", "project/libs/*.js", "project/views/*.ejs", "project/public/css/*.css"], options: { livereload: true } }, webpack: { files: ["project/libs/*.js", "project/webpack.config.js"], tasks: ["webpack:dev"], options: { spawn: false, } }, express: { files: ["project/app.js", "project/server/*.js"], tasks: ["express:dev"], options: { spawn: false } } } }); // grunt.loadNpmTasks("grunt-react"); // grunt.loadNpmTasks("grunt-contrib-uglify"); // grunt.loadNpmTasks("grunt-contrib-jshint"); // grunt.loadNpmTasks("grunt-contrib-cssmin"); // grunt.loadNpmTasks("grunt-contrib-connect"); // grunt.loadNpmTasks("grunt-contrib-imagemin"); // grunt.loadNpmTasks("grunt-usemin"); // grunt.loadNpmTasks("grunt-filerev"); grunt.loadNpmTasks("grunt-webpack"); grunt.loadNpmTasks("grunt-contrib-watch"); grunt.loadNpmTasks("grunt-express-server"); grunt.registerTask("default", ["webpack:dev", "express", "watch"]);};怒答一記~
從Material-ui項目里學習到的整個gulp- 提取出來了,針對jsx(es6),用到了babel browserify
- 沒有添加css預處理,可以自行添加sass或者less...
- uglify在最終build的時候把注釋去掉,就能用了喲~
github地址 : https://github.com/dcalsky/gulp-jsx-es6
star了以後建構項目就不yeoman自動生成的gulp了(雖然可以自己寫,但是肯定沒這麼好噠)推薦閱讀:
※前端框架可以直接使用,為何需要nodejs/gulp等工具?
TAG:JavaScript | 編程 | Nodejs | grunt | gulp |