Skip to content

Gatsby plugin for optimizing generated static files.

License

Notifications You must be signed in to change notification settings

mohatt/gatsby-plugin-postbuild

Repository files navigation

Gatsby Postbuild

Provides an easy way to transform, modify or optimize static files generated by Gatsby using an extendable event-based tasks API. A Postbuild task is a set of functions that hook into certain events emitted by file transformers.

The plugin comes with these tasks out of the box:

  • Purgecss
    Optimizes HTML/CSS files by removing unused CSS selectors.
  • HTTP Headers
    Automatically generates headers configuration file for different hosting providers
  • Minify
    Minifies HTML inline scripts and styles using terser and cssnano.

Installation

Install with npm

$ npm install gatsby-plugin-postbuild

or yarn

$ yarn add gatsby-plugin-postbuild

Usage

All tasks that come bundled with the plugin are disabled by default so you will need to explicitly enable the ones you're going to use

// in your `gatsby-config.js`
plugins: [
  {
    resolve: `gatsby-plugin-postbuild`,
    options: {
      purgecss: {
        enabled: true
      },
      'http-headers': {
        enabled: true
      }
    }
  }
]

Every task has its own options that can be set as well. See tasks from more info

plugins: [
  {
    resolve: `gatsby-plugin-postbuild`,
    options: {
      purgecss: {
        enabled: true,
        ignore: ['resume/index.html'],
        allowSymbols: true
      },
      'http-headers': {
        enabled: true,
        provider: 'netlify',
        headers: {
          '[*]': {
            'X-Frame-Options': 'DENY',
            'X-XSS-Protection': '1; mode=block'
          }
        }
      }
    }
  }
]

Options

Define your own task

You can define custum events using the events option and the plugin will import them as a Postbuild task.

Lets say you want to manipulate the contents of svg files under /public, you can define a simple event like this:

options: {
  events: {
    svg: {
      contents: ({ raw, file }) => {
        // do something with the data
        return raw
      }
    }
  }
}

You can also use a glob pattern to match specific files

options: {
  events: {
    '/icons/*.svg': {
      contents: ({ raw, file }) => {
        // do something with the data
        return raw
      }
    }
  }
}

The contents event we used above is emitted by the generic file transformer which is used for unkown file types. Other known file types will have different set of events that will allow transforming files in a more structured way.

In this example, we will define an event that is specific to html files. Lets say you would like to strip out all comments from html files

options: {
  events: {
    html: {
      node: ({ node, file }) => {
        if (node.nodeName === '#comment') {
          file.adaptor.detachNode(node)
        }
      }
    }
  }
}

Learn more about the HTML file transformer

Processing options

You can change how files are processed using the processing option

options: {
  processing: {
    strategy: 'parallel',
    concurrency: 20
  }
}

Processing strategy accepts two values:

  • parallel: files will be read, processed and written in one step all at the same time (better memory consumption)
  • sequential: files will be processed in 3 steps with the last step being run in sequential order (consumes more memory but allows processing files based on data collected from all files)

Concurrency option sets the maximum number of files to process at once and can be set for both processing strategies.

You can also specifiy custom processing options for a specific file type

options: {
  extensions: {
    html: {
      strategy: 'sequential',
      concurrency: 15
    }
  }
}

Ignoring files

You can exclude specific files from being processed by the plugin using ignore option

options: {
  ignore: [
    'index.html',
    'icons/logo.svg'
  ]
}

You can also exclude files from being processed by a specific task

options: {
  purgecss: {
    ignore: [
      'index.html',
      'resume/index.html'
    ]
  }
}

Reporting

By default, the plugin:

  • generates a postbuild.log.json under /public after every build
  • prints a summary report during build with a list of file changes

You can change this behaviour using reporting option

options: {
  reporting: {
    log: true,
    console: false
  }
}

or enable/disable the reporting feature as a whole with a boolean value

options: {
  reporting: false
}

Defaults

These are the default plugin options defined in src/options.ts.

plugins: [
  {
    resolve: 'gatsby-plugin-postbuild',
    options: {
      enabled: true,
      reporting: true,
      ignore: [],
      events: {},
      processing: {
        strategy: 'parallel',
        concurrency: 10
      },
      extensions: {}
    }
  }
]

File transformers

Postbuild uses file transformers to process files of different types, file transformers read the files, processes them and emitt certain events, tasks define functions that hook into those events to perform certain actions. Thats basically how the plugin works.

Generic file transformer

Handles files with unknown extensions.

Events

contents: ({ raw, options, file, event, filesystem, gatsby }) => string

  • Emitted when the file is about to be written

HTML file transformer

Uses Parse5 to compile HTML files into AST then emits some events to be consumed by tasks.

Events

parse: ({ html, options, file, event, filesystem, gatsby }) => string

  • Emitted before parsing the HTML string

tree: ({ options, file, event, filesystem, gatsby }) => void

  • Emitted after HTML is compiled into AST

node: ({ node, options, file, event, filesystem, gatsby }) => void

  • Emitted for every AST node

serialize: ({ options, file, event, filesystem, gatsby }) => void

  • Emitted before serializing AST back to HTML string

write: ({ html, options, file, event, filesystem, gatsby }) => string

  • Emitted when the file is about to be written

Lifecycle events

These events are emitted at certain run time points.

Events

on.postbuild: ({ options, event, filesystem, gatsby }) => void

  • Emitted before processing files to allow tasks to run setup code

on.shutdown: ({ options, event, filesystem, gatsby }) => void

  • Emitted after processing files to allow tasks to run teardown code

[extension].configure: ({ config, options, event, filesystem, gatsby }) => void

  • Emitted before processing files of a certain extension to allow tasks to read/write processing options for that extension.

License

MIT