Fix edge case where file had module.export in the content (#5823)

We ran into this eg on hyper-site, which has `module.exports` in the content.
This commit is contained in:
Tim Neutkens 2018-12-05 14:37:26 +01:00 committed by GitHub
parent e463c2a1bb
commit 6542750e12
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 2 deletions

View file

@ -0,0 +1,34 @@
import {PluginObj} from '@babel/core'
import {NodePath} from '@babel/traverse'
import {Program} from '@babel/types'
import commonjsPlugin from '@babel/plugin-transform-modules-commonjs'
// Rewrite imports using next/<something> to next-server/<something>
export default function NextToNextServer (...args: any): PluginObj {
const commonjs = commonjsPlugin(...args)
return {
visitor: {
Program: {
exit (path: NodePath<Program>, state) {
let foundModuleExports = false
path.traverse({
MemberExpression (
path: any
) {
if (path.node.object.name !== 'module') return
if (path.node.property.name !== 'exports') return
foundModuleExports = true
console.log('FOUND', state.file.opts.filename)
}
})
if (!foundModuleExports) {
console.log('NOT FOUND', state.file.opts.filename)
return
}
commonjs.visitor.Program.exit.call(this, path, state)
}
}
}
}
}

View file

@ -2,6 +2,7 @@ import babelLoader from 'babel-loader'
module.exports = babelLoader.custom(babel => {
const presetItem = babel.createConfigItem(require('../../babel/preset'), {type: 'preset'})
const applyCommonJs = babel.createConfigItem(require('../../babel/plugins/commonjs'), {type: 'plugin'})
const commonJsItem = babel.createConfigItem(require('@babel/plugin-transform-modules-commonjs'), {type: 'plugin'})
const configs = new Set()
@ -37,11 +38,14 @@ module.exports = babelLoader.custom(babel => {
options.presets = [...options.presets, presetItem]
}
if (source.match(/module\.exports/)) {
// If the file has `module.exports` we have to transpile commonjs because Babel adds `import` statements
// That break webpack, since webpack doesn't support combining commonjs and esmodules
if (source.indexOf('module.exports') !== -1) {
options.plugins = options.plugins || []
options.plugins.push(commonJsItem)
options.plugins.push(applyCommonJs)
}
// As next-server/lib has stateful modules we have to transpile commonjs
options.overrides = [
...(options.overrides || []),
{

View file

@ -0,0 +1,3 @@
export default () => {
return <div>module.exports</div>
}

View file

@ -131,6 +131,11 @@ export default function ({ app }, suiteName, render, fetch) {
expect(res.status).toBe(404)
})
test('should render page that has module.exports anywhere', async () => {
const res = await fetch('/exports')
expect(res.status).toBe(200)
})
test('should expose the compiled page file in development', async () => {
await fetch('/stateless') // make sure the stateless page is built
const clientSideJsRes = await fetch('/_next/development/static/development/pages/stateless.js')