diff --git a/_tests/pdf.test.js b/_tests/pdf.test.js index c66523f37..7528e5d1e 100644 --- a/_tests/pdf.test.js +++ b/_tests/pdf.test.js @@ -1,7 +1,6 @@ -const test = require('node:test'); - -import { execa } from 'execa'; import { PDFDocument } from 'pdf-lib'; +import { execa } from 'execa'; +import test from 'node:test'; // Start a new default publication, build it, and make the pdf var { stderr, stdout } = await execa("npx",["quire","new", "--quire-path", "$(pwd)/packages/11ty", "test-pub"]) diff --git a/packages/11ty/.eleventy.js b/packages/11ty/.eleventy.js index 77672c49c..58d38fdf1 100644 --- a/packages/11ty/.eleventy.js +++ b/packages/11ty/.eleventy.js @@ -1,45 +1,68 @@ -require('module-alias/register') - -const copy = require('rollup-plugin-copy') -const fs = require('fs-extra') -const packageJSON = require('./package.json'); -const path = require('path') -const scss = require('rollup-plugin-scss') - -const chalkFactory = require('~lib/chalk') +import fs from 'fs-extra' +import path from 'node:path' /** - * Quire features are implemented as Eleventy plugins + * Eleventy plugins */ -const { +import { EleventyHtmlBasePlugin, + IdAttributePlugin, + InputPathToUrlTransformPlugin, EleventyRenderPlugin -} = require('@11ty/eleventy') -const citationsPlugin = require('~plugins/citations') -const collectionsPlugin = require('~plugins/collections') -const componentsPlugin = require('~plugins/components') -const dataExtensionsPlugin = require('~plugins/dataExtensions') -const directoryOutputPlugin = require('@11ty/eleventy-plugin-directory-output') -const figuresPlugin = require('~plugins/figures') -const filtersPlugin = require('~plugins/filters') -const frontmatterPlugin = require('~plugins/frontmatter') -const globalDataPlugin = require('~plugins/globalData') -const i18nPlugin = require('~plugins/i18n') -const lintersPlugin = require('~plugins/linters') -const markdownPlugin = require('~plugins/markdown') -const navigationPlugin = require('@11ty/eleventy-navigation') -const pluginWebc = require('@11ty/eleventy-plugin-webc') -const searchPlugin = require('~plugins/search') -const shortcodesPlugin = require('~plugins/shortcodes') -const syntaxHighlightPlugin = require('@11ty/eleventy-plugin-syntaxhighlight') -const transformsPlugin = require('~plugins/transforms') -const vitePlugin = require('~plugins/vite') +} from '@11ty/eleventy' +// import { eleventyImageTransformPlugin } from '@11ty/eleventy-img' +import directoryOutputPlugin from '@11ty/eleventy-plugin-directory-output' +import navigationPlugin from '@11ty/eleventy-navigation' +import pluginWebc from '@11ty/eleventy-plugin-webc' +import syntaxHighlightPlugin from '@11ty/eleventy-plugin-syntaxhighlight' +import UpgradeHelper from '@11ty/eleventy-upgrade-help' + +/** + * Quire plugins for Eleventy + * dynamic import of the default export from local plugins modules + */ +// const plugins = +// fs.readdir('_plugins', { withFileTypes: true }, (error, entries) => { +// entries.forEach((entry) => { +// if (entry.isDirectory()) { +// const { default: plugin } = await import(`./plugins/${entry.name}`) +// eleventyConfig.addPlugin(plugin, collections) +// } +// }) +// }) +import citationsPlugin from '#plugins/citations/index.js' +import collectionsPlugin from '#plugins/collections/index.js' +import componentsPlugin from '#plugins/components/index.js' +import dataExtensionsPlugin from '#plugins/dataExtensions/index.js' +import figuresPlugin from '#plugins/figures/index.js' +import filtersPlugin from '#plugins/filters/index.js' +import frontmatterPlugin from '#plugins/frontmatter/index.js' +import globalDataPlugin from '#plugins/globalData/index.js' +import i18nPlugin from '#plugins/i18n/index.js' +import lintersPlugin from '#plugins/linters/index.js' +import markdownPlugin from '#plugins/markdown/index.js' +import searchPlugin from '#plugins/search/index.js' +import shortcodesPlugin from '#plugins/shortcodes/index.js' +import transformsPlugin from '#plugins/transforms/index.js' +import vitePlugin from '#plugins/vite/index.js' + +/** + * Application modules + */ +import chalkFactory from '#lib/chalk/index.js' +// Read package.json manually for now, see: https://github.com/11ty/eleventy/issues/3128 +// When issue merged, use: import packageJSON from './package.json' with { type: 'json' }; +const packageJSON = JSON.parse( + (await fs.readFile(new URL('package.json', import.meta.url))).toString() +) + +// eslint-disable-next-line no-unused-vars const { error } = chalkFactory('eleventy config') const inputDir = process.env.ELEVENTY_INPUT || 'content' const outputDir = process.env.ELEVENTY_OUTPUT || '_site' -const publicDir = process.env.ELEVENTY_ENV === 'production' ? 'public' : false // publicDir should be set explicitly to false in development +const publicDir = process.env.ELEVENTY_ENV === 'production' ? 'public' : false // publicDir should be set explicitly to false in development /** * Eleventy configuration @@ -48,7 +71,44 @@ const publicDir = process.env.ELEVENTY_ENV === 'production' ? 'public' : false / * @param {Object} base eleventy configuration * @return {Object} A modified eleventy configuation */ -module.exports = function(eleventyConfig) { +export default async function (eleventyConfig) { + /** + * Eleventy v2 to v3 upgrade helper + * @see https://www.11ty.dev/docs/plugins/upgrade-help/ + */ + eleventyConfig.addPlugin(UpgradeHelper) + + const dataDir = process.env.ELEVENTY_DATA || '_computed' + const includesDir = process.env.ELEVENTY_INCLUDES || path.join('..', '_includes') + const layoutsDir = process.env.ELEVENTY_LAYOUTS || path.join('..', '_layouts') + + // ⚠️ input and output dirs are _relative_ to the `.eleventy.js` module + eleventyConfig.setInputDirectory(inputDir) + eleventyConfig.setOutputDirectory(outputDir) + // ⚠️ the following directories are _relative_ to the `input` directory + eleventyConfig.setDataDirectory(dataDir) + eleventyConfig.setIncludesDirectory(includesDir) + eleventyConfig.setLayoutsDirectory(layoutsDir) + + /** + * All of the following template formats support universal shortcodes. + * + * Nota bene: + * Markdown files are pre-processed as Liquid templates by default. This + * means that shortcodes available in Liquid templates are also available + * in Markdown files. Likewise, if you change the template engine for + * Markdown files, the shortcodes available for that templating language + * will also be available in Markdown files. + * @see {@link https://www.11ty.dev/docs/config/#template-formats} + */ + eleventyConfig.setTemplateFormats([ + '11ty.js', // JavaScript + 'html', // HTML + 'liquid', // Liquid + 'md', // Markdown + 'njk' // Nunjucks + ]) + /** * Override addPassthroughCopy to use _absolute_ system paths. * @see https://www.11ty.dev/docs/copy/#passthrough-file-copy @@ -116,7 +176,17 @@ module.exports = function(eleventyConfig) { eleventyConfig.addPlugin(EleventyHtmlBasePlugin) /** - * Plugins are loaded in this order: + * @see https://www.11ty.dev/docs/plugins/id-attribute/ + */ + eleventyConfig.addPlugin(IdAttributePlugin) + + /** + * @see https://www.11ty.dev/docs/plugins/inputpath-to-url/ + */ + eleventyConfig.addPlugin(InputPathToUrlTransformPlugin) + + /** + * Plugins are loaded in this order: * 1) immediately invoked * 2) addPlugin statements * Plugins that mutate globalData must be added before other plugins @@ -171,11 +241,33 @@ module.exports = function(eleventyConfig) { * @property {Boolean} useTransform - Use WebC transform to process all HTML output */ eleventyConfig.addPlugin(pluginWebc, { - components: '_includes/components/**/*.webc', + components: [ + '_includes/components/**/*.webc', + 'npm:@11ty/eleventy-img/*.webc' + ], transformData: {}, - useTransform: false, + useTransform: false }) + /** + * Configure the Eleventy Image plugin + * @see https://www.11ty.dev/docs/plugins/image/ + */ + // eleventyConfig.addPlugin(eleventyImageTransformPlugin, { + // defaultAttributes: { + // decoding: 'async', + // loading: 'lazy' + // }, + // filenameFormat: (id, src, width, format, options) => { + // const extension = path.extname(src) + // const name = path.basename(src, extension) + // return `${name}-${width}w.${format}` + // }, + // formats: ['jpeg'], + // outputDir: '.', + // urlPath: '/img/' + // }) + /** * Register a plugin to run linters on input templates * Nota bene: linters are run *before* applying layouts @@ -225,59 +317,12 @@ module.exports = function(eleventyConfig) { eleventyConfig.watchIgnores.add('_pdf') eleventyConfig.watchIgnores.add('_temp') - const { pathname: pathPrefix } = globalData.publication - return { - /** - * @see {@link https://www.11ty.dev/docs/config/#configuration-options} - */ - dir: { - // ⚠️ input and output dirs are _relative_ to the `.eleventy.js` module - input: inputDir, - output: outputDir, - // ⚠️ the following directories are _relative_ to the `input` directory - data: process.env.ELEVENTY_DATA || '_computed', - includes: process.env.ELEVENTY_INCLUDES || path.join('..', '_includes'), - layouts: process.env.ELEVENTY_LAYOUTS || path.join('..', '_layouts'), - }, - /** - * The default global template engine to pre-process HTML files. - * Use false to avoid pre-processing and passthrough copy the content (HTML is not transformed, so technically this could be any plaintext). - * @see {@link https://www.11ty.dev/docs/config/#default-template-engine-for-html-files} - */ - htmlTemplateEngine: 'liquid', - /** - * Suffix for template and directory specific data files - * @example '.data' will search for `*.data.js` and `*.data.json` data files. - * @see {@link https://www.11ty.dev/docs/data-template-dir/ Template and Directory Specific Data Files} - */ - jsDataFileSuffix: '.data', - /** - * The default global template engine to pre-process markdown files. - * Use false to avoid pre-processing and only transform markdown. - * @see {@link https://www.11ty.dev/docs/config/#default-template-engine-for-markdown-files} - */ - markdownTemplateEngine: 'liquid', - /** - * @see {@link https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix} - */ - pathPrefix, - /** - * All of the following template formats support universal shortcodes. - * - * Nota bene: - * Markdown files are pre-processed as Liquid templates by default. This - * means that shortcodes available in Liquid templates are also available - * in Markdown files. Likewise, if you change the template engine for - * Markdown files, the shortcodes available for that templating language - * will also be available in Markdown files. - * @see {@link https://www.11ty.dev/docs/config/#template-formats} - */ - templateFormats: [ - '11ty.js', // JavaScript - 'hbs', // Handlebars - 'liquid', // Liquid - 'md', // Markdown - 'njk', // Nunjucks - ] - } + /** + * Suffix for template and directory specific data files + * @example '.data' will search for `*.data.js` and `*.data.json` data files + * @see https://www.11ty.dev/docs/config/#change-base-file-name-for-data-files + * @see https://www.11ty.dev/docs/config/#change-file-suffix-for-data-files + */ + eleventyConfig.setDataFileBaseName('index') + eleventyConfig.setDataFileSuffixes(['.data', '']) } diff --git a/packages/11ty/.eslintrc b/packages/11ty/.eslintrc deleted file mode 100644 index 776bb4a0b..000000000 --- a/packages/11ty/.eslintrc +++ /dev/null @@ -1,34 +0,0 @@ -{ - "env": { - "browser": true, - "es2021": true, - "node": true, - }, - "extends": "eslint:recommended", - "ignorePatterns": [ "**/*.min.js" ], - "overrides": [], - "parserOptions": { - "ecmaVersion": "latest", - "sourceType": "module" - }, - "rules": { - "getter-return": [ "error", { "allowImplicit": true } ], - "indent": [ "error", 2, { "SwitchCase": 1 } ], - "linebreak-style": [ "error", "unix" ], - "quotes": [ "error", "single", { "allowTemplateLiterals": true } ], - "no-console": "off", - "no-prototype-builtins": "off", - "no-unused-vars": "off", - "semi": [ "error", "never" ], - "sort-imports": [ - "warn", - { - "allowSeparatedGroups": false, - "ignoreCase": false, - "ignoreDeclarationSort": false, - "ignoreMemberSort": false, - "memberSyntaxSortOrder": ["none", "all", "multiple", "single"], - } - ], - } -} diff --git a/packages/11ty/.node-version b/packages/11ty/.node-version index 6d80269a4..e9dbbdadc 100644 --- a/packages/11ty/.node-version +++ b/packages/11ty/.node-version @@ -1 +1 @@ -18.16.0 +21.1.0 diff --git a/packages/11ty/CHANGELOG.md b/packages/11ty/CHANGELOG.md index 016f79733..b4ef232ac 100644 --- a/packages/11ty/CHANGELOG.md +++ b/packages/11ty/CHANGELOG.md @@ -12,6 +12,15 @@ Changelog entries are classified using the following labels: - `Fixed`: for any bug fixes - `Removed`: for deprecated features removed in this release +## [unreleased] + +### Bumped + +- Update dependency pins for `@11ty/eleventy`, `@11ty/eleventy-plugin-vite` to support Eleventy v3 + +### Breaking + +This release is updates the *major* version of `eleventy`, which requires using ECMAScript module (ESM) syntax for JavaScript code. Specifically, ESM `import` statements to use other modules and the `import.meta.url` property for a module's file path from within that module. For most Quire users this update should be transparent. For publications that have customized the quire code or import packages that are not already in the publication's package dependency tree changes may be needed to address ESM conformance to the custom modules. ## [1.0.0-rc.22] ### Changed diff --git a/packages/11ty/_includes/README.md b/packages/11ty/_includes/README.md index 5601b9524..ab139ff1c 100644 --- a/packages/11ty/_includes/README.md +++ b/packages/11ty/_includes/README.md @@ -29,9 +29,9 @@ The `data` property contains the final data from the [Eleventy data cascade](htt #### In an `11ty.js` `_include` ```javascript -const { html } = require('common-tags') +import { html } from 'common-tags' -module.exports = function(eleventyConfig, params) { +export default function(eleventyConfig, params) { const { publication } = params const siteTitle = eleventyConfig.getFilter('siteTitle') @@ -47,7 +47,7 @@ module.exports = function(eleventyConfig, params) { #### In an `11ty.js` `_layout` ```javascript -const { html } = require('common-tags') +import { html } from 'common-tags' exports.data = { layout: 'base' diff --git a/packages/11ty/_includes/components/abstract.js b/packages/11ty/_includes/components/abstract.js index 653a42e87..259aef3b7 100644 --- a/packages/11ty/_includes/components/abstract.js +++ b/packages/11ty/_includes/components/abstract.js @@ -1,10 +1,10 @@ -const { html } = require('~lib/common-tags') +import { html } from '#lib/common-tags/index.js' /** * Publication abstract * @param {Object} eleventyConfig */ -module.exports = function(eleventyConfig) { +export default function (eleventyConfig) { const markdownify = eleventyConfig.getFilter('markdownify') return function (params) { const { abstract } = params diff --git a/packages/11ty/_includes/components/accordion/global-controls.js b/packages/11ty/_includes/components/accordion/global-controls.js index dde2e1042..110667053 100644 --- a/packages/11ty/_includes/components/accordion/global-controls.js +++ b/packages/11ty/_includes/components/accordion/global-controls.js @@ -1,16 +1,16 @@ -const { html } = require('~lib/common-tags') +import { html } from '#lib/common-tags/index.js' /** * @param {Object} eleventyConfig * @returns Global Accordion Controls Shortcode */ -module.exports = function(eleventyConfig) { +export default function (eleventyConfig) { const { collapseText, expandText } = eleventyConfig.globalData.config.accordion.globalControls /** * @return {String} html markup for global accordion controls */ - return function() { + return function () { return html`
diff --git a/packages/11ty/_includes/components/analytics.js b/packages/11ty/_includes/components/analytics.js index 40ff2f9fb..90d07618a 100644 --- a/packages/11ty/_includes/components/analytics.js +++ b/packages/11ty/_includes/components/analytics.js @@ -1,13 +1,13 @@ -const { html } = require('~lib/common-tags') +import { html } from '#lib/common-tags/index.js' /** * Google Analytics * @param {Object} eleventyConfig * @param {Object} data */ -module.exports = function(eleventyConfig) { +export default function (eleventyConfig) { const { googleId } = eleventyConfig.globalData.config.analytics - return function(params) { + return function (params) { if (!googleId) return '' return html` ` diff --git a/packages/11ty/_includes/components/search.js b/packages/11ty/_includes/components/search.js index 52d9341ff..33839054c 100644 --- a/packages/11ty/_includes/components/search.js +++ b/packages/11ty/_includes/components/search.js @@ -1,12 +1,12 @@ -const { html } = require('~lib/common-tags') +import { html } from '#lib/common-tags/index.js' /** * Search Input - * + * * @param {EleventyConfig} eleventyConfig * @return {String} HTML tags */ -module.exports = function(eleventyConfig) { +export default function (eleventyConfig) { const icon = eleventyConfig.getFilter('icon') return (params) => { const { url } = params.publication @@ -45,7 +45,7 @@ module.exports = function(eleventyConfig) { type="search" value="" /> - ${icon({ type: 'search', description: 'Search'})} + ${icon({ type: 'search', description: 'Search' })}