Elimination has to run before other plugins (#12949)

This commit is contained in:
Joe Haddad 2020-05-15 16:51:29 -04:00 committed by GitHub
parent 18dc1f66c6
commit 7edc815a38
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 120 additions and 69 deletions

View file

@ -168,13 +168,85 @@ export default function nextTransformSsg({
return {
visitor: {
Program: {
enter(_, state) {
enter(path, state) {
state.refs = new Set<NodePath<BabelTypes.Identifier>>()
state.isPrerender = false
state.isServerProps = false
state.done = false
},
exit(path, state) {
path.traverse(
{
VariableDeclarator(path, state) {
if (path.node.id.type !== 'Identifier') {
return
}
const local = path.get('id') as NodePath<BabelTypes.Identifier>
if (isIdentifierReferenced(local)) {
state.refs.add(local)
}
},
FunctionDeclaration: markFunction,
FunctionExpression: markFunction,
ArrowFunctionExpression: markFunction,
ImportSpecifier: markImport,
ImportDefaultSpecifier: markImport,
ImportNamespaceSpecifier: markImport,
ExportNamedDeclaration(path, state) {
const specifiers = path.get('specifiers')
if (specifiers.length) {
specifiers.forEach(s => {
if (isDataIdentifier(s.node.exported.name, state)) {
s.remove()
}
})
if (path.node.specifiers.length < 1) {
path.remove()
}
return
}
const decl = path.get('declaration') as NodePath<
| BabelTypes.FunctionDeclaration
| BabelTypes.VariableDeclaration
>
if (decl == null || decl.node == null) {
return
}
switch (decl.node.type) {
case 'FunctionDeclaration': {
const name = decl.node.id!.name
if (isDataIdentifier(name, state)) {
path.remove()
}
break
}
case 'VariableDeclaration': {
const inner = decl.get('declarations') as NodePath<
BabelTypes.VariableDeclarator
>[]
inner.forEach(d => {
if (d.node.id.type !== 'Identifier') {
return
}
const name = d.node.id.name
if (isDataIdentifier(name, state)) {
d.remove()
}
})
break
}
default: {
break
}
}
},
},
state
)
if (!state.isPrerender && !state.isServerProps) {
return
}
@ -257,72 +329,6 @@ export default function nextTransformSsg({
decorateSsgExport(t, path, state)
},
},
VariableDeclarator(path, state) {
if (path.node.id.type !== 'Identifier') {
return
}
const local = path.get('id') as NodePath<BabelTypes.Identifier>
if (isIdentifierReferenced(local)) {
state.refs.add(local)
}
},
FunctionDeclaration: markFunction,
FunctionExpression: markFunction,
ArrowFunctionExpression: markFunction,
ImportSpecifier: markImport,
ImportDefaultSpecifier: markImport,
ImportNamespaceSpecifier: markImport,
ExportNamedDeclaration(path, state) {
const specifiers = path.get('specifiers')
if (specifiers.length) {
specifiers.forEach(s => {
if (isDataIdentifier(s.node.exported.name, state)) {
s.remove()
}
})
if (path.node.specifiers.length < 1) {
path.remove()
}
return
}
const decl = path.get('declaration') as NodePath<
BabelTypes.FunctionDeclaration | BabelTypes.VariableDeclaration
>
if (decl == null || decl.node == null) {
return
}
switch (decl.node.type) {
case 'FunctionDeclaration': {
const name = decl.node.id!.name
if (isDataIdentifier(name, state)) {
path.remove()
}
break
}
case 'VariableDeclaration': {
const inner = decl.get('declarations') as NodePath<
BabelTypes.VariableDeclarator
>[]
inner.forEach(d => {
if (d.node.id.type !== 'Identifier') {
return
}
const name = d.node.id.name
if (isDataIdentifier(name, state)) {
d.remove()
}
})
break
}
default: {
break
}
}
},
},
}
}

View file

@ -57,6 +57,7 @@ const babel = async (
babelPresetPlugins: [],
hasModern,
development,
hasReactRefresh: Boolean(!isServer && development),
},
})(code, null)
@ -329,6 +330,50 @@ describe('next-babel-loader', () => {
)
})
it('should support 9.4 regression', async () => {
const output = await babel(
`
import React from "react";
import queryGraphql from "../graphql/schema";
const gql = String.raw;
export default function Home({ greeting }) {
return <h1>{greeting}</h1>;
}
export async function getStaticProps() {
const greeting = await getGreeting();
return {
props: {
greeting,
},
};
}
async function getGreeting() {
const result = await queryGraphql(
gql\`
{
query {
greeting
}
}
\`
);
return result.data.greeting;
}
`,
{ resourcePath: pageFile, isServer: false, development: true }
)
expect(output).toMatchInlineSnapshot(
`"var __jsx=React.createElement;import React from\\"react\\";export var __N_SSG=true;export default function Home(_ref){var greeting=_ref.greeting;return __jsx(\\"h1\\",null,greeting);}_c=Home;var _c;$RefreshReg$(_c,\\"Home\\");"`
)
})
it('should support optional chaining for JS file', async () => {
const code = await babel(
`let hello;` +