rollup-plugin-minify-html-literals icon indicating copy to clipboard operation
rollup-plugin-minify-html-literals copied to clipboard

feat: make additional pipeline between source and minifier.

Open houd1ni opened this issue 6 years ago • 2 comments

I want to use css preprocessor, therefore I have to use custom minifier function, where the last call would be to minify.minifyHTMLLiterals.

How about making a special function, that accepts next(processedSource) as a callback, where all the preprocessor stuff would perform? next would finally call minify.minifyHTMLLiterals.

houd1ni avatar Aug 19 '19 11:08 houd1ni

PS: I can make a PR.

houd1ni avatar Aug 19 '19 11:08 houd1ni

The whole focus of this plugin is on one task: minifying. I'd be hesitant to add non-minifying features to it so that it stays lightweight.

I've definitely talked with people about writing a new tool that can do this kind of work, but in the meantime it might be more efficient to write your own plugin using parse-literals, while referring to this and minify-html-literals for inspiration on how I'm handling extra fluff like include/exclude and source maps.

Here's a super basic implementation. You could define it inline in your rollup.config.js, or as a separate plugin:

import { parseLiterals } from 'parse-literals';
import postcss from 'postcss';

export default function postcssLiterals() {
  // Create the postcss processor with whatever plugins. Could pass in plugins via options.
  const processor = postcss(plugins);

  return {
    name: 'postcss-literals',
    async transform(code, id) {
      // Get template literals
      const templates = parseLiterals(code);
      // I'll explain why we're reversing them in a minute
      for (let template of templates.reverse()) { 
        // Check if it's a css`` tagged literal
        if (template.tag === 'css') {
          // Replace the JS expressions with a CSS comment so that the string isn't 
          // missing parts. Make sure your postcss plugins don't modify it!
          const css = template.parts.map(part => part.text).join('/* JS-EXPRESSION */');
          // Run postcss on the CSS string
          const result = await processor.process(plugins, css);
          // Split the resulting string back into its individual template parts
          const resultParts = result.css.split('/* JS-EXPRESSION */');
          // Update the source code. Remember that line numbers will change as you're 
          // updating the code. I find it's best to update it in reverse so you don't 
          // have to worry about that.
          for (let i = template.parts.length - 1; i > -1; i--) {
            const part = template.parts[i];
            // stitch it back together!
            code = code.substring(0, part.start) + 
              resultParts[i] +  
              code.substring(part.end);
          }
        }
      }

      return { code };
    }
  };
}

You'd probably want it to run before minifying

rollup.config.js

import minifyLiterals from 'rollup-plugin-minify-literals';
import postcssLiterals from './postcss-literals-plugin';

export default {
  input: 'index.js',
  output: { file: 'bundle.js' },
  plugins: [
    postcssLiterals(),
    minifyLiterals()
  ]
}

asyncliz avatar Aug 19 '19 13:08 asyncliz