link-media-html-webpack-plugin icon indicating copy to clipboard operation
link-media-html-webpack-plugin copied to clipboard

parses CSS filenames to automatically apply media HTML attribute to link elements

Link Media HTML Webpack Plugin

Build Status codecov

This is an extension plugin for the webpack plugin html-webpack-plugin.

It automatically adds the media attribute to generated <link> HTML elements, inferred from the CSS filename according to the pattern media_{base64MediaString}:

style.media_KG1pbi13aWR0aDogNzAwcHgpLCBoYW5kaGVsZCBhbmQgKG9yaWVudGF0aW9uOiBsYW5kc2NhcGUp.css

will be injected into the HTML template as:

<link src="styles.media_KG1pbi13aWR0aDogNzAwcHgpLCBoYW5kaGVsZCBhbmQgKG9yaWVudGF0aW9uOiBsYW5kc2NhcGUp.css" rel="stylesheet" media="(min-width: 700px), handheld and (orientation: landscape)" />

This is useful for print stylesheets or desktop/mobile-specific styles that the browser should only load depending on the @media match.

Installation

You must be running webpack on node 4.x or higher

Install the plugin with npm:

$ npm install --save-dev link-media-html-webpack-plugin

Basic Usage

Load the plugin

const LinkMediaHtmlWebpackPlugin = require('link-media-html-webpack-plugin');

and add it to your webpack config as follows:

plugins: [
    new HtmlWebpackPlugin(),
    new LinkMediaHtmlWebpackPlugin(),
]

you'll probably want to use this in conjunction with extract-text-webpack-plugin to split up the loaded assets so the browser can do its thing. Here's a sample webpack 2.x config:

const path = require('path');
const webpack = require('webpack');
const HTMLPlugin = require('html-webpack-plugin');
const LinkMediaHTMLPlugin = require('link-media-html-webpack-plugin');

const ExtractPlugin = require('extract-text-webpack-plugin');

// a utility provided by this plugin for easily forming the requisite filename syntax
const getMediaFilename = require('link-media-html-webpack-plugin/get-media-filename');

const getFilePath = (filename) => path.join(__dirname, 'src', filename);

const mainStyleExtractor = new ExtractPlugin('style.css');
const printStyleExtractor = new ExtractPlugin(getMediaFilename(getFilePath('style.print.css')));

webpack({
    entry: getFilePath('entry.js'),
    module: {
      loaders: [
        {
            test: /print\.css$/,
            use: printStyleExtractor.extract('css-loader'),
        }, {
            test: /\.css$/,
            exclude: /print\.css$/,
            use: mainStyleExtractor.extract('css-loader'),
        },
      ],
    },
    output: {
        path: OUTPUT_DIR,
    },
    plugins: [
        mainStyleExtractor,
        printStyleExtractor,
        new HTMLPlugin({
            minify: {
                collapseWhitespace: true,
            },
        }),
        new LinkMediaHTMLPlugin(),
    ],
});