webpack甚のプラグむンを䜜成する

すでにハブ䞊のwebpackに぀いお曞いおmoscowjsに぀いお話したした。webpackの䞀般的な機胜、その長所ず短所を説明する他のリ゜ヌスに関する蚘事がいく぀かありたす。



したがっお、この蚘事ではwebpack自䜓に぀いお簡単に説明し、プラグむンの開発に぀いお詳しく説明したす。



画像





1. Webpackに぀いお簡単に



人気のあるgruntやgulpなどのビルドシステム甚に倚数の補助ラむブラリが蚘述されおいたすが、webpackは珟時点ではそのような豊富さを誇っおいたせん。必芁なラむブラリを䜿甚できるこずは玠晎らしいこずです。 プロゞェクトにwebpackを実装するこずを決めたが、既成の゜リュヌションがない堎合、解決方法は1぀しかありたせん-自分で曞いおください。



それで、webpackずは䜕ですか、その機胜は䜕ですか、それはどのように機胜したすか



開発者自身がWebpackを配眮しおいるため http://webpack.github.io 、Webpackはモゞュヌルバンドラヌです。



画像



箱から出しお、AMD、CommonJS、およびES6モゞュヌルをサポヌトしたす。webpack-dev-serverアドオンに実装され、socket.ioを介しお動䜜するラむブreload'aの可胜性がありたす。 ぀たり、゜ヌスファむルに倉曎を加えた埌、毎回ビルドコマンドを再床実行する必芁はありたせん。



たた、webpackの蚭定はかなりシンプルで、gulpほど透明ではありたせんが、簡朔で掗緎されおいたす。



甚語



2.ロヌダヌずプラグむン



ロヌダヌは、ファむルのダりンロヌド、凊理、倉換に䜿甚される匷力なツヌルです。 ぀たり プロゞェクトで、たずえば、ヒスむ、sass、coffee、es6などのテクノロゞヌを䜿甚しおいる堎合、たたはsvgが倧きすぎお圧瞮する必芁がある堎合-凊理、倉換、瞮小のすべおのタスクはロヌダヌによっお解決されたす。 それらの倚くはすでに曞かれおいたす 。 ここで芋぀けるこずができたす。



ロヌダヌの䜜成は簡単です。 これを行うために、プロゞェクトの公匏りェブサむトに別のセクションがありたす- ロヌダヌを曞く方法、そしお䞀般に、コヌドの最初の行で、それがどれほど簡単かすぐに理解できたす



// Identity loader module.exports = function(source) { return source; };
      
      





 // Identity loader with SourceMap support module.exports = function(source, map) { this.callback(null, source, map); };
      
      





Loaderはmodule.exports関数で、ファむルの内容を入力ずしお受け取り、凊理の結果を返したす。たた、構成に必芁な属性が存圚する堎合、sourcemapを返すこずもできたす。



珟圚のコンテキストを返すず、連鎖を䜿甚するこずが可胜になりたす。 したがっお、それぞれが1぀のタスクのみを実行する必芁がありたす。Webpack開発者は、各ステップに個別のロヌダヌを䜜成するこずをお勧めしたす。 䞀般に、これは各モゞュヌルがカプセル化されおいる堎合の䞀般的なモゞュヌルむデオロギヌであり、これにより、これを操䜜しおデバッグを実行するのがはるかに簡単になりたす。



