免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
常用gulp插件介紹(一)

在寫(xiě)generator-aio-angular的過(guò)程中,gulp這一塊發(fā)現(xiàn)了很多非常實(shí)用的插件,大大的增加了能自動(dòng)化的范圍,這篇文章就分門(mén)別類(lèi)的簡(jiǎn)單介紹下常用的gulp插件吧。

util工具類(lèi)

這個(gè)分類(lèi)下主要介紹一些輔助工具類(lèi)的插件。

gulp-load-plugins

顧名思義,本插件的功能就是幫你自動(dòng)require你在package.json中聲明的依賴(lài)。只要一句var $ = require('gulp-load-plugins')(),則package.json中聲明的gulp-gulp.開(kāi)頭的插件就會(huì)自動(dòng)被放在變量$下面。如$.util就等于require('gulp-util'),而有兩個(gè)連字符的插件則會(huì)自動(dòng)命名為駝峰格式,如$.taskListing則等于require('gulp-task-listing')。有了這個(gè)插件,就不用一個(gè)一個(gè)的require了。這個(gè)插件還有一些常用的參數(shù)配置,這里列幾個(gè)常用的:

  • lazyload: true,用到這個(gè)插件的時(shí)候再去require,默認(rèn)為true。
  • rename: {'gulp-task-listing': 'list'},如果有些插件名字太長(zhǎng),可以使用該參數(shù)重命名。
  • scope: ['dependencies'],本插件默認(rèn)會(huì)掃描package.json里的所有dependence,可以使用該參數(shù)進(jìn)行限制。

要使用這些參數(shù)只要在require的時(shí)候傳入即可,如require('gulp-load-plugins')({lazy: true})

gulp-task-listing

這個(gè)插件的作用也很容易猜,它可以打印出gulpfile.js中定義的所有task,這個(gè)插件我們?cè)?a target="_blank" style="background-color: transparent; color: rgb(34, 34, 34); border-bottom: 1px solid rgb(153, 153, 153);">重構(gòu)你的gulpfile這篇文章的最后介紹過(guò),值得一提的是它還可以根據(jù)task的名字確定它是不是一個(gè)子task,比如帶有:-、_的task就被認(rèn)為是子task。我一般把這個(gè)插件作為默認(rèn)的task來(lái)調(diào)用,如

1
2
gulp.task('default', ['help']);
gulp.task('help', $.taskListing);

這樣,如果只執(zhí)行gulp的話(huà)就會(huì)打印出所有定義好的task,非常實(shí)用。

yargs

嚴(yán)格的說(shuō),yargs不是專(zhuān)門(mén)用于gulp的,它是Node中處理命令行參數(shù)的通用解決方案。只要一句代碼var args = require('yargs').argv;就可以讓命令行的參數(shù)都放在變量args上,非常方便。它可以處理的參數(shù)類(lèi)型也是多種多樣的:

  • 單字符的簡(jiǎn)單參數(shù),如傳入-m=5-m 5,則可得到args.m = 5
  • 多字符參數(shù)(必須使用雙連字符),如傳入--test=5--test 5,則可得到args.test = 5。
  • 不帶值的參數(shù),如傳入--mock,則會(huì)被認(rèn)為是布爾類(lèi)型的參數(shù),可得到args.mock = true

除此之外,還支持很多其他類(lèi)型的傳參方式,具體可參考它的文檔。

gulp-util

gulp-util帶有很多方便的函數(shù),其中最常用的應(yīng)該就是log了。$.util.log()支持傳入多個(gè)參數(shù),打印結(jié)果會(huì)將多個(gè)參數(shù)用空格連接起來(lái)。它與console.log的區(qū)別就是所有$.util.log的結(jié)果會(huì)自動(dòng)帶上時(shí)間前綴。另外,它還支持顏色,如$.util.log($.util.colors.magenta('123'));打印出來(lái)的123是品紅色的。其實(shí)$.util.colors就是一個(gè)chalk的實(shí)例,而chalk是專(zhuān)門(mén)用來(lái)處理命令行打印著色的一個(gè)工具。

del

