I'm ashamed to say that , Always using the tools inside the company , I didn't use these red and purple things . Today, we finally got the first one gulp application .gulp What does it do , What's the advantage? I'll stop talking . Get to the point .

First in D Create a xxxx Catalog , Then open the console , Direct will npm install gulp. There's one more inside node_modules Directory installed successfully .

then xxxx Create one under the directory src Catalog , Build a index.html file , The content is as follows or you scribble a little , Our example mainly tests compression html.

<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
</head>
<body>
<h2> Write it at the front </h2>
<p> I wanted to write about how to write gulp Plug in popular science article , All of a sudden, the desire to explore is on again , So there's this article ... Look at the source code <code>gulp.src()</code> The implementation of the , I can't help feeling : It's so complicated ...</p>
<h2> Get to the point </h2>
<p> First of all, let's take a look <code>gulpfile</code> What does it look like , Have much express Is the taste of middleware ~<br /> We know <code>.pipe()</code> It's a typical streaming operation API. Very natural , We will think <code>gulp.src()</code> This API It should be a Stream object ( Maybe through layers of encapsulation ). In order to find out , It took a little time to gulp I've scanned the source code of , We finally found the answer .</p>
<p>gulpfile.js</p>
<pre class="hljs-dark"><code class="hljs javascript"><span class="hljs-keyword">var gulp = <span class="hljs-built_in">require(<span class="hljs-string">'gulp'),
preprocess = <span class="hljs-built_in">require(<span class="hljs-string">'gulp-preprocess'); gulp.task(<span class="hljs-string">'default', <span class="hljs-function"><span class="hljs-keyword">function<span class="hljs-params">() { gulp.src(<span class="hljs-string">'src/index.html')
.pipe(preprocess({USERNAME:<span class="hljs-string">' Program ape little card '}))
.pipe(gulp.dest(<span class="hljs-string">'dest/'));
});
</span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<h2> Advanced spoiler </h2>
<p> Here's the content spoiler , If there's something wrong with the spoiler , Please skip this paragraph by yourself ...</p>
<blockquote>
<p>gulp.src() It's back to customized Stream object . Can be in github On the search <code>ordered-read-streams</code> This project .</p>
<p> The general relationship is :<br />ordered-read-streams --> glob-stream --> vinyl-fs --> gulp.src()</p> </blockquote>
<h2> The way to explore </h2>
<p> First , Let's take a look at <code>require('gulp')</code> Back to what . from gulp The source code of , Back to <code>Gulp</code> object , There are <code>src</code>、<code>pipe</code>、<code>dest</code> Other methods . very good , Found what we wanted <code>src</code> Method . So let's look down <br /> Reference resources :<a href="https://github.com/gulpjs/gulp/blob/master/index.js#L62" target="_blank">https://github.com/gulpjs/gulp/blob/master/index.js#L62</a></p>
<p>gulp/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-keyword">var inst = <span class="hljs-keyword">new Gulp();
<span class="hljs-built_in">module.exports = inst;
</span></span></span></code></pre>
<p> As you can see from the following code ,<code>gulp.src</code> Method , It's actually <code>vfs.src</code>. continue <br /> Reference resources :<a href="https://github.com/gulpjs/gulp/blob/master/index.js#L25" target="_blank">https://github.com/gulpjs/gulp/blob/master/index.js#L25</a></p>
<p>gulp/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-keyword">var vfs = <span class="hljs-built_in">require(<span class="hljs-string">'vinyl-fs');
<span class="hljs-comment">// Omit a lot of lines of code
Gulp.prototype.src = vfs.src;
</span></span></span></span></code></pre>
<p> Let's take a look <code>vfs.src</code> This method . from <code>vinyl-fs/index.js</code> You can see ,<code>vfs.src</code> the truth is that <code>vinyl-fs/lib/src/index.js</code>.<br /> Reference resources :<a href="https://github.com/wearefractal/vinyl-fs/blob/master/index.js" target="_blank">https://github.com/wearefractal/vinyl-fs/blob/master/index.js</a></p>
<p>vinyl-fs/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-pi">'use strict'; <span class="hljs-built_in">module.exports = {
src: <span class="hljs-built_in">require(<span class="hljs-string">'./lib/src'),
dest: <span class="hljs-built_in">require(<span class="hljs-string">'./lib/dest'),
watch: <span class="hljs-built_in">require(<span class="hljs-string">'glob-watcher')
};
</span></span></span></span></span></span></span></span></code></pre>
<p> that , Let's take a look at <code>vinyl-fs/lib/src/index.js</code>. You can see ,<code>gulp.src()</code> Back to , the truth is that <code>outputStream</code> This product , and <code>outputStream</code> yes <code>gs.create(glob, options).pipe()</code> To obtain the , Almost close to the truth , There are just a few more steps .<br /> Reference resources :<a href="https://github.com/wearefractal/vinyl-fs/blob/master/lib/src/index.js#L37" target="_blank">https://github.com/wearefractal/vinyl-fs/blob/master/lib/src/index.js#L37</a></p>
<p>vinyl-fs/lib/src/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-keyword">var defaults = <span class="hljs-built_in">require(<span class="hljs-string">'lodash.defaults');
<span class="hljs-keyword">var through = <span class="hljs-built_in">require(<span class="hljs-string">'through2');
<span class="hljs-keyword">var gs = <span class="hljs-built_in">require(<span class="hljs-string">'glob-stream');
<span class="hljs-keyword">var File = <span class="hljs-built_in">require(<span class="hljs-string">'vinyl'); <span class="hljs-comment">// Omit lines of unimportant code <span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">src<span class="hljs-params">(glob, opt) {
<span class="hljs-comment">// Continue to omit the code <span class="hljs-keyword">var globStream = gs.create(glob, options); <span class="hljs-comment">// when people write to use just pass it through
<span class="hljs-keyword">var outputStream = globStream
.pipe(through.obj(createFile))
.pipe(getStats(options)); <span class="hljs-keyword">if (options.read !== <span class="hljs-literal">false) {
outputStream = outputStream
.pipe(getContents(options));
}
<span class="hljs-comment">// This is it
<span class="hljs-keyword">return outputStream
.pipe(through.obj());
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p> Let's see <code>glob-stream/index.js</code> Inside <code>create</code> Method , final <code>return aggregate.pipe(uniqueStream);</code>. well , The next step is the truth , Let's go to the <code>ordered-read-streams</code> Let's get to the bottom of this project .<br /> Reference resources :<a href="https://github.com/wearefractal/glob-stream/blob/master/index.js#L89" target="_blank">https://github.com/wearefractal/glob-stream/blob/master/index.js#L89</a></p>
<p>glob-stream/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-keyword">var through2 = <span class="hljs-built_in">require(<span class="hljs-string">'through2');
<span class="hljs-keyword">var Combine = <span class="hljs-built_in">require(<span class="hljs-string">'ordered-read-streams');
<span class="hljs-keyword">var unique = <span class="hljs-built_in">require(<span class="hljs-string">'unique-stream'); <span class="hljs-keyword">var glob = <span class="hljs-built_in">require(<span class="hljs-string">'glob');
<span class="hljs-keyword">var minimatch = <span class="hljs-built_in">require(<span class="hljs-string">'minimatch');
<span class="hljs-keyword">var glob2base = <span class="hljs-built_in">require(<span class="hljs-string">'glob2base');
<span class="hljs-keyword">var path = <span class="hljs-built_in">require(<span class="hljs-string">'path'); <span class="hljs-comment">// A lot of code has to be omitted <span class="hljs-comment">// create Method
create: <span class="hljs-function"><span class="hljs-keyword">function<span class="hljs-params">(globs, opt) {
<span class="hljs-comment">// Continue to omit the code
<span class="hljs-comment">// create all individual streams
<span class="hljs-keyword">var streams = positives.map(<span class="hljs-function"><span class="hljs-keyword">function<span class="hljs-params">(glob){
<span class="hljs-keyword">return gs.createStream(glob, negatives, opt);
}); <span class="hljs-comment">// then just pipe them to a single unique stream and return it
<span class="hljs-keyword">var aggregate = <span class="hljs-keyword">new Combine(streams);
<span class="hljs-keyword">var uniqueStream = unique(<span class="hljs-string">'path'); <span class="hljs-comment">// TODO: set up streaming queue so items come in order <span class="hljs-keyword">return aggregate.pipe(uniqueStream);
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p> The truth is coming , Let's take a look at <code>ordered-read-streams</code> Code for , Maybe I didn't understand it at first , No problem , Know that it has achieved its own <code>Stream</code> That's all right. (nodejs There is a corresponding exposure API Let developers be right about Stream It's customized ), For details, please refer to :<a href="http://www.nodejs.org/api/stream.html#stream_api_for_stream_implementors" target="_blank">http://www.nodejs.org/api/stream.html#stream_api_for_stream_implementors</a></p>
<p> Code from :<a href="https://github.com/armed/ordered-read-streams/blob/master/index.js" target="_blank">https://github.com/armed/ordered-read-streams/blob/master/index.js</a></p>
<p>ordered-read-streams/index.js</p>
<pre class="hljs-dark"><code class="hljs js"><span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-title">OrderedStreams<span class="hljs-params">(streams, options) {
<span class="hljs-keyword">if (!(<span class="hljs-keyword">this <span class="hljs-keyword">instanceof(OrderedStreams))) {
<span class="hljs-keyword">return <span class="hljs-keyword">new OrderedStreams(streams, options);
} streams = streams || [];
options = options || {}; <span class="hljs-keyword">if (!<span class="hljs-built_in">Array.isArray(streams)) {
streams = [streams];
} options.objectMode = <span class="hljs-literal">true; Readable.call(<span class="hljs-keyword">this, options); <span class="hljs-comment">// stream data buffer
<span class="hljs-keyword">this._buffs = []; <span class="hljs-keyword">if (streams.length === <span class="hljs-number">0) {
<span class="hljs-keyword">this.push(<span class="hljs-literal">null); <span class="hljs-comment">// no streams, close
<span class="hljs-keyword">return;
} streams.forEach(<span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-params">(s, i) {
<span class="hljs-keyword">if (!s.readable) {
<span class="hljs-keyword">throw <span class="hljs-keyword">new <span class="hljs-built_in">Error(<span class="hljs-string">'All input streams must be readable');
}
s.on(<span class="hljs-string">'error', <span class="hljs-function"><span class="hljs-keyword">function <span class="hljs-params">(e) {
<span class="hljs-keyword">this.emit(<span class="hljs-string">'error', e);
}.bind(<span class="hljs-keyword">this)); <span class="hljs-keyword">var buff = [];
<span class="hljs-keyword">this._buffs.push(buff); s.on(<span class="hljs-string">'data', buff.unshift.bind(buff));
s.on(<span class="hljs-string">'end', flushStreamAtIndex.bind(<span class="hljs-keyword">this, i));
}, <span class="hljs-keyword">this);
}
</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code></pre>
<p> Reference resources :<a href="https://github.com/armed/ordered-read-streams/blob/master/index.js" target="_blank">https://github.com/armed/ordered-read-streams/blob/master/index.js</a></p>
<h2> Written in the back </h2>
<p> Take a big turn in your pocket , Finally found <code>gulp.src()</code> The source of , The general flow is as follows , It's quite a deep level . The details of the code , Interested students can have a deep study .</p>
<blockquote>
<p>ordered-read-streams --> glob-stream --> vinyl-fs --> gulp.src()</p>
</blockquote>
</body>
</html>

