From 0a6c6eb40409ac92d30917e00f26a0bc4c9ca9e5 Mon Sep 17 00:00:00 2001 From: Michal Piechowiak Date: Wed, 10 Mar 2021 16:10:43 +0100 Subject: [PATCH] fix(gatsby-plugin-mdx): fix html field resolver to work with webpack@5 (#30158) * fix(gatsby-plugin-mdx): fix html field resolver to work with webpack@5 * test(e2e-mdx): add setup for checking html field (like with gatsby-plugin-feed) --- .../mdx/cypress/integration/html-field.js | 7 ++ e2e-tests/mdx/gatsby-node.js | 18 ++++ e2e-tests/mdx/package.json | 13 +-- e2e-tests/mdx/src/pages/html.mdx | 7 ++ .../gatsby-plugin-mdx/utils/render-html.js | 100 ++---------------- 5 files changed, 47 insertions(+), 98 deletions(-) create mode 100644 e2e-tests/mdx/cypress/integration/html-field.js create mode 100644 e2e-tests/mdx/gatsby-node.js create mode 100644 e2e-tests/mdx/src/pages/html.mdx diff --git a/e2e-tests/mdx/cypress/integration/html-field.js b/e2e-tests/mdx/cypress/integration/html-field.js new file mode 100644 index 0000000000000..c39a83d4791e9 --- /dev/null +++ b/e2e-tests/mdx/cypress/integration/html-field.js @@ -0,0 +1,7 @@ +it(`generates content for html field correctly`, () => { + cy.request("/html-queried-like-feed-plugin.json").should(response => { + expect(response.body.data.mdx.html).to.include( + `

Just to test html field used usually for rss feed generation` + ) + }) +}) diff --git a/e2e-tests/mdx/gatsby-node.js b/e2e-tests/mdx/gatsby-node.js new file mode 100644 index 0000000000000..eceaaff1a0d20 --- /dev/null +++ b/e2e-tests/mdx/gatsby-node.js @@ -0,0 +1,18 @@ +const fs = require(`fs-extra`) +const path = require(`path`) + +exports.onPostBuild = async ({ graphql }) => { + const results = await graphql(` + { + mdx(slug: { eq: "html" }) { + html + } + } + `) + + await fs.outputJSON( + path.join(__dirname, `public`, `html-queried-like-feed-plugin.json`), + results, + { spaces: 2 } + ) +} diff --git a/e2e-tests/mdx/package.json b/e2e-tests/mdx/package.json index 7df2170e3f8fe..fde0c84ad8827 100644 --- a/e2e-tests/mdx/package.json +++ b/e2e-tests/mdx/package.json @@ -6,11 +6,12 @@ "@mdx-js/mdx": "^1.6.6", "@mdx-js/react": "^1.6.6", "cypress": "^3.1.0", - "gatsby": "^2.0.118", - "gatsby-plugin-mdx": "^1.2.19", - "gatsby-source-filesystem": "^2.3.14", - "react": "^16.9.0", - "react-dom": "^16.9.0", + "fs-extra": "^8.1.0", + "gatsby": "^3.0.0", + "gatsby-plugin-mdx": "^2.0.0", + "gatsby-source-filesystem": "^3.0.0", + "react": "^17.0.0", + "react-dom": "^17.0.0", "theme-ui": "^0.3.1" }, "keywords": [ @@ -34,4 +35,4 @@ "prettier": "2.0.4", "start-server-and-test": "^1.7.1" } -} \ No newline at end of file +} diff --git a/e2e-tests/mdx/src/pages/html.mdx b/e2e-tests/mdx/src/pages/html.mdx new file mode 100644 index 0000000000000..765e9e852de81 --- /dev/null +++ b/e2e-tests/mdx/src/pages/html.mdx @@ -0,0 +1,7 @@ +import { Message } from "theme-ui" + +Just to test html field used usually for rss feed generation. Please don't edit. + + + +Just testing diff --git a/packages/gatsby-plugin-mdx/utils/render-html.js b/packages/gatsby-plugin-mdx/utils/render-html.js index c52e616930b74..7c51f7b144369 100644 --- a/packages/gatsby-plugin-mdx/utils/render-html.js +++ b/packages/gatsby-plugin-mdx/utils/render-html.js @@ -22,110 +22,23 @@ queue.on(`active`, () => { ) }) -const findAsset = function (src, compilation, webpackStatsJson) { - if (!src) { - const chunkNames = Object.keys(webpackStatsJson.assetsByChunkName) - - src = chunkNames[0] - } - - const asset = compilation.assets[src] - - if (asset) { - return asset - } - - let chunkValue = webpackStatsJson.assetsByChunkName[src] - - if (!chunkValue) { - return null - } - // Webpack outputs an array for each chunk when using sourcemaps - if (chunkValue instanceof Array) { - // Is the main bundle always the first element? - chunkValue = chunkValue.find(function (filename) { - return /\.js$/.test(filename) - }) - } - return compilation.assets[chunkValue] -} - -let renderMdxBody = undefined -class MdxHtmlBuilderWebpackPlugin { - apply(compiler) { - const self = this - const afterEmit = (compilation, callback) => { - // var options = compiler.options; - /* var stats = compilation.getStats().toJson({ - * hash: true, - * publicPath: true, - * assets: true, - * chunks: false, - * modules: false, - * source: false, - * errorDetails: false, - * timings: false - * }); */ - // console.log(Object.keys(compilation.assets)); - const webpackStats = compilation.getStats() - const webpackStatsJson = webpackStats.toJson() - - try { - const asset = findAsset(self.entry, compilation, webpackStatsJson) - - if (asset == null) { - throw new Error(`Source file not found: "` + self.entry + `"`) - } - - const source = asset.source() - let render = evaluate( - source, - /* filename: */ self.entry, - /* scope: */ self.globals, - /* includeGlobals: */ true - ) - - if (render.hasOwnProperty(`default`)) { - render = render[`default`] - } - - if (typeof render !== `function`) { - throw new Error( - `Export from '${self.entry}' must be a function that returns a htmlString value.` - ) - } - // use function here - renderMdxBody = render - callback() - } catch (err) { - compilation.errors.push(err.stack) - callback() - } - } - if (compiler.hooks) { - const plugin = { name: `MdxHtmlBuilderWebpackPlugin` } - - compiler.hooks.afterEmit.tapAsync(plugin, afterEmit) - } else { - compiler.plugin(`after-emit`, afterEmit) - } - } -} - exports.mdxHTMLLoader = ({ cache, reporter, store }) => new DataLoader( async keys => { const webpackConfig = cloneDeep(store.getState().webpack) + const outputPath = path.join(cache.directory, `webpack`) // something sets externals, which will cause React to be undefined webpackConfig.externals = undefined webpackConfig.entry = require.resolve(`./wrap-root-render-html-entry.js`) webpackConfig.output = { filename: `output.js`, - path: path.join(cache.directory, `webpack`), + path: outputPath, libraryTarget: `commonjs`, } webpackConfig.plugins = webpackConfig.plugins || [] - webpackConfig.plugins.push(new MdxHtmlBuilderWebpackPlugin()) + webpackConfig.externalsPresets = { + node: true, + } const compiler = webpack(webpackConfig) return queue.add( @@ -151,6 +64,9 @@ exports.mdxHTMLLoader = ({ cache, reporter, store }) => reporter.warn(`gatsby-plugin-mdx\n` + info.warnings) } + const renderMdxBody = require(path.join(outputPath, `output.js`)) + .default + resolve( keys.map(({ body }) => renderMdxBody