grunt自身提供一個(gè)grunt-contrib-clean用來(lái)處理支持glob匹配的刪除,而del就是gulp上對(duì)應(yīng)的工具。del支持和gulp.src參數(shù)同樣的匹配,除此之外,它的第二個(gè)參數(shù)還支持一個(gè)回調(diào)函數(shù),當(dāng)刪除完成以后執(zhí)行,所以這是一個(gè)異步的刪除。常用的調(diào)用方法為:del([xxx], callback)。

gulp-bytediff

這是一個(gè)統(tǒng)計(jì)文件大小變化的工具,通常與壓縮類(lèi)工具放在一起實(shí)用,比如

1
2
3
4
5
6
7
8
9
10
11
12
13
gulp.src('**/*.html')
.pipe($.bytediff.start())
.pipe($.minifyHtml({empty: true}))
.pipe($.bytediff.stop(bytediffFormatter))
.pipe(gulp.dest('dist'));
function bytediffFormatter (data) {
var difference = (data.savings > 0) ? ' smaller.' : ' larger.';
return data.fileName + ' went from ' +
(data.startSize / 1000).toFixed(2) + ' kB to ' +
(data.endSize / 1000).toFixed(2) + ' kB and is ' +
formatPercent(1 - data.percent, 2) + '%' + difference;
}

在壓縮的pipe前后加上$.bytediff.start()$.bytediff.stop(callback),即可統(tǒng)計(jì)壓縮前后文件的變化。在callback中傳入的參數(shù)data上,可以訪問(wèn)到很多變量,如文件名,變化前后的大小,變化百分比等等。

gulp-print

這個(gè)插件的作用很簡(jiǎn)單,打印出stream里面的所有文件名,通常調(diào)試的時(shí)候比較需要。

gulp-bump

這個(gè)插件也可以顧名思義:用來(lái)升級(jí)版本用的,廢話(huà)不說(shuō),直接看例子吧:

1
2
3
4
return gulp
.src('package.json')
.pipe($.bump(options))
.pipe(gulp.dest('dist'));

重點(diǎn)來(lái)看這里的options,我們可直接傳遞一個(gè)具體的version進(jìn)去,也可以按照Node的版本規(guī)范傳遞一個(gè)type進(jìn)去,讓其自己生成對(duì)應(yīng)的version:

  • version,直接傳遞要升級(jí)到的版本號(hào),如1.2.3
  • type,可接受的值包括下面四個(gè),倘若現(xiàn)在的版本號(hào)為1.2.3,則對(duì)應(yīng)的新版本號(hào)為:
    • prerelease:1.2.3-0
    • patch:1.2.4
    • minor:1.3.0
    • major:2.0.0

最終這個(gè)升級(jí)后的版本號(hào)會(huì)反映在package.json中,當(dāng)然,你也可以在gulp.src中傳入更多的文件(如bower.json)來(lái)替換更多的文件。

gulp-header

這個(gè)工具用來(lái)在壓縮后的JS、CSS文件中添加頭部注釋?zhuān)憧梢园我庀胍男畔?,通常就是作者、描述、版本?hào)、license等,比如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getHeader () {
var pkg = require('package.json');
var template = ['/**',
' * <%= pkg.name %> - <%= pkg.description %>',
' * @authors <%= pkg.authors %>',
' * @version v<%= pkg.version %>',
' * @link <%= pkg.homepage %>',
' * @license <%= pkg.license %>',
' */',
''
].join('\n');
return $.header(template, {
pkg: pkg
});
}

這個(gè)函數(shù)將package.json中的各種信息提取出來(lái),變成頭部注釋?zhuān)灰趬嚎s的pipe中調(diào)用.pipe(getHeader())即可。

stream相關(guān)

這個(gè)部分主要介紹一些跟stream操作有關(guān)的插件。

gulp-filter

