Skip to content

Commit

Permalink
fix(gatsby-plugin-mdx): fix html field resolver to work with webpack@5 (
Browse files Browse the repository at this point in the history
#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)
  • Loading branch information
pieh committed Mar 10, 2021
1 parent 513e28a commit 0a6c6eb
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 98 deletions.
7 changes: 7 additions & 0 deletions 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(
`<p>Just to test html field used usually for rss feed generation`
)
})
})
18 changes: 18 additions & 0 deletions 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 }
)
}
13 changes: 7 additions & 6 deletions e2e-tests/mdx/package.json
Expand Up @@ -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": [
Expand All @@ -34,4 +35,4 @@
"prettier": "2.0.4",
"start-server-and-test": "^1.7.1"
}
}
}
7 changes: 7 additions & 0 deletions 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.

<Example />

<Message data-testid="external">Just testing</Message>
100 changes: 8 additions & 92 deletions packages/gatsby-plugin-mdx/utils/render-html.js
Expand Up @@ -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(
Expand All @@ -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
Expand Down

0 comments on commit 0a6c6eb

Please sign in to comment.