目次
要件の説明
ステップ 1 (JS/CSS リソース)
ステップ 2 (HTML ファイル)
ステップ 3 (場所の依存関係)
ステップ 4 (依存関係の照合)
步骤5 (资源转换/依赖注入)
One More Thing
. . .
ホームページ ウェブフロントエンド htmlチュートリアル Gulp の高度なカスタマイズされた gulp プラグイン_html/css_WEB-ITnose

Gulp の高度なカスタマイズされた gulp プラグイン_html/css_WEB-ITnose

Jun 21, 2016 am 08:58 AM

gulp は多くのプロジェクトの標準となっており、gulp プラグイン エコシステムも非常に繁栄しています。2015.1.5 の時点で、npm には 10,190 の gulp プラグインが使用できます。完全に確実なビルドを組み立てることができます。

しかし、ドキュメントに従って最終的にプラグインを呼び出し、対応するパラメーターを渡しても、結果が期待どおりではないことが判明し、この時点でトラブルシューティングが必要になるという状況によく遭遇します。これは、gulp プラグインがどのように機能するかをある程度理解する必要があります。この記事では、gulp プラグインの実装を例として、gulp プラグインがどのように機能するかを説明します。

要件の説明

通常、構築リソースは js/css/html およびその他のリソース ファイルですが、開発またはリリースの段階で、js/css はマージ、圧縮、名前変更されます。他の処理ステップ。

場合によっては、構築後に生成される js/css の名前や数量を決定できないため、HTML ファイルにリソースの参照アドレスを記述することができません。それを使用するには、最終的に生成されたリソース ファイル/アドレスを HTML に挿入するのはどうでしょうか?

実装する必要があるプラグインが次のように使用されているとします。

<html><head>    <!--InlineResource:\.css$--></head><body>    <!--InlineResource:\.js$--></body></html>
ログイン後にコピー

HTML コメントを使用して、依存する必要があるリソースを宣言します。 InlineResource は単語を一致させるための鍵であり、「:」は区切り文字として使用され、/*.css$/、/*.js$/ は依存するファイルを宣言するための通常の一致です。

gulpfile.js では、ここで設定する必要があります:

gulp.task('dist', function () {    return gulp.src('index.html')              .pipe(InjectResources(                    gulp.src(['*.js', '*.css'])                        .pipe(hash(/*添加MD5作为文件名*/))              ))              .pipe(gulp.dest('dist'))})
ログイン後にコピー

いくつかの方法と手順を簡単に紹介します:

  • gulp.src('index.html') は、ファイル システムの現在のディレクトリにあるindex.html を読み取り、後続のステップで使用する読み取り可能なストリームを生成します

  • InjectResources(stream) は、HTML に挿入される JS/CSS を取得するためのパラメーターを受け取ります。このパラメーターは、受信および受信用の Stream インスタンスを生成するために使用されます。前の手順でストリーミングされたデータを処理します。

  • hash(options) は、現在のストリームのファイル名に md5 文字列を追加するために使用されるサードパーティのプラグインです。 : gulp-hash

  • gulp.dest('dist') は、リソースを現在のディレクトリに挿入した後に HTML ファイルを生成するために使用されます

私たちが注意する必要があるのは 2 番目のポイントです。すべてのリソース ファイルを受信し、インジェクションを完了する方法は次のとおりです。

このロジックは 4 つのステップに分けることができます

  1. すべての js/css リソースを取得します
  2. すべての HTML ファイルを取得します
  3. HTML の位置 依存関係の宣言
  4. は依存リソース
  5. に一致します 依存リソース タグを生成して挿入します

プログラムを開始する前に、重要なサードパーティ ライブラリに依存する必要があります:map- stream

map-stream は、現在のストリーム内の各ファイル データを取得し、データの内容を変更するために使用されます。

ステップ 1 (JS/CSS リソース)

