Skip to content

Commit 0a6c6eb

Browse files
authored
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)
1 parent 513e28a commit 0a6c6eb

File tree

5 files changed

+47
-98
lines changed

5 files changed

+47
-98
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
it(`generates content for html field correctly`, () => {
2+
cy.request("/html-queried-like-feed-plugin.json").should(response => {
3+
expect(response.body.data.mdx.html).to.include(
4+
`<p>Just to test html field used usually for rss feed generation`
5+
)
6+
})
7+
})

e2e-tests/mdx/gatsby-node.js

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const fs = require(`fs-extra`)
2+
const path = require(`path`)
3+
4+
exports.onPostBuild = async ({ graphql }) => {
5+
const results = await graphql(`
6+
{
7+
mdx(slug: { eq: "html" }) {
8+
html
9+
}
10+
}
11+
`)
12+
13+
await fs.outputJSON(
14+
path.join(__dirname, `public`, `html-queried-like-feed-plugin.json`),
15+
results,
16+
{ spaces: 2 }
17+
)
18+
}

e2e-tests/mdx/package.json

+7-6
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@
66
"@mdx-js/mdx": "^1.6.6",
77
"@mdx-js/react": "^1.6.6",
88
"cypress": "^3.1.0",
9-
"gatsby": "^2.0.118",
10-
"gatsby-plugin-mdx": "^1.2.19",
11-
"gatsby-source-filesystem": "^2.3.14",
12-
"react": "^16.9.0",
13-
"react-dom": "^16.9.0",
9+
"fs-extra": "^8.1.0",
10+
"gatsby": "^3.0.0",
11+
"gatsby-plugin-mdx": "^2.0.0",
12+
"gatsby-source-filesystem": "^3.0.0",
13+
"react": "^17.0.0",
14+
"react-dom": "^17.0.0",
1415
"theme-ui": "^0.3.1"
1516
},
1617
"keywords": [
@@ -34,4 +35,4 @@
3435
"prettier": "2.0.4",
3536
"start-server-and-test": "^1.7.1"
3637
}
37-
}
38+
}

e2e-tests/mdx/src/pages/html.mdx

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { Message } from "theme-ui"
2+
3+
Just to test html field used usually for rss feed generation. Please don't edit.
4+
5+
<Example />
6+
7+
<Message data-testid="external">Just testing</Message>

packages/gatsby-plugin-mdx/utils/render-html.js

+8-92
Original file line numberDiff line numberDiff line change
@@ -22,110 +22,23 @@ queue.on(`active`, () => {
2222
)
2323
})
2424

25-
const findAsset = function (src, compilation, webpackStatsJson) {
26-
if (!src) {
27-
const chunkNames = Object.keys(webpackStatsJson.assetsByChunkName)
28-
29-
src = chunkNames[0]
30-
}
31-
32-
const asset = compilation.assets[src]
33-
34-
if (asset) {
35-
return asset
36-
}
37-
38-
let chunkValue = webpackStatsJson.assetsByChunkName[src]
39-
40-
if (!chunkValue) {
41-
return null
42-
}
43-
// Webpack outputs an array for each chunk when using sourcemaps
44-
if (chunkValue instanceof Array) {
45-
// Is the main bundle always the first element?
46-
chunkValue = chunkValue.find(function (filename) {
47-
return /\.js$/.test(filename)
48-
})
49-
}
50-
return compilation.assets[chunkValue]
51-
}
52-
53-
let renderMdxBody = undefined
54-
class MdxHtmlBuilderWebpackPlugin {
55-
apply(compiler) {
56-
const self = this
57-
const afterEmit = (compilation, callback) => {
58-
// var options = compiler.options;
59-
/* var stats = compilation.getStats().toJson({
60-
* hash: true,
61-
* publicPath: true,
62-
* assets: true,
63-
* chunks: false,
64-
* modules: false,
65-
* source: false,
66-
* errorDetails: false,
67-
* timings: false
68-
* }); */
69-
// console.log(Object.keys(compilation.assets));
70-
const webpackStats = compilation.getStats()
71-
const webpackStatsJson = webpackStats.toJson()
72-
73-
try {
74-
const asset = findAsset(self.entry, compilation, webpackStatsJson)
75-
76-
if (asset == null) {
77-
throw new Error(`Source file not found: "` + self.entry + `"`)
78-
}
79-
80-
const source = asset.source()
81-
let render = evaluate(
82-
source,
83-
/* filename: */ self.entry,
84-
/* scope: */ self.globals,
85-
/* includeGlobals: */ true
86-
)
87-
88-
if (render.hasOwnProperty(`default`)) {
89-
render = render[`default`]
90-
}
91-
92-
if (typeof render !== `function`) {
93-
throw new Error(
94-
`Export from '${self.entry}' must be a function that returns a htmlString value.`
95-
)
96-
}
97-
// use function here
98-
renderMdxBody = render
99-
callback()
100-
} catch (err) {
101-
compilation.errors.push(err.stack)
102-
callback()
103-
}
104-
}
105-
if (compiler.hooks) {
106-
const plugin = { name: `MdxHtmlBuilderWebpackPlugin` }
107-
108-
compiler.hooks.afterEmit.tapAsync(plugin, afterEmit)
109-
} else {
110-
compiler.plugin(`after-emit`, afterEmit)
111-
}
112-
}
113-
}
114-
11525
exports.mdxHTMLLoader = ({ cache, reporter, store }) =>
11626
new DataLoader(
11727
async keys => {
11828
const webpackConfig = cloneDeep(store.getState().webpack)
29+
const outputPath = path.join(cache.directory, `webpack`)
11930
// something sets externals, which will cause React to be undefined
12031
webpackConfig.externals = undefined
12132
webpackConfig.entry = require.resolve(`./wrap-root-render-html-entry.js`)
12233
webpackConfig.output = {
12334
filename: `output.js`,
124-
path: path.join(cache.directory, `webpack`),
35+
path: outputPath,
12536
libraryTarget: `commonjs`,
12637
}
12738
webpackConfig.plugins = webpackConfig.plugins || []
128-
webpackConfig.plugins.push(new MdxHtmlBuilderWebpackPlugin())
39+
webpackConfig.externalsPresets = {
40+
node: true,
41+
}
12942
const compiler = webpack(webpackConfig)
13043

13144
return queue.add(
@@ -151,6 +64,9 @@ exports.mdxHTMLLoader = ({ cache, reporter, store }) =>
15164
reporter.warn(`gatsby-plugin-mdx\n` + info.warnings)
15265
}
15366

67+
const renderMdxBody = require(path.join(outputPath, `output.js`))
68+
.default
69+
15470
resolve(
15571
keys.map(({ body }) =>
15672
renderMdxBody

0 commit comments

Comments
 (0)