摘要:默認排除語法的弊端有個時候我們需要時用排除已經壓縮過的,等。主要用兩個屬性來描述文件,它們分別是路徑及內容。判斷函數接受一個文件對象,返回一個值。官方例子僅壓縮符合條件的文件,丹斯所有文件包括不符合條件的都會被發送到目錄。
gulp默認排除語法的弊端
有個時候我們需要時用gulp排除已經壓縮過的js,css等。如果以壓縮文件是以".min.js"之類命名規范的還好,如果不是呢?而且還有其他一些場景也會有需要。
gulp默認支持glob格式,排除語法為!
舉幾個例子:
排除目錄
gulp.src([ baseDir + "/**", // Include all "!" + baseDir + "/excl1{,/**}", // Exclude excl1 dir "!" + baseDir + "/excl2/**/!(.gitignore)", // Exclude excl2 dir, except .gitignore ], { dot: true });
排除文件:
gulp.src(["css/**/!(ignore.css)*.css"]) gulp.src([ "!css/ignnore.css", "css/*.css" ])
這確實能夠排除一些文件。但是還不算強大,不能滿足一些復雜的場景。
而且還存在這樣一個問題:當我有一個jquery.min.js,在壓縮js時,我不想對它進行壓縮,但同時我又想將其輸出到dist目錄下。單純采用上面這種方式需要"曲線救國",場景如下:
gulp.task("jsmin", function (cb) { return gulp.src([SRC_DIR+"/**/*.js",,"!"+SRC_DIR+"/**/*.min.js"]) .pipe(sourcemaps.init()) .pipe(uglify({mangle: {except: ["require" ,"exports" ,"module" ,"$"]}})) //排除混淆關鍵字 .pipe(sourcemaps.write(".")) .pipe(gulp.dest(DEST_DIR)); });
很遺憾地告訴你,*.min.js并沒有被拷貝到DEST_DIR,當然曲線救國可以如下:
gulp.task("copy", () =>{ return gulp.src([SRC_DIR+"/**/*.min.js"]) .pipe(gulp.dest(DEST_DIR)); } );
但是,這不是很優雅。而且上面我們也說了只是采用glob語法對文件進行排除不適用于復雜的場景。
Vinyl文件系統詳細說明,請參考探究Gulp的Stream
現在這里貼出,后面會說明其目的。
雖然Gulp使用的是Stream,但卻不是普通的Node Stream,實際上,Gulp(以及Gulp插件)用的應該叫做Vinyl File Object Stream。
這里的Vinyl,是一種虛擬文件格式。Vinyl主要用兩個屬性來描述文件,它們分別是路徑(path)及內容(contents)。具體來說,Vinyl并不神秘,它仍然是JavaScript Object。Vinyl官方給了這樣的示例:
var File = require("vinyl"); var coffeeFile = new File({ cwd: "/", base: "/test/", path: "/test/file.coffee", contents: new Buffer("test = 123") });
從這段代碼可以看出,Vinyl是Object,path和contents也正是這個Object的屬性。
解決方案描述:可以采用gulp插件來實現更為強大的排除。主要有以下幾個插件:
gulp-ignore,支持通過boolean,stat對象,函數來判斷是否排除與包含。判斷函數接受一個Vinyl文件對象,返回一個boolean值。
gulp-filter,支持glob模式、函數過濾,以及過濾后恢復
gulp-if,支持條件判斷(支持函數條件)來控制相關流程。
下面具體說明如何使用
API
exclude(condition [, minimatchOptions])
Exclude files whose file.path matches, include everything else
include(condition [, minimatchOptions])
Include files whose file.path matches, exclude everything else
參數說明:
condition:類型可以為 boolean or stat object or function
當為函數是接受一個vinyl file返回boolean值
下面貼出官方例子:
var gulpIgnore = require("gulp-ignore"); var uglify = require("gulp-uglify"); var jshint = require("gulp-jshint"); var condition = "./gulpfile.js"; gulp.task("task", function() { gulp.src("./**/*.js") .pipe(jshint()) .pipe(gulpIgnore.exclude(condition)) .pipe(uglify()) .pipe(gulp.dest("./dist/")); });
var gulpIgnore = require("gulp-ignore"); var uglify = require("gulp-uglify"); var jshint = require("gulp-jshint"); var condition = "./public/**.js"; gulp.task("task", function() { gulp.src("./**/*.js") .pipe(jshint()) .pipe(gulpIgnore.include(condition)) .pipe(uglify()) .pipe(gulp.dest("./dist/")); });
實現:
var condition = function(f){ if(f.path.endswith(".min.js")){ return true; } return false }; gulp.task("jsmin", function (cb) { return gulp.src([SRC_DIR+"/**/*.js"]) .pipe(gulpIgnore.exclude(condition)) .pipe(sourcemaps.init()) .pipe(uglify({mangle: {except: ["require" ,"exports" ,"module" ,"$"]}})) //排除混淆關鍵字 .pipe(sourcemaps.write(".")) .pipe(gulp.dest(DEST_DIR)); });
優點:很明顯,你可以在條件函數中做你想做的任何事情,包括使用正則表達式等。
缺點:和默認情況一樣,不支持被排除文件的拷貝
和gulp-ignore作者是同一個人
API:
gulpif(condition, stream [, elseStream, [, minimatchOptions]])
gulp-if will pipe data to stream whenever condition is truthy.
If condition is falsey and elseStream is passed, data will pipe to elseStream
這就類似于三目運算符,功能用偽代碼表示就是if condition then stream(data) else elseStream(data)
After data is piped to stream or elseStream or neither, data is piped down-stream.
參數說明:
condition 與gulp-ignore一致。
Type: boolean or stat object or function that takes in a vinyl file and returns a boolean or RegularExpression that works on the file.path
stream
Stream for gulp-if to pipe data into when condition is truthy.
elseStream
Optional, Stream for gulp-if to pipe data into when condition is falsey.
minimatchOptions
Optional, if it"s a glob condition, these options are passed to minimatch.
官方例子:
var gulpif = require("gulp-if"); var uglify = require("gulp-uglify"); var condition = true; // TODO: add business logic gulp.task("task", function() { gulp.src("./src/*.js") .pipe(gulpif(condition, uglify())) .pipe(gulp.dest("./dist/")); });
Only uglify the content if the condition is true, but send all the files to the dist folder
僅壓縮符合條件的文件,丹斯所有文件(包括不符合條件的)都會被發送到dist目錄。
實現:
var condition = function(f){ if(f.path.endswith(".min.js")){ return false; } return true; }; gulp.task("jsmin", function (cb) { return gulp.src([SRC_DIR+"/**/*.js"]) .pipe(sourcemaps.init()) .pipe(gulpif(condition, uglify({mangle: {except: ["require" ,"exports" ,"module" ,"$"]}}))) //排除混淆關鍵字 .pipe(sourcemaps.write(".")) .pipe(gulp.dest(DEST_DIR)); });gulp-filter
API
filter(pattern, [options])
Returns a transform stream with a .restore object.
參數說明:
pattern
Type: string, array, function
Accepts a string/array with globbing patterns which are run through multimatch.
如果是函數,則應該接受一個 vinyl file object作為第一個參數,return true/false whether to include the file:
filter(file => /unicorns/.test(file.path));
選項options
Type: object
Accepts minimatch options.
Note: Set dot: true if you need to match files prefixed with a dot (eg. .gitignore).
options.restore
Type: boolean
Default: false
Restore filtered files.
options.passthrough
Type: boolean
Default: true
When set to true filtered files are restored with a PassThrough stream, otherwise, when set to false, filtered files are restored as a Readable stream.
官方例子:
const gulp = require("gulp"); const uglify = require("gulp-uglify"); const filter = require("gulp-filter"); gulp.task("default", () => { // create filter instance inside task function const f = filter(["**", "!*src/vendor"], {restore: true}); return gulp.src("src/**/*.js") // filter a subset of the files .pipe(f) // run them through a plugin .pipe(uglify()) // bring back the previously filtered out files (optional) .pipe(f.restore) .pipe(gulp.dest("dist")); }); gulp.task("defaultmulti", () => { const jsFilter = filter("**/*.js", {restore: true}); const lessFilter = filter("**/*.less", {restore: true}); return gulp.src("assets/**") .pipe(jsFilter) .pipe(concat("bundle.js")) .pipe(jsFilter.restore) .pipe(lessFilter) .pipe(less()) .pipe(lessFilter.restore) .pipe(gulp.dest("out/")); });
實戰:
var condition = function(f){ if(f.path.endswith(".min.js")){ return false; } return true; }; const jsFilter = filter(condition, {restore: true}); gulp.task("jsmin", function (cb) { return gulp.src([SRC_DIR+"/**/*.js"]) .pipe(jsFilter) .pipe(sourcemaps.init()) .pipe(uglify({mangle: {except: ["require" ,"exports" ,"module" ,"$"]}})) //排除混淆關鍵字 .pipe(sourcemaps.write(".")) .pipe(jsFilter.restore) .pipe(gulp.dest(DEST_DIR)); });
部分文件被壓縮,所有文件都會被發送到DEST_DIR
小結如何選擇?
gulp-if:可以完美解決問題,且足夠優雅。
gulp-filter:可以完美解決問題,但是相比gulp-if略顯麻煩。更復雜的場景下用gulp-filter比gulp-if方便。
gulp-ignore:更為強大的過濾,在僅僅只是過濾而不拷貝的情況下首推。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/91330.html
摘要:通常情況下我們不需要用到。為任務名請不要在名字中使用空格是當前定義的任務需要依賴的其他任務,為一個數組。為要監視的文件匹配模式,規則和用法與方法中的相同。 1.gulp安裝 1.首先確保你已經正確安裝了nodejs環境。然后可以全局方式安裝gulp: $ npm install -g gulp 我們可以檢查一下gulp版本 $ gulp -v 這樣就完成了對全局的安裝2.如果想在安裝的...
摘要:通常情況下我們不需要用到。為任務名請不要在名字中使用空格是當前定義的任務需要依賴的其他任務,為一個數組。為要監視的文件匹配模式,規則和用法與方法中的相同。 1.gulp安裝 1.首先確保你已經正確安裝了nodejs環境。然后可以全局方式安裝gulp: $ npm install -g gulp 我們可以檢查一下gulp版本 $ gulp -v 這樣就完成了對全局的安裝2.如果想在安裝的...
摘要:通常情況下我們不需要用到。為任務名請不要在名字中使用空格是當前定義的任務需要依賴的其他任務,為一個數組。為要監視的文件匹配模式,規則和用法與方法中的相同。 1.gulp安裝 1.首先確保你已經正確安裝了nodejs環境。然后可以全局方式安裝gulp: $ npm install -g gulp 我們可以檢查一下gulp版本 $ gulp -v 這樣就完成了對全局的安裝2.如果想在安裝的...
摘要:其中使用代碼如下部分丑化代碼注意路徑的寫法合并所有到壓縮后的文件名丑化代碼,相當加密排除關鍵字注意路徑的寫法 為什么使用 最近在迭代公司的項目,發現項目有如下缺點: 代碼沒有壓縮,js文件,內存大,放在服務器上占空間; 源代碼沒有混淆或者丑化處理,本公司的程序員寫出來的代碼和高質量邏輯容易被其他公司的程序員盜用; js,css 文件數量多,瀏覽器加載起來會手忙腳亂和生氣。 這個小項...
閱讀 3569·2021-11-18 13:20
閱讀 2727·2021-10-15 09:40
閱讀 1740·2021-10-11 10:58
閱讀 2107·2021-09-27 13:36
閱讀 2586·2021-09-07 10:06
閱讀 1848·2021-08-11 11:21
閱讀 1425·2019-08-29 17:04
閱讀 2080·2019-08-29 14:06