gulp-filter可以把stream里的文件根據(jù)一定的規(guī)則進(jìn)行篩選過(guò)濾。比如gulp.src中傳入匹配符匹配了很多文件,可以把這些文件pipe給gulp-filter作二次篩選,如gulp.src('**/*.js').pipe($.filter(**/a/*.js)),本來(lái)選中了所有子文件下的js文件,經(jīng)過(guò)篩選后變成名為a的子文件夾下的js文件。那有人要問(wèn)了,為什么不直接將需要的篩選傳入gulp.src,干嘛要多篩選一步呢?這里面有兩種情況:

  • gulp.src$.filter中間可能需要?jiǎng)e的處理,比如我對(duì)所有文件做了操作1以后,還需要篩選出一部分做操作2。
  • 第二種情況就要談到gulp-filter的另外一個(gè)特性:篩選之后還可以restore回去。比如我對(duì)所有文件做了操作1,篩選了一部分做操作2,最后要把所有的文件都拷貝到最終的位置。代碼如下:
1
2
3
4
5
6
7
var filter = $.filter('**/a/*.js');
gulp.src('**/*.js')
.pipe(action1())
.pipe(filter)
.pipe(action2())
.pipe(filter.restore())
.pipe(gulp.dest('dist'))

可以看到,如果沒(méi)有restore這個(gè)操作,那么拷貝到最終位置的文件將只包含被過(guò)濾出來(lái)的文件,這樣一restore,所有的文件都被拷貝了。

gulp-flatten

gulp-flatten非常實(shí)用,可能知道別的庫(kù)中flatten函數(shù)的同學(xué)已經(jīng)猜到它是干嘛的了。比如gulp.src('**/*.js')匹配了很多文件,包括a/b/c.js,d/e.jsf/g/h/i/j/k.js,l.js,這些文件的層級(jí)都不一樣,一旦我們將這個(gè)文件pipe給$.flatten(),則所有的文件夾層級(jí)都會(huì)去掉,最終的文件將是c.jse.js,k.js,l.js,在一些場(chǎng)景下還是非常有用的。

gulp-plumber

這個(gè)插件的作用簡(jiǎn)單來(lái)說(shuō)就是一旦pipe中的某一steam報(bào)錯(cuò)了,保證下面的steam還繼續(xù)執(zhí)行。因?yàn)閜ipe默認(rèn)的onerror函數(shù)會(huì)把剩下的stream給unpipe掉,這個(gè)插件阻止了這種行為。那它一般用于哪種場(chǎng)景呢?比如,代碼每次build之前要跑一遍jshint和jscs來(lái)確保所有代碼都符合規(guī)范,但一旦某些代碼不符合規(guī)范,整個(gè)build流程就會(huì)停止,這個(gè)時(shí)候就需要gulp-plumber出場(chǎng)了。如:

1
2
3
4
5
6
7
8
gulp.task('build', ['jslint', 'xxxx']);
gulp.task('jslint', function () {
return gulp
.src(config.js.all)
.pipe($.plumber())
.pipe($.jshint())
.pipe($.jscs());
});

這樣,一旦jshint或jscs報(bào)錯(cuò),整個(gè)build流程還是可以繼續(xù)走下去的,而且gulp-plumber會(huì)給出一個(gè)報(bào)錯(cuò)提醒我們:

1
2
3
4
[16:52:36] Plumber found unhandled error:
Error in plugin 'gulp-jshint'
Message:
JSHint failed for: xxxx.js

gulp-if

這個(gè)插件的功能也很簡(jiǎn)單,可以條件性的添加stream,如.pipe($.if(flag, action1())),則只會(huì)在flag變量為true時(shí)才會(huì)將action1()添加到stream中去。其實(shí)不用這個(gè)插件也可以達(dá)到類(lèi)似的效果,那就是gulp-util里有一個(gè)函數(shù)叫做noop(),也就是no operation,這個(gè)函數(shù)其實(shí)是返回一個(gè)什么都不干的空stream。利用這個(gè)函數(shù)我們可以這么寫(xiě):.pipe(flag ? action1() : $.util.noop()),與上例的效果是一樣的。

merge-stream

一個(gè)gulp的task只能返回一個(gè)stream,但有的時(shí)候有這么一種情景:有兩類(lèi)文件,它們的原始位置和處理后的位置都是不同的,但它們的處理流程相同。由于gulp.srcgulp.dest的參數(shù)不同,我們就需要寫(xiě)兩個(gè)task來(lái)分別完成這個(gè)任務(wù),一方面略顯重復(fù),另一方面邏輯上來(lái)講這兩個(gè)task本來(lái)就是處理同樣的事情的。這種情況就需要merge-stream登場(chǎng)了,它的作用就是將多個(gè)stream合成一個(gè)返回。比如下面這個(gè)例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
var merge = require('merge-stream');
gulp.task('jade', function () {
var stream1 = jade(src1, dest1);
var stream2 = jade(src2, dest2);
return merge(stream1, stream2);
});
function jade (src, dest) {
return gulp
.src(src)
.pipe($.jade())
.pipe(gulp.dest(dest));
}

可以看到,處理的流程被提取出來(lái)放入一個(gè)函數(shù),它接受兩個(gè)參數(shù),分別是src和dest。然后在task中直接調(diào)用這個(gè)函數(shù)生成兩個(gè)stream,然后返回merge-stream合并后的結(jié)果。

run-sequence

gulp里的task都是異步并發(fā)執(zhí)行的,有的時(shí)候我們需要一連串的task按順序執(zhí)行,這時(shí)就需要run-sequence登場(chǎng)了。它的調(diào)用很簡(jiǎn)單:runSequence('task1', 'task2', ['task3', 'task4'], 'task5'),這里的task都是gulp定義好的task名稱(chēng),task1完成后才會(huì)執(zhí)行task2,以此類(lèi)推。注意到task3和task4被放在中括號(hào)里了,這表明,task3和task4可以并發(fā)執(zhí)行的,但兩個(gè)都執(zhí)行完后才會(huì)執(zhí)行task5。這里要說(shuō)明的是,每個(gè)task要么返回一個(gè)stream,即return gulp.src().pipe().pipe(),要么支持回調(diào)函數(shù),即gulp.task('task1', function (done) { action1(done); }),滿(mǎn)足了這兩點(diǎn)才能保證正常的執(zhí)行順序,因?yàn)檫@是gulp對(duì)異步task的基本要求