Okay , Continue to install another plug-in gulp-htmlmin. According to readme Installation is , But the installation of so many dependencies , Black stuff , It's really scary !

And then in xxxx Under the table of contents , Build a gulpfile.js file , Copy the content directly gulp-htmlmin Of readme:

var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin'); gulp.task('minify', function() {
gulp.src('src/*.html')
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('dist'))
});

Then the console runs gulp command , Report errors , what did you say? “ Task 'default' is not in your gulpfile”. We have to turn to Google , Find out This thing

var gulp = require('gulp');
var coffee = require('gulp-coffee'); gulp.task('scripts', function () {
gulp.src('src/*.coffee')
.pipe(coffee())
.pipe(gulp.dest('./'));
}); gulp.task('watch', function () {
gulp.watch('src/*.coffee', ['scripts']);
}); gulp.task('default', ['scripts', 'watch']);

So I modified the original code :

var gulp = require('gulp');
var htmlmin = require('gulp-htmlmin'); gulp.task('minify', function() {
gulp.src('src/*.html')
.pipe(htmlmin({collapseWhitespace: true}))
.pipe(gulp.dest('dist'))
});
gulp.task('watch', function () {
console.log(' Keep killing you !')
gulp.watch('src/*.html', ['minify']);
});
gulp.task('default', ['minify', 'watch']);

