@kitschpatrol/eleventy-plugin-parcel

1.0.5 • Public • Published

@kitschpatrol/eleventy-plugin-parcel

NPM Package @kitschpatrol/eleventy-plugin-parcel License: MIT

A plugin integrating the Parcel build tool and dev server with the Eleventy static site generator.

Overview

This plugin adds a Parcel bundling step to the Eleventy build process, and (optionally) allows the use of the Parcel Development Server as middleware during development.

Parcel is invoked automatically each time Eleventy finishes a build of your site, performing additional optimization and transpilation of various scripts and resources. Eleventy then launches its integrated development server to provide a preview of the site with automatic reloading when files are changed.

This post-processing step happens entirely within Eleventy's plugin system; no additions or modifications to your NPM scripts are required.

Getting started

Dependencies

This plugin is designed for Eleventy 2.x and Parcel 2.x. It is not compatible with Eleventy 1.x. It has not yet been tested with Elevent 3.x. Node 14+ is required.

The installation instrutions below assume you already have an Elevent 2.x project that you want to add Parcel to.

Installation

  1. Add the plugin to your Eleventy project:

    $ npm install --save-dev @kitschpatrol/eleventy-plugin-parcel
    
  2. Load the plugin in your .eleventy.js file:

    const eleventyParcelPlugin = require("@kitschpatrol/eleventy-plugin-parcel");
    
    module.exports = function (eleventyConfig) {
      eleventyConfig.addPlugin(eleventyParcelPlugin);
    };

    Note that if you do not want to use the Parcel Development Server as middleware when serving your site, pass the useMiddleware: false option when adding the plugin:

    const eleventyParcelPlugin = require("@kitschpatrol/eleventy-plugin-parcel");
    
    module.exports = function (eleventyConfig) {
      eleventyConfig.addPlugin(eleventyParcelPlugin { useMiddleware: false });
    };

    This serves your site as usual via an unmodified version of the Eleventy Dev Server, but Parcel will still process your output.

  3. Create a .parcelrc file in your project's root including at least the following:

    {
      "extends": "@parcel/config-default",
      "resolvers": ["@mischnic/parcel-resolver-root", "..."]
    }

    You must include this for absolute links to resolve correctly in the output subfolder when Parcel spiders through your site!

Usage

Build and run your Eleventy project as usual. The output from Eleventy will be passed to Parcel, which will process the site, replacing the contents of your output folder (usually _site), and then start the Eleventy Dev Server:

$ npx @11ty/eleventy --serve --quiet

A normal Eleventy build will output your site with all Parcel optimizations enabled:

$ npx @11ty/eleventy

Configuration

Additional configuration may be passed to Parcel when the plugin is added to Eleventy's configuration.

The available top-level option keys are as follows:

  • parcelOptions

    Object passed to configure additional options as specified by Parcel's InitialParcelOptions type.

    Defaults to:

    {
      parcelOptions: {
        entries: "index.html",
        defaultConfig: "@parcel/config-default",
        shouldDisableCache: true,
        shouldAutoInstall: true,
        serveOptions: {
          port: 3000,
        },
        hmrOptions: {
          port: 3001,
        }
      }
    }

    Important notes about how the plugin dynamically modifies the parcelOptions object in an effort to make your life more convenient:

    By default, Parcel's mode option is set dynamically based on the context of the build. Serve builds, e.g. npx @11ty/eleventy --serve, gets "development" mode, while release builds, e.g. npx @11ty/eleventy gets "production". You can override this by passing an explicit mode string to your parcelOptions.

    The Plugin automatically uses your Eleventy project's output folder to correctly prefix your parcelOptions.entries string or array.

    Similarly, for release builds, Parcel's defaultTargetOptions.distDir path is automatically set to match Eleventy's output.

  • tempFolderName

    String with name of folder to stage the Parcel builds. Defaults to .11ty-parcel-temp There's little reason to change this unless there is a conflict. This folder is automatically created and cleaned up during the release build process, but may linger during a serve build. It's recommended to add this path, along with .parcel-cache to you .gitignore.

  • useMiddleware

    Boolean specifying whether to use the Parcel development server as middleware. Defaults to true.

  • middlewareOptions

    Object passed to the middleware (if useMiddleware: true) as specified by the http-proxy-middleware options type.

