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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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`, () => {
)
})

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