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

Needs additional guidance around feeding getBundle through a minifier #7

Open
zachleat opened this issue Mar 4, 2023 · 3 comments
Open
Labels
bug Something isn't working education

Comments

@zachleat
Copy link
Member

zachleat commented Mar 4, 2023

If you run getBundle output through a minifier before the transform gets to it, it will get removed!

Specifically this quick tip: https://www.11ty.dev/docs/quicktips/inline-css/#capture-and-minify

<!-- capture the CSS content as a Nunjucks variable -->
{% set css %}
  {% include "sample.css" %}
  {% getBundle "css" %}
{% endset %}
<!-- feed it through our cssmin filter to minify -->
<style>
  {{ css | cssmin | safe }}
</style>

Workaround is to move the bundle outside of the css minification pipeline (and optionally use a bundle transform to minify instead):

<!-- capture the CSS content as a Nunjucks variable -->
{% set css %}
  {% include "sample.css" %}
{% endset %}
<!-- feed it through our cssmin filter to minify -->
<style>
  {{ css | cssmin | safe }}
</style>
<style>{% getBundle "css" %}</style>
@zachleat zachleat added bug Something isn't working education labels Mar 4, 2023
@zachleat zachleat changed the title Needs additional guidance around minification Needs additional guidance around minification of bundle content Mar 4, 2023
@zachleat zachleat changed the title Needs additional guidance around minification of bundle content Needs additional guidance around feeding bundle content through a minifier Mar 4, 2023
@zachleat zachleat changed the title Needs additional guidance around feeding bundle content through a minifier Needs additional guidance around feeding getBundle through a minifier Mar 4, 2023
zachleat added a commit to 11ty/11ty-website that referenced this issue Mar 4, 2023
@nhoizey
Copy link

nhoizey commented May 12, 2023

@zachleat I chose to add minification directly in my own template format (I support Sass, not CSS):

(I'm currently trying to move this code out of the project config file, into a plugin, so this should no longer be in the main branch soon.)

@elgandoz
Copy link

elgandoz commented May 24, 2023

The doco explains how to do it: Modify the bundle output. This is also more performant during the build.

Here's an example of what I'm doing in my site:
.eleventy.js

const bundlerPlugin = require("@11ty/eleventy-plugin-bundle");
const postcss = require('postcss');
const postcssNesting = require('postcss-nesting');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const UglifyJS = require("uglify-js");

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(bundlerPlugin, {
    transforms: [
      async function (code) {
        // this.type returns the bundle name.
        if (this.type === 'css') {
          // Same as Eleventy transforms, this.page is available here.
          let result = await postcss([
            // postcssNesting,
            autoprefixer,
            cssnano
          ]).process(code, { from: this.page.inputPath, to: null });
          return result.css;
        }
        if (this.type === 'js') {
          let minified = UglifyJS.minify(code);
          if (minified.error) {
            console.log("UglifyJS error: ", minified.error);
            return code;
          }
          return minified.code;
        }
        return code;
      }
    ]
  });
 }

head.njk

<head>
  [...]
  {% css %}
    {% include "assets/css/inline.css" %}
  {% endcss %}
  <!-- Inlined critical styles -->
  <style>{% getBundle "css" %}</style>
  
  <!-- Deferred non-critical styles -->
  <link rel="stylesheet" href="{% getBundleFileUrl 'css', 'defer' %}" media="print" onload="this.media='all'">
  <noscript>
  <link rel="stylesheet" href="{% getBundleFileUrl 'css', 'defer' %}">
  </noscript>
  
  <!-- Inlined js bundle -->
  <script>{% getBundle "js" %}</script>
</head>

@zyriab
Copy link

zyriab commented May 11, 2024

I tried replicating the example in the bottom of the readme but it did not work, ultimately, I used the solution by elgandoz and it's working fine.

As an example, here's the code that did not work:

    cfg.addBundle("css", {
        transforms: [
            (/** @type {string} */ input) => (new CleanCSS()).minify(input).styles
        ]
    });

    cfg.addBundle("js", {
        transforms: [
            async function(/** @type {string} */ input) {
                try {
                    const result = await minifyJs(input);
                    return result.code;
                } catch (e) {
                    // eslint-disable-next-line no-console
                    console.error(e);
                    return input;
                }
            }
        ]
    });

Have I messed up somewhere? I tried with non-arrow functions but still no success.

The working code:

    cfg.addPlugin(pluginBundle, {
        transforms: [
            async function(content) {
                // this.type returns the bundle name.
                if (this.type === "css") {
                    return (new CleanCSS).minify(content).styles;
                }

                if (this.type === "js") {
                    try {
                        const minified = await minifyJs(content);
                        return minified.code;
                    }
                    catch (e) {
                        // eslint-disable-next-line no-console
                        console.error(e);
                        return content;
                    }
                }

                return content;
            }
        ]
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working education
Projects
None yet
Development

No branches or pull requests

4 participants