@kitschpatrol/eleventy-plugin-parcel
v1.0.8
Published
A plugin integrating the Parcel build tool and dev server with the Eleventy static site generator.
Downloads
53
Maintainers
Readme
@kitschpatrol/eleventy-plugin-parcel
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 Eleventy 3.x. Node 14+ is required.
The installation instrutions below assume you already have an Eleventy 2.x project that you want to add Parcel to.
Installation
Add the plugin to your Eleventy project:
$ npm install --save-dev @kitschpatrol/eleventy-plugin-parcel
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.
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 explicitmode
string to yourparcelOptions
.The Plugin automatically uses your Eleventy project's
output
folder to correctly prefix yourparcelOptions.entries
string or array.Similarly, for release builds, Parcel's
defaultTargetOptions.distDir
path is automatically set to match Eleventy'soutput
.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 aserve
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 yourpackage.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:
- Michelle Barker's eleventy-parcel
- Rico Sta. Cruz's eleventy-parcel-demo
- Mark van Seventer's eleventy-parcel-boilerplate
- Chris D. Macrae's parceleventy
- Dusty Candland's 11ty-starter
Also:
- CloudSh blog post
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
Acknowledgments
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