| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -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 | + - [ ] エコシステム | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments