@@ -97,29 +97,32 @@ Transform Streamというものが出てきましたが、Node.jsのStreamは次
97
97
そのデータを変更したもの次のStreamに流すということを行っています。
98
98
99
99
「gulpから流れてきたデータ」を扱うために` readableObjectMode ` と` writableObjectMode ` をそれぞれ` true ` にしています。
100
- この _ ObjectMode_ というのは名前の通り、Streamでオブジェクトが流れるという設定のことです 。
100
+ この _ ObjectMode_ というのは名前の通り、Streamでオブジェクトが流すための設定です 。
101
101
102
102
通常のNode.js Streamは[ Buffer] ( https://nodejs.org/api/buffer.html " Buffer ") というバイナリデータを扱います。
103
- この[ Buffer] ( https://nodejs.org/api/buffer.html " Buffer ") は文字列オブジェクトと相互変換が可能ですが、複数の値を持ったオブジェクトを扱うのは少し変更です 。
103
+ この[ Buffer] ( https://nodejs.org/api/buffer.html " Buffer ") は文字列オブジェクトと相互変換が可能ですが、複数の値を持ったオブジェクトを扱うのは少し大変です 。
104
104
105
105
そのため、Node.js Streamには[ Object Mode] ( https://nodejs.org/api/stream.html#stream_object_mode " Object Mode ") があり、
106
106
JavaScriptのオブジェクトそのものをStreamで流せるようになっています。
107
107
108
108
### vinyl
109
109
110
- gulpでは[ vinyl] ( https://github.com/gulpjs/vinyl " vinyl ") オブジェクトがStreamとして流れてきます 。
111
- このvinylは _ Virtual file format_ というように、データをラップした抽象フォーマットのオブジェクトです 。
110
+ gulpでは[ vinyl] ( https://github.com/gulpjs/vinyl " vinyl ") オブジェクトがStreamで流れてきます 。
111
+ このvinylは _ Virtual file format_ という呼ばれているもので、ファイル情報と中身をラップしたgulp用の作成された抽象フォーマットです 。
112
112
113
113
なぜこういった抽象フォーマットが必要なのかは次のことを考えてみると分かりやすいと思います。
114
114
115
115
` gulp.src ` で読み込んだファイルの中身のみが、Transform Streamに渡されてしまうと、
116
116
Transform Streamからはそのファイルのパスや読み取り属性などの詳細な情報を知ることができません。
117
+
117
118
そのため、` gulp.src ` で読み込んだファイルはvinylでラップされ、ファイルの中身は` contents ` として参照できるようになっています。
118
119
119
- この抽象フォーマットの` contents ` はStreamまたはBufferとなっているので、
120
- 両方対応する場合は以下のように両方のパターンに対応したコードを書く必要があります。
120
+ ### vinylの中身を処理する
121
+
122
+ 先ほどのTransform Streamの中身を見てみましょう。
121
123
122
124
``` js
125
+ // file は `vinyl` オブジェクト
123
126
if (file .isBuffer ()) {
124
127
file .contents = prefixBuffer (file .contents , prefix);
125
128
}
@@ -129,8 +132,61 @@ if (file.isStream()) {
129
132
}
130
133
```
131
134
135
+ ` vinyl ` 抽象フォーマットの` contents ` プロパティには、読み込んだファイルのBufferまたはStreamが格納されています。
136
+ そのため両方のパターンに対応したコードする場合はどちらが来ても問題ないように書く必要があります。
137
+
138
+ > ** NOTE** : gulp pluginは必ずしも両方のパターンに対応しないといけないのではなく、Bufferだけに対応したものも多いです。しかし、その場合にStreamが来た時のErrorイベントを通知することがガイドラインで推奨されています。 - [ gulp/guidelines.md at master · gulpjs/gulp] ( https://github.com/gulpjs/gulp/blob/master/docs/writing-a-plugin/guidelines.md " gulp/guidelines.md at master · gulpjs/gulp ")
139
+
140
+ ` contents ` にどちらのタイプが格納されているかは、ひとつ前のStreamで決定されます。
141
+
142
+ ``` js
143
+ gulp .src (" ./*.*" )
144
+ .pipe (gulpPrefixer (" prefix text" ))
145
+ .pipe (gulp .dest (" build" ));
146
+ ```
147
+
148
+ この場合は、` gulp.src ` により決定されます。
149
+ ` gulp.src ` はデフォルトでは、` contents ` にBufferを格納するので、この場合はBufferで処理されることになります。
150
+
151
+ ` gulp.src ` はオプションに` { buffer: false } ` を渡すことで` contents ` にStreamを流すことも可能です。
152
+
153
+ ``` js
154
+ gulp .src (" ./*.*" , { buffer: false })
155
+ .pipe (gulpPrefixer (" prefix text" ))
156
+ .pipe (gulp .dest (" build" ));
157
+ ```
158
+
159
+ ### 変換処理
160
+
161
+ 最後にBufferとStreamのそれぞれの変換処理を見てみます。
162
+
163
+ ``` js
164
+ export function prefixBuffer (buffer , prefix ) {
165
+ return Buffer .concat ([Buffer (prefix), buffer]);
166
+ }
167
+
168
+ export function prefixStream (prefix ) {
169
+ return new Transform ({
170
+ transform : function (chunk , encoding , next ) {
171
+ // chunkにはBufferが流れてくる
172
+ let buffer = prefixBuffer (chunk, prefix);
173
+ this .push (buffer);
174
+ next ();
175
+ }
176
+ });
177
+ }
178
+ ```
179
+
180
+ やってみたBufferの先頭に` prefix ` の文字列をBufferとして結合して返すだけの処理が行われています。
181
+
182
+ この変換処理自体は、gulpに依存したものはないため、通常のライブラリに渡して処理するということが可能です。
183
+ BufferはStringと相互変換が可能であるため、多くのgulpプラグインと呼ばれるものは、` gulpPrefixer ` と` prefixBuffer ` にあたる部分だけを実装しています。
184
+
185
+ つまり、prefixを付けるといった変換処理自体は、既存のライブラリをそのまま使うことができるようになっています。
186
+
187
+
132
188
- [ ] どういう用途に向いている?
133
189
- [ ] どういう用途に向いていない?
134
190
- [ ] この仕組みを使っているもの
135
191
- [ ] 実装してみよう
136
- - [ ] エコシステム
192
+ - [ ] エコシステム
0 commit comments