function gulp command , Generate dest Catalog , Inside index.html Has been compressed successfully . And with watch Mission , Every time we change it later html, It's all synced to dest In the middle .

It is estimated that default The task should be similar C Linguistic main Methods, things like that , Without it, we can't drive other tasks .

Then let's learn the basics .

gulp Yes 5 A basic way :src、dest、task、run、watch

gulp.src()

gulp Modular src Method , Used to generate data streams . Its parameters represent the file to be processed , There are generally the following forms :

  • js/app.js: Specify the exact file name
  • js/*.js: All suffixes of a directory are js The file of
  • js/**/*.js: All suffixes in a directory and all its subdirectories are js The file of
  • !js/app.js: except js/app.js All documents other than
  • *.+(js|css): Match item root , All suffixes are js or css The file of

src The argument to a method can also be an array , Used to specify multiple members :

gulp.src(['js/**/*.js', '!js/**/*.min.js']);

gulp.dest()

gulp Modular dest Method , Can be used to transfer files , Write the file to the specified directory at the same time . You can send it data repeatedly , So you can transfer files to multiple directories . A simple example :

gulp.src('./client/templates/*.jade')
.pipe(jade())
.pipe(gulp.dest('./build/templates'))
.pipe(minify())
.pipe(gulp.dest('./build/minified_templates'));

