Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(gatsby-plugin-mdx): fix html field resolver to work with webpack@5 (#30158) #30172

Merged
merged 1 commit into from
Mar 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions e2e-tests/mdx/cypress/integration/html-field.js
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -22,110 +22,23 @@ queue.on(`active`, () => {
)
})

var findAsset = function (src, compilation, webpackStatsJson) {
if (!src) {
var chunkNames = Object.keys(webpackStatsJson.assetsByChunkName)

src = chunkNames[0]
}

var asset = compilation.assets[src]

if (asset) {
return asset
}

var 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
var 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));
var webpackStats = compilation.getStats()
var webpackStatsJson = webpackStats.toJson()

try {
var asset = findAsset(self.entry, compilation, webpackStatsJson)

if (asset == null) {
throw new Error(`Source file not found: "` + self.entry + `"`)
}

var source = asset.source()
var 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) {
var 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