inject相關(guān)

這個(gè)部分主要介紹一些將JS/CSS自動(dòng)插入到HTML的相關(guān)插件。

wiredep

wiredep就是wire dependence的意思,它的作用就是把bower.json中聲明的dependence自動(dòng)的包含到HTML中去。要插入文件,wiredep需要解決兩個(gè)問(wèn)題:

  • 插入的位置:wiredep通過(guò)識(shí)別HTML中的注釋來(lái)識(shí)別插入位置,如
1
2
3
4
<!-- bower:css -->
<!-- endbower -->
<!-- bower:js -->
<!-- endbower -->

不同類(lèi)型的文件被插入到不同的區(qū)塊。

  • 插入什么文件:要插入的文件列表自然來(lái)自bower.json,每個(gè)bower安裝的依賴(lài)庫(kù),根目錄下邊都有一個(gè)自己的bower.json文件,其中的main字段指明了使用這個(gè)庫(kù)需要包含的文件,wiredep最終包含的文件列表就來(lái)自這個(gè)字段。有些情況下,庫(kù)自身的bower.json的main字段可能會(huì)多包含文件或少包含文件,如果想要定制這個(gè)列表,則可以在自己的bower.json中使用overrides字段,如下面的代碼覆蓋了mdi這個(gè)庫(kù)的main字段。
1
2
3
4
5
6
7
"overrides": {
"mdi": {
"main": [
"css/materialdesignicons.css"
]
}
},

wiredep插件支持很多參數(shù),常用的主要有兩個(gè):

  • bowerJson:指定bower.json的內(nèi)容,注意這個(gè)字段不是bower.json文件的位置,這個(gè)參數(shù)需要使用require后的結(jié)果賦值:require('bower.json')。
  • directory:指定存放bower安裝后的依賴(lài)包的路徑,通常是bower_components。注意最終插入到HTML中的文件列表的路徑是index.html文件相對(duì)于本文件夾的相對(duì)路徑。

使用wiredep也比較簡(jiǎn)單,直接把它傳入到stream中即可,如gulp.src('index.html').pipe(wiredep(options))。

gulp-inject