gulp.task()

gulp Modular task Method , Used to define specific tasks . Its first parameter is the task name , The second parameter is the task function . Here's a very simple task function :

gulp.task('greet', function () {
console.log('Hello world!');
});

task Method can also specify a set of tasks to run in order :

gulp.task('build', ['css', 'js', 'imgs']);

The above code specifies build Mission , It is made up of css、js、imgs It's made up of three tasks . Be careful : Because each task is called asynchronously , So there's no way to guarantee js The start time of the task , Is precisely css Task run end time .

If you want the tasks to run in strict order , The previous task can be written as the dependent module of the later task :

gulp.task('css', ['greet'], function () {
// Deal with CSS here
});

The above code indicates ,css The task depends on greet Mission , therefore css It will be there. greet Run it after it's finished .

If the name of a task is default, It shows that it is “ Default task ”, Enter... Directly on the command line gulp command , It will run the task :

gulp.task('default', function () {
// Your default task
});

gulp.run()

gulp Modular run Method , Indicates the task to be performed . It is possible to pass multiple tasks in the form of a single parameter . Be careful : Tasks are executed in parallel as many as possible , And may not run in the specified order :

gulp.run('scripts','copyfiles','builddocs');
gulp.run('scripts','copyfiles','builddocs', function(err) {
// All tasks are completed , Or trigger an error to terminate
});

have access to gulp.run Running tasks in other tasks . It can also be used in the default task gulp.run Organizing multiple smaller tasks into one big task .

gulp.watch()

gulp Modular watch Method , Used to specify the files that need to be monitored . Once these documents change , Just run the assigned task :

gulp.task('watch', function () {
gulp.watch('templates/*.tmpl.html', ['build']);
});

The above code specifies , once templates The template file in the directory has changed , Just run build Mission .

watch Methods can also use callback functions , Instead of the assigned task :

gulp.watch('templates/*.tmpl.html', function (event) {
console.log('Event type: ' + event.type);
console.log('Event path: ' + event.path);
});

Another way of writing is watch When the file monitored by method changes ( modify 、 increase 、 Delete file ), Will trigger change event , It can be done to change Event specifies the callback function :

var watcher = gulp.watch('templates/*.tmpl.html', ['build']);
watcher.on('change', function (event) {
console.log('Event type: ' + event.type);
console.log('Event path: ' + event.path);
});

except change event ,watch Method can also trigger the following events :

  • end: Trigger when the callback function finishes running .
  • error: Trigger when an error occurs .
  • ready: Triggered when listening to a file .
  • nomatch: Triggered when there is no matching listening file .

watcher Object also contains other methods :

  • watcher.end(): stop it watcher object , No more calls to tasks or callback functions .
  • watcher.files(): return watcher Object monitoring files .
  • watcher.add(glob): Add files to be monitored , It can also attach the second parameter , Represents a callback function .
  • watcher.remove(filepath): from watcher Object to remove a monitored file .

After learning these, you can go to its official website to find plug-ins , After all, plug-ins are king .