Parcel will also pull configuration from a .parcelrc file in your project's root to further customize the build process.

Examples

Here are a few example configurations to customize the Parcel's plugin's behavior. These object are passed to the plugin via the addPlugin method, usually in your projects .eleventy.js file.

Skip middleware

Skip the Parcel middleware and always build with all Parcel's optimizations enabled, regardless of invocation context:

const eleventyParcelPlugin = require("@kitschpatrol/eleventy-plugin-parcel");

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyParcelPlugin, {
    parcelOptions: {
      mode: "production",
    },
    useMiddleware: false,
  });
};

Custom rewrite

Customize settings passed to http-proxy-middleware to rewrite paths in a way that allows you to drop the .html from URLs. This works well with the parcel-optimizer-friendly-urls Parcel plugin.

const eleventyParcelPlugin = require("@kitschpatrol/eleventy-plugin-parcel");

module.exports = function (eleventyConfig) {
  eleventyConfig.addPlugin(eleventyParcelPlugin, {
    useMiddleware: true,
    middlewareOptions: {
      pathRewrite: {
        "^([^.]+?)$": "$1.html",
      },
    },
  });
};

Background

Motivation

Simplicity and a sense of containment are part Eleventy's charm, and there's a certain appeal to keeping the build process as "close to the core" as possible, even as a site's complexity accumulates. The very thorough eleventy-high-performance-blog starter template illustrates this philosophy in practice.

For a while I've hewn to a similar approach in my own projects, but have found myself plumbing together byzantine chains of smaller tools to optimize images, add cache-busting hashes, generate CSP headers, etc. etc. — problems that have been solved several times over by a variety of build tools.

An official asset pipeline has been a topic of discussion on Eleventy's issue pages over the years. Vite seems likely to be ordained as such, but Parcel has significant feature overlap — so I wanted to kick the tires on it as well as a point of comparison.

Implementation notes

  • Passthrough files must be copied to the output folder to be accessible to Parcel (the plugin sets eleventyConfig.setServerPassthroughCopyBehavior("copy");)
  • Not tested with Eleventy's Serverless or Edge features
  • The dom-diffing morphdom functionality integrated in the Eleventy Dev Server's auto-reloading logic does not play well with Parcel's output, and must be disabled (the plugin sets eleventyConfig.setServerOptions({ domdiff: false });)
  • Parcel's caching system seems to have issues with Eleventy's output, and is disabled via the shouldDisableCache option
  • Parcel is configured with shouldAutoInstall enabled by default, which means it will automatically make changes to your package.json as plugins are needed to handle various file types
  • To avoid duplication of certain configuration parameters, the plugin writes an object related to the parcel-resolver-root Parcel plug-in default to your package.json if needed
  • Unlike Parcel 1.x, Parcel 2.x does not bundle middleware functionality as part of its development server... Instead, the plugin establishes the middleware proxy via http-proxy-middleware

Similar projects

Many others have combined Parcel and Eleventy in various ways and at different points in the build chain:

The future

  • [ ] Eleventy 3.x testing and support
  • [ ] Alternative to resolver dependency
  • [ ] Pass resolver plugin options differently to avoid dynamically modifying package.js
  • [ ] Support Parcel's cache (currently has issues with reloading)
  • [ ] Legacy BrowserSync dev server reload timing issues
  • [ ] More intelligent Parcel entry point than index.html to accommodate sites with un-crawlable pages

Maintainers

@kitschpatrol

Acknowledgements

This plugin is basically a port of Zach Leat's eleventy-plugin-vite from Vite to Parcel.

Contributing

Issues and pull requests are welcome.

License

MIT © Eric Mika

Package Sidebar

Install

npm i @kitschpatrol/eleventy-plugin-parcel

Weekly Downloads

5

Version

1.0.5

License

MIT

Unpacked Size

25.2 kB

Total Files

11

Last publish

Collaborators

  • kitschpatrol