diff --git a/lib/build-pages/index.js b/lib/build-pages/index.js index 4f13858..607469c 100644 --- a/lib/build-pages/index.js +++ b/lib/build-pages/index.js @@ -254,6 +254,9 @@ export async function buildPagesDirect (src, dest, siteData, _opts) { ? siteData.templates.filter(t => templateFilterSet.has(t.templateFile.filepath)) : siteData.templates + // Merge once — globalVars and globalDataVars are constant for this build. + const templateGlobalVars = { ...globalVars, ...globalDataVars } + await Promise.all([ pMap(pagesToRender, async (page) => { try { @@ -274,9 +277,8 @@ export async function buildPagesDirect (src, dest, siteData, _opts) { pMap(templatesToRender, async (template) => { try { const buildResult = await templateBuilder({ - src, dest, - globalVars, + globalVars: templateGlobalVars, template, pages, }) diff --git a/lib/build-pages/page-builders/template-builder.js b/lib/build-pages/page-builders/template-builder.js index cdd4bf4..d428ff4 100644 --- a/lib/build-pages/page-builders/template-builder.js +++ b/lib/build-pages/page-builders/template-builder.js @@ -17,7 +17,7 @@ import { writeFile, mkdir } from 'fs/promises' * @template {Record} T - The type of variables for the template * @callback TemplateFunction * @param {object} params - The parameters for the template. - * @param {T} params.vars - All of the site globalVars. + * @param {T} params.vars - All of the site globalVars merged with global.data.js output. * @param {TemplateInfo} params.template - Info about the current template * @param {PageData[]} params.pages - An array of info about every page * @returns {Promise} @@ -46,12 +46,12 @@ import { writeFile, mkdir } from 'fs/promises' */ /** - * The template builder renders templates agains the globalVars variables + * The template builder renders templates against the globalVars variables. + * globalVars passed here already includes global.data.js output merged in. * @template {Record} T - The type of global variables for the template builder * @param {object} params - * @param {string} params.src - The src path of the site build. * @param {string} params.dest - The dest path of the site build. - * @param {T} params.globalVars - The resolvedGlobal vars object. + * @param {T} params.globalVars - globalVars merged with global.data.js output. * @param {TemplateInfo} params.template - The TemplateInfo of the template. * @param {PageData[]} params.pages - The array of PageData object. */ diff --git a/test-cases/general-features/index.test.js b/test-cases/general-features/index.test.js index f876b3d..3c6e8e3 100644 --- a/test-cases/general-features/index.test.js +++ b/test-cases/general-features/index.test.js @@ -103,6 +103,21 @@ test.describe('general-features', () => { const jsChunkFiles = files.filter(f => f.relname.match(/chunks\/js\/chunk-.+\.js$/)) assert.ok(jsChunkFiles.length > 0, 'at least one shared JS chunk was produced with a hashed name') + // Verify that global.data.js output reaches template vars + const feedJsonPath = path.join(dest, 'feeds/feed.json') + try { + const feedContent = await readFile(feedJsonPath, 'utf8') + const feedData = JSON.parse(feedContent) + assert.strictEqual( + feedData._globalDataSentinel, + 'data-from-global-dot-data', + 'feeds template received globalDataSentinel from global.data.js via vars' + ) + } catch (err) { + const error = err instanceof Error ? err : new Error('Unknown error', { cause: err }) + assert.fail('Failed to verify global.data.js output in template vars: ' + error.message) + } + // Special test for global.data.js blogPostsHtml const indexPath = path.join(dest, 'index.html') try { diff --git a/test-cases/general-features/src/feeds.template.js b/test-cases/general-features/src/feeds.template.js index 5cb350b..6cf6154 100644 --- a/test-cases/general-features/src/feeds.template.js +++ b/test-cases/general-features/src/feeds.template.js @@ -12,7 +12,8 @@ import jsonfeedToAtom from 'jsonfeed-to-atom' * authorUrl: string, * authorImgUrl: string, * publishDate: string, - * siteDescription: string + * siteDescription: string, + * globalDataSentinel: string, * }>} */ export default async function * feedsTemplate ({ @@ -23,6 +24,7 @@ export default async function * feedsTemplate ({ authorUrl, authorImgUrl, siteDescription, + globalDataSentinel, }, pages, }) { @@ -39,6 +41,7 @@ export default async function * feedsTemplate ({ home_page_url: homePageUrl, feed_url: `${homePageUrl}/feed.json`, description: siteDescription, + _globalDataSentinel: globalDataSentinel, author: { name: authorName, url: authorUrl, diff --git a/test-cases/general-features/src/global.data.js b/test-cases/general-features/src/global.data.js index 0a38db4..db26d76 100644 --- a/test-cases/general-features/src/global.data.js +++ b/test-cases/general-features/src/global.data.js @@ -5,7 +5,7 @@ import { html } from 'htm/preact' import { render } from 'preact-render-to-string' -/** @type {AsyncGlobalDataFunction<{ blogPostsHtml: string }>} */ +/** @type {AsyncGlobalDataFunction<{ blogPostsHtml: string, globalDataSentinel: string }>} */ export default async function ({ pages }) { const blogPosts = pages .filter(page => page.vars?.layout === 'blog' && page.vars?.publishDate) @@ -36,5 +36,5 @@ export default async function ({ pages }) { `) - return { blogPostsHtml } + return { blogPostsHtml, globalDataSentinel: 'data-from-global-dot-data' } }