module.exports = function (resourcesStream) {    // step 1: TODO => 这里要获取所有的js/css资源}
ログイン後にコピー

リソース ストリームは、非同期インスタンスを通じて取得されるパラメーターとして InjectResources メソッドに渡されます。

var resources = []function getResources(done) {    if (resources) return done(resources)    //  由于下面的操作是异步的,此处要有锁...    resourcesStream.pipe(mapStream(function (data, cb) {            resources.push(data)            cb(null, data)        }))        .on('end', function () {            done(resources)        })}
ログイン後にコピー

  • mapStream 処理メソッドで取得されたデータは、gulp.src によって生成されたビニール オブジェクトであり、A を表します。ファイル
  • 各ストリームは受信後に終了イベントをスローします

注: MapStream 処理メソッドの cb メソッド、2 番目のパラメータは置換に使用できます 現在処理されていますファイル オブジェクト

この時点で、カプセル化の最初のステップが完了しました。

module.exports = function (resourcesStream) {    // step 1:    function getResources () {        ...    }}
ログイン後にコピー

ステップ 2 (HTML ファイル)

module.exports = function (resourcesStream) {    // step 1: ✔︎     // step 2: TODO => 获取当前流中的所有目标HTML文件    return mapStream(function (data, cb) {     })}
ログイン後にコピー

InjectResources プラグイン メソッドは、受信用の Writable Stream インスタンスを返します。 InjectResources にストリーミングされた HTML ファイルを処理する場合、mapStream の戻り値は書き込み可能なストリームです。

このとき、mapStream処理メソッドで取得したデータはHTMLファイルオブジェクトとなり、その内容が処理されます。

ステップ 3 (場所の依存関係)

module.exports = function (resourcesStream) {    // step 1: ✔︎     // step 2: ✔    return mapStream(function (data, cb) {        var html = data.contents.toString()        // step 3: TODO => 获取HTML中的资源依赖声明     })}
ログイン後にコピー

取得するデータはビニール オブジェクトであり、contents 属性はファイルのコンテンツです。 Buffer または It is String であり、文字列の内容は toStraing() を通じて取得できます。

すべての依存関係宣言には InlineResource キーワードが含まれています。簡単な方法は、正規表現を使用して HTML 内のリソース依存関係を見つけて置換することです。

html.replace(/<!--InlineResource:(.*?)-->/g, function (expr, fileRegexpStr){    // fileRegexp是用以匹配依赖资源的正则字符串})
ログイン後にコピー

この時点で、リソースの依存関係の配置が完了しました。次のステップは、置換用の依存リソースを取得することです。

ステップ 4 (依存関係の照合)

ステップ 1 で定義した getResources メソッドを通じて必要なリソース ファイルを取得します。

module.exports = function (resourcesStream) {    // step 1: ✔︎     // step 2: ✔    return mapStream(function (data, cb) {        // step 3: ✔         getResources(function (list) {            html.replace(depRegexp, function (expr, fileRegexpStr) {                var fileRegexp = new RegExp(fileRegexpStr)                // step 4: TODO => 获取匹配的依赖            })        })    })}
ログイン後にコピー

getResources は非同期メソッドであるため、置換処理ロジックは getResources のコールバック メソッドでラップする必要があります。

依存関係宣言の正規表現に従って、リソース リストを 1 つずつ照合します。

function matchingDependences(list, regexp) {    var deps = []    list.forEach(function (file) {        var fpath = file.path        if (fileRegexp.test(fpath)) {            deps.push(fpath)        }    })    return deps}
ログイン後にコピー

これは最後のステップです。リソースを HTML タグに変換し、HTML に挿入します

步骤5 (资源转换/依赖注入)

module.exports = function (resourcesStream) {    // step 1: ✔︎     // step 2: ✔    return mapStream(function (data, cb) {        // step 3: ✔         // step 4: ✔        // ...            html.replace(depRegexp, function (expr, fileRegexpStr) {                var deps = matchingDependences(list, fileRegexpStr)                // step 5: 文件对象转换为HTML标签            })    })}
ログイン後にコピー

接下来的定义一个transform方法,用于将路径列表转换为HTML的资源标签列表,其中引入了 path模块用于解析获取文件路径的一些信息,该模块是node内置模块。

var path = require('path') function transform(deps) {    return deps.map(function (dep) {        var ext = path.extname(dep)        switch (ext) {            case 'js':                     '<script>' + dep + '</script>'            break            case 'css':                return '<link rel="stylesheet" href="' + dep + '">'            break        }        return ''    }).join('')}
ログイン後にコピー

最终,我们将标签列表拼接为一个字符串来HTML中的依赖声明(注入):

html = html.replace(depRegexp, function (expr, fileRegexpStr) {    var deps = matchingDependences(list, fileRegexpStr)    // step 5: 文件对象转换为HTML标签    return transform(deps)})// html文件对象data.contents = new Buffer(html)// 把修改后的文件对象放回HTML流中cb(null, data)
ログイン後にコピー

到此也就完整地实现了一个拥有基本注入功能的插件~~~~~~

One More Thing

通过上面实现的示例步骤,可以清楚了解到gulp插件的工作原理。 但要做一个易用/可定制性高的插件,我们还要继续完善一下,例如:

  • 比较资源的路径与HTML的路径,输出相对路径作为默认的标签资源路径
  • 提供 sort 选项方法用于修改资源的注入顺序
  • 提供 transform 选项方法用于定制标签中的资源路径
  • 在依赖声明中支持 inline 声明,用以将资源内容内联到HTML中,例如:

      <!--InjectResources:*\.js$??inline-->
    ログイン後にコピー

  • 支持命名空间,用于往同一个资源流中使用多次资源注入的区分,例如:

      gulp.src('index.html')      .pipe(          InjectResources(gulp.src('asserts/*.js'), { name: 'asserts'})      )      .pipe(          InjectResources(gulp.src('components/*.js'), { name: 'components'})      )      ...
    ログイン後にコピー

  • . . .

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? 公式アカウントのキャッシュの更新の難しさ:バージョンの更新後のユーザーエクスペリエンスに影響を与える古いキャッシュを回避する方法は? Mar 04, 2025 pm 12:32 PM

公式アカウントのWebページはキャッシュを更新します。これはシンプルでシンプルで、ポットを飲むのに十分な複雑です。あなたは公式のアカウントの記事を更新するために一生懸命働きましたが、ユーザーはまだ古いバージョンを開くことができますか?この記事では、この背後にあるtwist余曲折と、この問題を優雅に解決する方法を見てみましょう。それを読んだ後、さまざまなキャッシュの問題に簡単に対処でき、ユーザーが常に新鮮なコンテンツを体験できるようになります。最初に基本について話しましょう。それを率直に言うと、アクセス速度を向上させるために、ブラウザまたはサーバーはいくつかの静的リソース(写真、CSS、JSなど)やページコンテンツを保存します。次回アクセスするときは、もう一度ダウンロードすることなく、キャッシュから直接検索できます。自然に高速です。しかし、このことは両刃の剣でもあります。新しいバージョンはオンラインです、

HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? HTML5フォーム検証属性を使用してユーザー入力を検証するにはどうすればよいですか? Mar 17, 2025 pm 12:27 PM

この記事では、ブラウザのユーザー入力を直接検証するために、必要、パターン、MIN、MAX、および長さの制限などのHTML5フォーム検証属性を使用して説明します。

HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? HTML5のクロスブラウザー互換性のベストプラクティスは何ですか? Mar 17, 2025 pm 12:20 PM

記事では、HTML5クロスブラウザーの互換性を確保するためのベストプラクティスについて説明し、機能検出、プログレッシブエンハンスメント、およびテスト方法に焦点を当てています。

WebページのPNG画像にストローク効果を効率的に追加する方法は? WebページのPNG画像にストローク効果を効率的に追加する方法は? Mar 04, 2025 pm 02:39 PM

この記事では、CSSを使用したWebページへの効率的なPNG境界追加を示しています。 CSSはJavaScriptやライブラリと比較して優れたパフォーマンスを提供し、微妙または顕著な効果のために境界幅、スタイル、色を調整する方法を詳述していると主張しています

&lt; datalist&gt;の目的は何ですか 要素? &lt; datalist&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:33 PM

この記事では、HTML&lt; Datalist&GT;について説明します。オートコンプリートの提案を提供し、ユーザーエクスペリエンスの改善、エラーの削減によりフォームを強化する要素。

&lt; meter&gt;の目的は何ですか 要素? &lt; meter&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:35 PM

この記事では、html&lt; meter&gt;について説明します。要素は、範囲内でスカラーまたは分数値を表示するために使用され、Web開発におけるその一般的なアプリケーション。それは差別化&lt; Meter&gt; &lt; Progress&gt;およびex

HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? HTML5&lt; time&gt;を使用するにはどうすればよいですか 日付と時刻を意味的に表す要素? Mar 12, 2025 pm 04:05 PM

この記事では、html5&lt; time&gt;について説明します。セマンティックデート/時刻表現の要素。 人間の読み取り可能なテキストとともに、マシンの読みやすさ(ISO 8601形式)のDateTime属性の重要性を強調し、Accessibilitを増やします

&lt; Progress&gt;の目的は何ですか 要素? &lt; Progress&gt;の目的は何ですか 要素? Mar 21, 2025 pm 12:34 PM

この記事では、HTML&lt; Progress&gt;について説明します。要素、その目的、スタイリング、および&lt; meter&gt;との違い要素。主な焦点は、&lt; Progress&gt;を使用することです。タスクの完了と&lt; Meter&gt; statiの場合

See all articles