first gulp More articles on the program

  1. Make one gulp+webpack+vue Single page application development shelf for

    1. The goal is There hasn't been much on the project lately , According to my own development habits , Decided to develop some simple development shelves , It is convenient to apply it directly when there are many things in the future . This article talks about a gulp+webpack+vue Single page application shelf for , What you want to achieve : It's through life ...

  2. One gulp Examples for development and production

    gulp Is a popular front-end build tool , Can help us do a lot of work : Listen for file changes . Refresh the browser . compile Less/Scss. Compressed code . add to md5. Merge files, etc .gulp It's very easy to configure and use , Study gulp By the way, I wrote a ...

  3. DirectX Game programming ( One ): Create a Direct3D Program

    One . Environmental Science Visual Studio 2012,DirectX SDK (June 2010) Two . Get ready 1. environment variable ( If not, please add ) Variable name :DXSDK_DIR A variable's value :D:\Software\ ...

  4. first python Program

    One python Two ways of executing a program : 1. The first way is through python Interpreter : cmd->python-> Get into python Interpreter -> To write python Code -> enter . 2. The second way ...

  5. Write the first MapReduce Program —— Statistical temperature

    Abstract :hadoop After installation , Like learning other languages , To start writing a “hello world!” , Read some learning materials , I wrote a program in imitation . For one C# For the programmer , Write a java Program , And call hadoop My bag , And run in ...

  6. 1.3 first C# Program

    The first program in almost no programming language is called “ Hello , The world ”, So first visual studio Create a Helloworld Program . Details of each part : Main Method is the starting point of program running , The most important code is written in Main ...

  7. One .net The Android journey of programmers -Eclipse Set the code intelligent prompt function

    One .net The Android journey of programmers - Code intelligent prompt function After the new year, I decided to start learning Android development , I bought a memory module on the Internet and added it to my notebook ( Because the notebook was 2G Memory is too laggy , installed vs2010.SQL Server 2008.orac ...

  8. MFC-01-Chapter01:Hello,MFC---1.3 first MFC Program (02)

    1.3.1 Application object MFC The core of an application is based on CWinApp Class ,CWinApp Provides a message loop to retrieve messages and schedule them to the application window . When containing header files <afxwin.h>, ...

  9. Go! new Hello World, My first one Go Program

    The following sentences are excerpted from Baidu Encyclopedia : Go Language is Google 2009 Second open source programming language released . Go The language is specially optimized for the programming of multiprocessor system applications , Use Go Compiled programs are comparable C or C++ Code speed , And it's safer . Support and March ...

Random recommendation

  1. How to implement modification FileUpload style

    It's hidden here first FileUpload Then use one input button And a text To simulate the FileUpload The specific code is <asp:FileUpload ID="FileUpload1& ...

  2. 【 turn 】Vim Command set and garbled problem solving

    The code problem """""""""""""""" ...

  3. Android On the simulator 127.0.0.1 localhost

    Debugging through android simulator Simulator Links localhost perhaps 127.0.0.1, Because I built... On the computer apache, My code is probably URL url = new URL(urlStrin ...

  4. 【 turn 】 In depth understanding of Java Memory model ( 6、 ... and )——final

    With the lock described earlier and volatile Comparison , Yes final Field reads and writes are more like normal variable access . about final Domain , The compiler and the processor are subject to two resorts : I have one in the constructor final The changes to the domain , And then the constructed object ...

  5. hdu 4747【 Line segment tree - Update in sections 】.cpp

    The question : Give a n A sequence of numbers , And define mex(l, r) The second in a sequence l Elements to r The smallest nonnegative integer that does not appear as the first of the elements . Find out all the... In this sequence mex Value . Ideas : You can see that for a sequence ,mex(r, r ...

  6. Unity This plug-in NGUI Study (1)—— Environmental structure

    Unity Official website http://unity3d.com/unity/download Download the latest version 4.5.4 Find cracks in the sacred Forum (Windows) Version number http://game.ceeger.com/f ...

  7. Spring mybatis Source code Chapter -MybatisDAO File parsing ( Two )

    Preface : Reading the source code to understand the implementation mechanism is conducive to cultivate sentiment , Take on the previous Spring mybatis Source code Chapter -MybatisDAO File parsing ( One ) The default load mybatis Master file mode XMLConfigBuilder ...

  8. Learn front end development from scratch — 17、CSS3 Background and gradient

    One .css3 Background cutting : background-clip:border-box|padding-box|content-box; effect : Used to set the visible area of the background a) border-box The default value is , background ...

  9. Web Map guide summary

    The copyright of the article is jointly owned by Li Xiaohui and blog park , If reprint, please indicate the source clearly :http://www.cnblogs.com/naaoveGIS/ 1. background The map side shows all kinds of mapping effects , Users want to generate reports with one click , The core ...

  10. tablednd onDrap Method does not call

    scene Use tablednd When the plug-in ,onDrap Method does not call solve to tr Label plus id attribute