プラグむンは、コンパむラヌずいう1぀のパラメヌタヌのみを持぀applyメ゜ッドを持぀オブゞェクトです。 それを介しお、webpack'aをコンパむルするさたざたな段階ず通信できたす。 必芁な倉換を実行したす。さたざたなタむプのプラグむンむンタヌフェむスもありたす。䟋ずしお、次のコヌドが公匏Webサむトで提䟛されおいたす。



 compiler.plugin("compile", function(params) { // Just print a text console.log("Compiling..."); });
      
      







プロゞェクトをビルドするタスクを開始するず、タヌミナルで、珟圚のビルドプロセスに関するメッセヌゞ、たたは必芁なラむブラリの䞍足が原因の゚ラヌ、たたはコヌド構文の問題に関連する゚ラヌが衚瀺されたす。



webpackを䜿甚しおビルドプロセスを開始するず、コヌドが機胜し、タヌミナルに「Compiling ...」ず衚瀺されたす。



倖芋䞊、これは理解できる仕組みですが、そのような䜜業の䟋はほずんどなく、ドキュメントには実際には䟋がありたせん。



郚分的に、これは蚘事を曞くように促したした。 ロヌダヌセクションの蚘述方法にはロヌダヌの倚くの䟋がありたすが、プラグむンセクションの蚘述方法は公匏サむトから無期限に非衚瀺になっおいたす堎合によっおは完党に削陀されたす。 抂しお、いわゆるむンタヌフェむスタむプの䜜業のリストずテキスト説明 upd 珟圚、このセクションは非衚瀺になっおいたすず、すでに䜜成されたプラグむンのコヌドを調査する機胜のみがあり、それがどのように䜿甚され動䜜するかを確認できたす



もちろん、webpack開発者がこのセクションをすぐに提䟛するこずは間違いありたせんが、珟圚の問題を解決するためにこのトピックを今すぐ理解しようずし、セクションを開くず、自分自身のために新しいものを芋぀け、おそらく完党に䜜業を再考したすプラグむン。



3.問題の解決䟋-svgスプラむトの接着



Webpackは数幎前から存圚しおいたすが、倚くの人がプロゞェクトを操䜜するためのメむンツヌルずしお䜿甚するこずを敢えおしおいたせん。その機胜は玠晎らしく、モゞュヌルの組み立おず操䜜の䞡方のツヌルをすぐに眮き換えるこずができたす。



そしお、りェブパックのメカニックのためのすべおのタスクずプラグむンず䞀緒にうなりやむちになるプロゞェクトを曞き盎すのは15分ではありたせん。 特に、これたでのずころ、叀い実行䞭のビルドシステムが誇るこずができるwebpackの䞋には倚くのラむブラリがないこずを考慮しおください。



これに決めお、プロゞェクトの曎新を開始したずしたす。 そしお、この過皋で、䞊蚘の問題に出くわす可胜性がありたす。webpack'eには、以前プロゞェクトにあり、完党に機胜しおいたタスクの同様のメカニズムを耇補たたは実行するツヌルが存圚しない堎合がありたす。



これはgrunt-svgstoreで発生したした -必芁なディレクトリからすべおのsvgを1぀のスプラむトに収集し、 use xlinkhref =“logo”を䜿甚しお必芁なsvgをペヌゞの適切な堎所に接続するラむブラリ



これは、スプラむトを介しおsvgを操䜜するための非垞に䟿利なメカニズムであり、移行䞭にこの機胜を倱いたくありたせん。

gulpの䞋にも同様の゜リュヌションがありたすが、webpackの䞋で芋぀けるこずはできたせんでした。

これが問題であり、Webpack甚のプラグむンを䜜成し、svgスプラむトを接着するための䞀般的な仕組みを維持し、堎合によっおはいく぀かの新しい機胜を远加するこずです。



4.コヌドを曞くプロセス



執筆を始めるためには、誰かのコヌドを盗んでそれを私たちのコヌドずしお停装するこずは私たちの目暙ではないこずを理解するこずが重芁です。しかし、垞に限られおいる時間を考えるず、車茪を再発明する気もありたせん。



したがっお、ここでこの方法を䜿甚したす。grunt-svgstoreラむブラリコヌドをベヌスずしお、Webpackのプラグむンずしお機胜するように少し倉曎し、いく぀かの新機胜を远加したす。䞀方、プラグむンコヌドの最䞊郚では、党䜓を瀺したす。



 /** * Webpack SVGstore plugin based on grunt-svg-store * @see https://github.com/FWeinb/grunt-svgstore/blob/master/tasks/svgstore.js */
      
      





したがっお、私たちはだれかを欺いたり、䞍平を蚀っおsvgstoreを曞いた開発者を怒らせたりしたせん。 䞀般に、このプラグむンは特定のプロゞェクトで1回だけ䜿甚するためではなく、npmでレむアりトしお成功した結果、オヌプン゜ヌスコミュニティに貢献するために取り䞊げたした。



タスクのコヌドをプラグむンに倉換するには、実際にコヌドからすべおのうなり声を削陀し、svgをスプラむトに盎接組み立おお接着するための既補のメカニズムのみを保持したす。 しかし、その埌、修正する必芁がある倚くの問題に遭遇したす。



5.予期しない問題



1スプラむトが倧きすぎるため、瞮小を远加する必芁がありたす。



最初に芋぀かったのは、webpackの䞋に、すべおのsvgを駆動できるsvgoのフヌドの䞋に既補のsvgロヌダヌhttps://github.com/rpominov/svgo-loaderがあるこずです。



プラグむンでsvgoモゞュヌルを接続したす。



 var SVGO = require('svgo');
      
      





そしお、svgの瞮小関数を远加したす。



 SvgStore.prototype.svgMin = function(file, loop) { var svgo = new SVGO(); var source = file; var i; function svgoCallback(result) { source = result.data; } // optimize loop for (i = 1; i <= loop; i++) { svgo.optimize(source, svgoCallback); } return source; };
      
      





ミニファむにより䞀郚のsvgが損なわれる可胜性がありたす。たた、新しいsvgを远加するプロセスで人件費が最小限になるように努めおいたす。 これを実珟するには、 mintrue / falseプラグむンにオプションを远加したす。これにより、特定のsvg'shkiを瞮小するか、すべおのsvgをそのたたの圢で正確に収集するかどうかがわかりたす。



スプラむトのサむズは重芁であり、サむズが小さいほど自然に優れおいたす。 しかし、すべおの瞮小を完党に拒吊するこずはあたり正しくないため、svgの内郚ディレクトリを远加するこずにしたした。 たずえば、svgを䜿甚したディレクトリぞのパス

/アプリ/アセット/ svg

そしお、サブディレクトリに瞮小したいsvgを入れたす

/アプリ/アセット/ svg /分

したがっお、内郚のminディレクトリにあるsvgのみを瞮小し、耇数のアむコンが砎損する堎合はすべおの瞮小を拒吊したす。必芁はありたせん。



ニュアンスもありたす。これは、関数が2぀のパラメヌタヌを取り、その1぀がsvgの内容であり、2番目が-ルヌプであるためです。

実際、svgの利点の1぀は、CSSを䜿甚しお画像のスタむルを制埡し、色、線幅などを倉曎できるこずです。



しかし、最初の実行埌、svgoはむンラむンスタむルを削陀したせん。そのため、CSSを䜿甚しおスタむルを再定矩するこずはできたせん。 たずえば、色をホバヌに倉曎する必芁がある堎合、これは堎合によっおは機胜したせん。 ただし、2回実行するず、これらの属性は消去され、再定矩が機胜し始めたす。



圓然、誰もがこれを必芁ずするわけではないため、デフォルトではルヌプオプションは11回の実行に等しくなりたすが、svgoを介しお任意の数の実行を蚭定できたす。



2プラグむンを䜿甚しお耇数のスプラむトを収集する必芁がありたす。 これは、かなり原始的なプリフィックスを䜿甚しお実装され、あたり矎しくないただし機胜するコヌドではなく、オプションはフィルタヌず呌ばれ、次のように機胜したす。



1. 'except-name'-倀がexcept-で始たる堎合、この堎合はnameで始たるものを陀き、すべおのsvgがスプラむトに収集されたす

2. 'name'-svgはスプラむトに収集されたす。スプラむトは指定された行この堎合はnameで始たりたす。



 output: [ { filter: 'Logo-', sprite: 'svg/[hash].logo_sprite.svg' }, { filter: 'except-Logo-', sprite: 'svg/[hash].sprite.svg' } ]
      
      





3. 'all'-䜕も共有する必芁がなく、すべおのsvgが配眮される出力で1぀のスプラむトのみを取埗する堎合。



 output: [ { filter: 'all', sprite: 'svg/[hash].sprite.svg' } ]
      
      





フィルタヌに加えお、すべおのアセットが移動するディレクトリも瀺し、[hash]オプションも远加されたした。 ハッシュ方法自䜓では、再び自転車を発明したせんでしたが、暗号モゞュヌルが䜿甚する最も暙準的なハッシュ方法を採甚したした。



 Name.replace('[hash]', crypto.createHash('md5').update(source).digest('hex'))
      
      





圓初、収集されたスプラむトにハッシュを远加するこずは蚈画されおいたせんでした。なぜなら、webpackがそのようなこずを行うように思われ、私たちのタスクは、ハッシュを远加する前にコンパむルされたスプラむトをスリップするこずであり、残りはコレクタヌによっお行われるからです しかし、残念ながら、それを機胜させるのは機胜しなかったので、プラグむン内にハッシュを远加したす。



3別の倧きな問題は、収集されたスプラむトをマニフェストに远加するこずです。



マニフェストは、アセットの名前ず収集された名前ずの察応をハッシュずパスで瀺すJSONです。 各アセンブリのハッシュがわからないため、これはアセットを接続するために行われたす。 マニフェストを䜿甚しお、䟿利なリンクテヌブルを取埗したす。 このために、webpackのマニフェストプラグむンを䜿甚したす 。



このマニフェストにより、プロゞェクトの裏偎は、新しいビルド埌に接続する必芁があるものを理解したす。

そしお、ここで私たちが遭遇したもう1぀の問題がありたす。コンパむラヌは2぀のオブゞェクトを提䟛し、そのうちの1぀はアセットの配列、2番目はモゞュヌルです。

そしお、プラグむン内にアセットを远加した埌



 compiler.plugin('emit', function(compilation, callback) { compilation.assets[key.sprite] = { source: function() { return new Buffer(source); }, size: function() { return Buffer.byteLength(source, 'utf8'); } }; callback(); });
      
      





compiler.assets配列に衚瀺されたすが、この配列はファむル名ずハッシュ付きのパスずの䞀臎を提䟛したせん。



そのため、manifest-webpackプラグむンを䜜成した開発者は、プラグむン内でcomiler.assetsではなくcompiler.modulesを䜿甚したすが、2番目の方がはるかに論理的です。



぀たり Tobiasが 提案したコヌドの䟋webpack開発者の1人に埓っお新しいアセットを远加した埌、このアセットはアセット配列に衚瀺されたすが、この配列には元の名前たたはパスが含たれおいないため、䜿甚できたせん。



プル配列を介しお名前のフィヌルドを挿入しお、assets配列を䜿甚しおマニフェストを䜜成できるようにしたしたが、受け入れられたせんでした。 そしお䞀般的に、この考えは拒吊されたした。



これにより、新しく䜜成したスプラむトをマニフェストに远加するずいう問題が発生したした。この段階では、最終段階でプラグむンを介しおプラグむンを手動で操䜜する必芁がありたす。



 compiler.plugin('done', function(compilation, callback) { // code })
      
      





そしお、手でfs.readFile / fs.writeFileを通しおスプラむトをマニフェストに远加したす。これは良くありたせん。



6.䜿甚䟋ず展望



リンクを䜿甚しお、Webpackプロゞェクトでプラグむンを䜜成しお詊しおみるこずができたす。



将来的には、プラグむンを最も汎甚性の高いものにし、コヌドをリファクタリングし、䜙分なものをすべお削陀し、テストでその䜜業をカバヌするこずを蚈画しおいたす-䞀般に、少なくずも必芁なものを残し、可胜な限り安定させる



7.参照



プラグむンの結果を䜿甚したデモ-motor.ruのすべおのアむコン

プラグむンリポゞトリ問題ずプルリク゚ストを埅っおいる -github.com/lgordey/webpack-svgstore-plugin

NPMプラグむン-www.npmjs.com/package/webpack-svgstore-plugin

Webpackドキュメント-webpack.github.io/docs

Webpackリポゞトリ-github.com/webpack/webpack



All Articles