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

Merged
merged 2 commits into from
Mar 10, 2021
Merged
Changes from 1 commit
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
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`, () => {
)
})

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