這個(gè)插件的作用與wiredep類(lèi)似,不同的是可以自己任意指定需要插入文件的列表。它同樣是利用注釋來(lái)尋找插入的位置,它識(shí)別的默認(rèn)注釋為<!-- inject:js -->,但更加智能

  • 支持各種模板語(yǔ)言:可以根據(jù)gulp.src指定的源文件自動(dòng)識(shí)別注釋和插入內(nèi)容,除了支持HTML外,還支持jade、haml等。若源為jade文件,則識(shí)別的注釋為//- inject:js,插入的內(nèi)容為:script(src="<filename>.js")
  • 配置非常靈活:
    • name:默認(rèn)識(shí)別的注釋標(biāo)簽格式為<!-- name:ext -->,這里的name默認(rèn)值就是“inject”,而ext的默認(rèn)值是要插入的文件的擴(kuò)展名。那么name屬性可配置意味著可以添加自定義的插入?yún)^(qū)塊,如<!-- production:js -->,這個(gè)標(biāo)簽可以只插入生產(chǎn)環(huán)境需要包含的JS文件。
    • starttag和endtag:支持自定義需要識(shí)別的注釋內(nèi)容。
    • addPrefix和addSuffix:支持在插入文件的路徑上自定義前綴、后綴。
    • relative:指定插入文件的路徑是否為相對(duì)路徑。
    • ingorePath:指定插入文件的路徑前面會(huì)忽略掉指定的路徑。
    • read:這個(gè)參數(shù)通常給false,不需要真正的去讀取文件。

這個(gè)插件的使用場(chǎng)景通常是,我們需要index里有多個(gè)區(qū)塊,比如上面name的例子,只有當(dāng)為production環(huán)境編譯的時(shí)候才去包含相關(guān)的文件。

gulp-useref 與 gulp-rev、gulp-rev-replace

這三個(gè)工具之所以放在一起講,是因?yàn)樗鼈円话愣际且黄鹗褂玫摹K鼈円鉀Q什么問(wèn)題呢?通過(guò)上面的wiredep也好,gulp-inject也好,插入了一堆JS、CSS文件到HTML中,一旦部署到生產(chǎn)環(huán)境,這么多文件必然是要合并壓縮的。光是壓縮還不夠,為了解決緩存問(wèn)題,每次合并壓縮后要給最終的文件加hash,這樣每次文件內(nèi)容一變動(dòng),hash也會(huì)跟著變動(dòng),就不存在瀏覽器依然使用緩存的老文件的問(wèn)題。這樣得到最終的文件以后,肯定還要將這個(gè)文件替換回HTML中去,一大堆的script和link標(biāo)簽替換成最終合并壓縮帶hash的版本。

前面啰啰嗦嗦的一大堆工作就是這三個(gè)插件要解決的問(wèn)題了。首先,gulp-useref根據(jù)注釋將HTML中需要合并壓縮的區(qū)塊找出來(lái),對(duì)區(qū)塊內(nèi)的所有文件進(jìn)行合并。注意:它只負(fù)責(zé)合并,不負(fù)責(zé)壓縮!所以合并出來(lái)的文件我們要自行壓縮,壓縮以后調(diào)用gulp-rev負(fù)責(zé)在文件名后追加hash。最后調(diào)用gulp-rev-replace負(fù)責(zé)把最終的文件名替換回HTML中去。扯了大半天,還是直接上例子吧。先來(lái)看看HTML中的注釋?zhuān)?/p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- build:css static/styles/lib.css -->
<!-- bower:css -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:css static/styles/app.css -->
<!-- inject:css -->
<!-- endinject -->
<!-- endbuild -->
<!-- build:js static/js/lib.js -->
<!-- bower:js -->
<!-- endbower -->
<!-- endbuild -->
<!-- build:js static/js/app.js -->
<!-- inject:js -->
<!-- endinject -->
<!-- endbuild -->

gulp-useref識(shí)別的就是build開(kāi)頭的注釋?zhuān)琤uild后面首先跟的是類(lèi)型擴(kuò)展名,然后后面的路徑就是build區(qū)塊中的所有文件進(jìn)行合并后的文件路徑,這個(gè)相對(duì)路徑是相對(duì)于這個(gè)HTML的路徑。上面的例子中我們用build區(qū)塊把bower和inject進(jìn)來(lái)的文件包起來(lái),這些文件就可以被gulp-useref合并了。再來(lái)看gulp中useref相關(guān)task的定義:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
var assets = $.useref.assets({searchPath: 'app/src/'});
var cssFilter = $.filter('**/*.css');
var jsAppFilter = $.filter('**/app.js');
var jslibFilter = $.filter('**/lib.js');
return gulp
.src('index.html')
.pipe(assets)
.pipe(cssFilter)
.pipe($.csso())
.pipe(cssFilter.restore())
.pipe(jsAppFilter)
.pipe($.uglify())
.pipe(getHeader())
.pipe(jsAppFilter.restore())
.pipe(jslibFilter)
.pipe($.uglify())
.pipe(jslibFilter.restore())
.pipe($.rev())
.pipe(assets.restore())
.pipe($.useref())
.pipe($.revReplace())
.pipe(gulp.dest('dist'));

