npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gulp-inject-webpack-plugin

v0.1.0

Published

A Webpack plugin that wraps gulp-inject for use with the Webpack CLI

Downloads

3

Readme

Gulp Inject Webpack Plugin

A Webpack plugin that wraps gulp-inject for use with the Webpack CLI

Use with indexhtml-webpack-plugin and chunk-maifest-webpack-plugin for a comprehensive solution to your project index.html file.

Rationale

Gulp has an excellect HTML composer called Gulp Inject. It has a lot of powerful features.

If you have existing projects that you are migrating to Webpack it is desirable for these features to work immediately, with the Webpack CLI.

This plugin wraps Gulp Inject so that you can use it without running Gulp. It has a dependency on the Vinyl File System used in Gulp but not on Gulp itself.

This makes the plugin somewhat of a frankenstein, however the excellent implementation of Gulp Inject makes it compelling nonetheless. Over time I am sure we can find a more elegant solution for html injection in Webpack.

To that end, please also consider html-webpack-plugin if you do not need the feature-set of this plugin.

Usage

Webpack configuration

In your webpack.config.js file the plugin should be instantiated as follows:

new GulpInjectPlugin(target, assetsOrChunks, options)

Where:

  • target is the string name of a chunk containing a html asset or a html asset relative to output.path. It will be edited in place.
  • assetsOrChunks is a single string|RegExp or Array.<string|RegExp> list of chunk names and/or asset names relative to output.path.
  • options is an optional hash object of options per the Gulp Inject API.

In full this would look like the following:

var IndexHTMLPlugin     = require('indexhtml-webpack-plugin'),
    ChunkManifestPlugin = require('chunk-manifest-webpack-plugin')
    GulpInjectPlugin    = require('gulp-inject-webpack-plugin');

module.exports = {
  context : __dirname,
  entry   : {
    html  : './src/index.html',
	vendor: './src/vendor.js',
	index : './src/index.js'
  },
  output  : {
    path                                 : './build',
    filename                             : 'assets/[name].[chunkhash].js',
    chunkFilename                        : 'assets/[name].[chunkhash].js',
    devtoolModuleFilenameTemplate        : '[absolute-resource-path]',
    devtoolFallbackModuleFilenameTemplate: '[absolute-resource-path]?[hash]'
  },
  module  : {
    loaders: [
	  {
        test  : /\.html?$/i,
        loader: 'html?removeComments=false&attrs=img:src link:href'
      }
    ]
  },
  plugins : [
    new IndexHTMLPlugin('html', 'index.html'),
	new ChunkManifestPlugin(),
	new GulpInjectPlugin('html', ['manifest.json', 'vendor', /^vendor\./, 'index'])
  ]
}

The output options should be configured to your own taste, but it is a good idea to use a chunkhash for long term caching.

Note the usage of IndexHTMLPlugin. This allows you to add assets such as favicon.ico to your HTML such that they are processed by Webpack.

Note the usage of ChunkManifestPlugin. This is important for long term caching and will produce a manifest.json that should be injected as the first item.

Note the usage of a Regular Expression for the vendor chunk. This will allow you to do bundle splitting as discussed below.

Source file

The ./src/index.html of the Webpack configuration is the source file for your project html file.

This source file should include the necessary injection placeholder comments used by Gulp Inject. For example:

<!DOCTYPE html>
<html>
<head>
  <!-- inject:css -->
  <!-- endinject -->
</head>
<body>
  <!-- inject:json -->
  <!-- endinject -->
  
  <!-- inject:js -->
  <!-- endinject -->
</body>
</html>

Note that the additional <!-- inject:json --> placeholder is necessary where you wish to inject the cache manifest .json file.

Options

Where the optional options hash is specified it is passed to Gulp Inject.

Note that options.quiet is asserted by default. This prevents Gulp Inject from creating log output in the Gulp Utils format. However you may find this option useful for debugging problems.

Regular Expressions (Bundle Splitting)

Sure we could automatically detect the files omitted in your compile and pass them to Gulp Inject. However we would not be able to determine the correct order.

Chunk order is important, and it may even be that certain chunks should only be included in certain html files. For this reason we do not automatically detect and the assetsOrChunks list is explicit.

But your code may define arbitrary split points and you wont't want this to be coupled with the assetsOrChunks list in your configuration. We can remedy this by using one or more Regular Expression elements in the assetsOrChunks list. The limitation being you must name chunks in order to write a meaningful expression.

Here is an example for a simple vendor.js, split using common-js syntax to split chunk vendor into chunks vendor (empty), vendor.jquery, vendor.angular and vendor (rest).

require.ensure([], function() {
    require('jquery');
    require.ensure([], function() {
        require('angular');
        require.ensure([], function() {
            ...
        }, 'vendor.rest');
    }, 'vendor.angular');
}, 'vendor.jquery');

The otherwise empty vendor chunk will be the entry chunk and will contain the Webpack prelude. Therefore it needs to come first. The order in which the remaining vendor.* chunks are injected does not matter because require.ensure() determines the execution order. Therefore we can group them all together with the single expression /^vendor\./. All of this is shown in the example configuration above.

Chunk Manifest

In addition to the default transforms the plugin adds a transform for .json files which will embed the Cache Manifest JSON data in the page.

Similar to Gulp Inject, all transforms are exported under the hash GulpInjectPlugin.transform.

By default GulpInjectPlugin.transform.html.json expects the default manifest variable name of webpackManifest. However you may change it by using a more explicit plugin configuration.

module.exports = {
  ...
  plugins: [
    new IndexHTMLPlugin('html', 'index.html'),
	new ChunkManifestPlugin({
      filename        : 'foo.json',
      manifestVariable: 'bar'
	}),
	new GulpInjectPlugin('index'),
	new GulpInjectPlugin('foo.json', {
	  transform: GulpInjectPlugin.transform.html.json.withManifestVariableName('bar')
	})
  ]
}

Don't forget to include a JSON injection placeholder, such as <!-- inject:json -->, in your HTML source file.