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 🙏

© 2025 – Pkg Stats / Ryan Hefner

html-js-css-webpack-plugin

v1.0.5

Published

html generation and resource inline or md5 for webpack

Readme

html-js-css-webpack-plugin

lcxfs1991/html-res-webpack-plugin的基础上进行了两点修改:

  // html-res-webpack-plugin
  var basename = path.basename(filename);

  // html-webpack-plugin
  his.options.filename = path.relative(compiler.options.output.path, filename);
  • 修改$&$&` 引入的bug

中文文档

Why do I rewrite the whole thing

I rencently notice that webpack is based itself on chunks. Therefore, writing plugin logic based on chunk may be adaptable to the core and sprite of webpack.

Basic Concpets: chunks and assets

In webpack, the basic element is chunks. The values in entry of webpack config are chunks. For instance, index and detail in the following entry config are chunks' names; In most cases, chunk is a js file. But if you require stylesheet or other files in js, a js chunk will include not only js file but also the files you require.

entry: {
    index: xxx
    detail: xxx
}

What about assets? Assets are files will be exported by webpack. They can be any file types like stylesheets, images, html and so on.

How to start

src/index.html --> dist/index.html

<!DOCTYPE html>
<html lang="en" id="html">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-dns-prefetch-control" content="on" />
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no, minimal-ui" />
    <title>html-res-webpack-example</title>
</head>
<body>
    <div class="preview-wrapper"></div>
</body>
</html>

src/page/preview/main.js --> dist/js/preview/preview.js

require('./index.scss');

var init = function() {
    // some code here   
};

src/page/preview/index.scss --> dist/css/preview/preview.css

html, body {
    margin: 0;
}
// some code here

webpack.config.js

    var config = {
        hash: "-[hash:6]",
        chunkhash: "-[chunkhash:6]",
        contenthash: "-[contenthash:6]"
    };
    var webpackconfig = {
        entry: {
            'preivew/preview': [path.join(config.path.src, "/page/preview/main.js")],
        },

        /**
         *  webpack options below
         */
        .
        .
        .
        output: {
            publicPath: (config.env === 'prod') ? config.cdn : config.defaultPath,
            path: path.join(config.path.dist),
            filename: "js/[name]" + config.chunkhash + ".js"
        },
    
        .
        .
        .

        plugins: [
            // some other plugins
            new ExtractTextPlugin("./css/[name]" + config.contenthash + ".css"),
            new HtmlResWebpackPlugin({
                filename: "index.html",
                template: "src/index.html",
                chunks:{
                    'index': {
                        attr: {                     // attributes for index chunk
                            js: "async=\"true\"",
                            css: "offline",
                        },
                        inline: {                   // inline or not for index chunk
                            js: true,
                            css: true
                        }
                    }
                },
            });
        ]
    };

package.json

"scripts": {
    "dev": "webpack --progress --colors --watch",
    "publish-mac": "export NODE_ENV=prod&&webpack -p --progress --colors",
    "publish-windows": "SET NODE_ENV=prod&&webpack -p --progress --colors"
 },

One thing need to be noticed is hash and chunkhash. The difference between hash and chunkhash is that hash is the same for all resources and chunkhash is different for specific resource. Usually you are recommended to use chunkhash instead (Exception for style files required in an entry js file. They share the same chunkhash if you use extract-text-webpack-plugin. Please use contenthash instead in order to ensure hash for stylesheet changes only when content changes).

Another thing worth being noticed is the order of chunks. The order of resources that will be injected is based on the order of chunks in html-res-webpack-plugin.

Inject External Resource

Sometimes, you may need to use external common resources. If this is the case, please write options like following:

chunks:{
    'qreport': {
        external: true,                                 // tell the plugin not to append publicPath
        res:  "//s.url.cn/pub/js/qreport.js?_bid=2231", // resource path
        attr: {
            js: "async=\"true\"",
        }
    }
}

Multiple Html Page

Sometimes there are more than one html pages in your projects. In this situation, please use similar iteration code to add plugins for different html pages

var config = {
    hash: "-[hash:6]",
    chunkhash: "-[chunkhash:6]",
    contenthash: "-[contenthash:6]"
};

var route = ['index', 'detail'];

var webapckConfig = {
    entry: {
        "js/index": "xxx/index",
        "js/detail": "xxx/detail",
    }
};

let pageMapping = {
    'detail': {
        'js/detail': {
            attr:{
                js: "",
                css: "",
            }
        },
    },
    'index': {
        'js/index': {
            attr:{
                js: "",
                css: "",
            }
        },
    }
};

webpackConfig.addPlugins = function(plugin, opt) {
    devConfig.plugins.push(new plugin(opt));
};

route.html.forEach(function(page) {
    webapckConfig.addPlugins(HtmlResWebpackPlugin, {
        filename: page + ".html",
        template: "src/" + page + ".html",
        favicon: "src/favicon.ico",
        chunks: pageMapping[page],
    });
}); 

Favicon

webpack.config.js

new HtmlResWebpackPlugin({
    filename: "index.html",
    template: "xxx/index.html",
    favicon: "xxx/favicon.ico",
    chunks:[
        'js/index',
    ],
}),

Modify Html Content Before Output

new HtmlResWebpackPlugin({
    filename: "index.html",
    template: "src/index.html",
    templateContent: function(tpl) {
        // some modification of tpl
        // you can use this.options [user input plugin options]
        // and this.webpackOptions [webpack config] here, you can open index.js of the plugin
        // to check what options are offered
        return tpl;
    }
}),

Usage with copy-webpack-plugin-hash

copy-webpack-plugin-hash is a plugin that helps copy files directly without webpack parsing. I add namePattern option feature for it so that files generated by this plugin can also have hash (Once the main repo accepts my pull request, I will delete this temporary repo).

If you use copy-webpack-plugin for example, you can use html-res-webpack-plugin easily. For example, if you copy /xxx/libs folder to libs/. If the folder contains react and react-dom, you can add chunks libs/react/ and libs/react-dom in html-res-webpack-plugin.

plugins: [
    new CopyWebpackPlugin([
        {
            from: '/xxx/libs/',
            to: 'libs/'
        }
    ], {
        namePattern: "[name]-[contenthash:6].js"
    }),
    new HtmlResWebpackPlugin({
        filename: "index.html",
        template: config.path.src + "/resource-copy-plugin-1/index.html",
        chunks:[
            'libs/react',
            'libs/react-dom',
            'js/index',
        ],
    }),
]

Options

  • filename:
    • is required
    • generated filename
  • template:
    • is required
    • template source
  • chunks:
    • is required
    • [Array|Object]
    • injected chunks
    • examples:

[Array]

    entry: {
        'index': xxx,
        'detail': xxx,
        'libs/react': xxx,
    }

    plugins: [
        new HtmlResWebpackPlugin({
            /** other config */
            chunks: [
                'index',
                'detail',
                'libs/react'
            ]
        })
    ]

[Object]

    plugins: [
        new HtmlResWebpackPlugin({
            /** other config */
            chunks: {
                'qreport': {
                    external: true              // tell the plugin not to append publicPath
                    res: "xxx"                  // resource path
                },
                'index': {
                    attr: {                     // attributes for index chunk
                        js: "async=\"true\"",
                        css: "offline",
                    },
                },
                'detail': {
                    inline: {                   // inline or not for detail chunk
                        js: true,
                        css: true
                    }
                },
                'libs/react': nulls
            }
        })
    ]
  • htmlMinify:
    • is optional
    • please checkout html-minifier to see detail options. If set false | null, html files won't be compressed.
  • favicon:
    • is optional
    • favicon path, for example, "src/favicon.ico"
  • templateContent:
    • is optional
    • a point for developer to modify html content before output. this.options and this.webpackOptionscan be used in such a function.

Last Words

I add automatic testing samples fo for the plugin to ensure stablity and relablility. I starting using this plugin in internal development.

If you still don't understand README, you can checkout examples in specWepback where testing samples are located.

Changelog

  • v0.0.1 resouce inline and md5
  • v0.0.2 customized name and hash
  • v0.0.3 support favicon file
  • v0.0.4 fix adding prefix and adding md5 bugs
  • v0.0.5 offer templateContent to modify html content before output
  • v0.0.7 compatible with webpack2.0 README
  • v1.0.0 rewrite the whole thing and add testing function
  • v1.0.1 allow external resource to be injected