首先一上來(lái),先調(diào)用$.useref.assets()函數(shù),這個(gè)函數(shù)返回一個(gè)stream,包含已經(jīng)合并后的文件??梢試L試在第9行后面加上前面介紹過(guò)的gulp-print插件.pipe($.print()),打印出stream里的文件,發(fā)現(xiàn)就是前面HTML中4個(gè)build注釋塊后面的4個(gè)文件。注意這里調(diào)用的時(shí)候跟了一個(gè)searchPath的參數(shù),它的用處就是指定從哪個(gè)路徑開(kāi)始尋找build區(qū)塊底下的文件。比如build區(qū)塊底下有這么一行<script src="static/js/a.js"></script>,那最終gulp-useref將從這個(gè)路徑app/src/static/js/a.js找到這個(gè)文件。第3到5行定義了3個(gè)filter,這主要是為了后面壓縮準(zhǔn)備的。下面正式看stream的pipe流程。先選出要處理的HTML文件,然后調(diào)用剛才得到的assets得到合并后的4個(gè)文件,第10到12行篩選出合并后的CSS文件進(jìn)行壓縮(壓縮類(lèi)插件下篇文章再講),第13到16行篩選出app.js進(jìn)行壓縮,第17到19行篩選出lib.js進(jìn)行壓縮。之所以要區(qū)別對(duì)待app.js和lib.js,是因?yàn)閍pp.js是我們自己寫(xiě)的代碼,壓縮后要加上header(第15行,使用前面介紹過(guò)的gulp-header插件),而lib.js是第三方的各種庫(kù),直接壓縮即可。后面調(diào)用gulp-rev給壓縮后的4個(gè)文件加hash,然后調(diào)用assets.restore()將src源換回HTML文件,這是為了后面調(diào)用$.useref(),因?yàn)?code style="font-family:"PT Mono",Consolas,Monaco,Menlo,monospace; font-size:1em; background:rgb(238,238,238); padding:0px 0.3em; white-space:pre-wrap; word-break:break-word">$.useref()做替換的src源是HTML文件,同樣后面調(diào)用gulp-rev-replace將帶hash的文件替換回HTML,它要求的src源也必須是HTML文件。這里的順序很重要,因?yàn)檫@幾個(gè)插件接受的源不一樣,gulp-rev接受的是JS、CSS文件,而gulp-useref和gulp-rev-replace接受的是HTML。還有一個(gè)問(wèn)題:gulp-rev-replace是怎么知道gulp-rev進(jìn)行hash前后的文件名對(duì)應(yīng)關(guān)系呢?其實(shí)gulp-rev會(huì)生成一個(gè)manifest的文件,內(nèi)容是類(lèi)似下面的JSON:

1
2
3
4
{
"static/styles/lib.css": "static/styles/lib-d41d8cd98f.css"
"static/js/lib.js": "static/js/lib-273c2cin3f.js"
}

當(dāng)然這個(gè)文件默認(rèn)是不會(huì)生成在文件系統(tǒng)里的,可以通過(guò).pipe($.rev.manifest())將這個(gè)文件保存到本地。有了這個(gè)文件,gulp-rev-replace甚至可以脫離gulp-rev獨(dú)立工作哦!

好了,這篇就到這里,還有好多工具沒(méi)介紹到,留著給下篇吧。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Gulp自動(dòng)添加版本號(hào)
Gulp.js
gulp快速入門(mén)&初體驗(yàn)
gulp基礎(chǔ)教程 | Reeoo's Blog
入門(mén):十分鐘自動(dòng)化構(gòu)建
基于gulp編寫(xiě)的一個(gè)簡(jiǎn)單實(shí)用的前端開(kāi)發(fā)環(huán)境
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服