Elimination has to run before other plugins (#12949)
This commit is contained in:
parent
18dc1f66c6
commit
7edc815a38
2 changed files with 120 additions and 69 deletions
|
@ -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
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;` +
|
||||
|
|
Loading…
Reference in a new issue