Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: make additional pipeline between source and minifier. #3

Open
houd1ni opened this issue Aug 19, 2019 · 2 comments
Open

feat: make additional pipeline between source and minifier. #3

houd1ni opened this issue Aug 19, 2019 · 2 comments

Comments

@houd1ni
Copy link

houd1ni commented Aug 19, 2019

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
Copy link
Author

houd1ni commented Aug 19, 2019

PS: I can make a PR.

@asyncLiz
Copy link
Owner

asyncLiz commented Aug 19, 2019

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()
  ]
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants