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

Add gSP and gSSP checks for both server and client layers in the SWC transform #43391

Merged
merged 5 commits into from Nov 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 10 additions & 3 deletions packages/next-swc/crates/core/src/react_server_components.rs
Expand Up @@ -58,7 +58,7 @@ impl<C: Comments> VisitMut for ReactServerComponents<C> {

if self.is_server {
if !is_client_entry {
self.assert_server_graph(&imports);
self.assert_server_graph(&imports, module);
} else {
self.to_module_ref(module);
return;
Expand Down Expand Up @@ -246,7 +246,7 @@ impl<C: Comments> ReactServerComponents<C> {
);
}

fn assert_server_graph(&self, imports: &Vec<ModuleImports>) {
fn assert_server_graph(&self, imports: &Vec<ModuleImports>, module: &Module) {
for import in imports {
let source = import.source.0.clone();
if self.invalid_server_imports.contains(&source) {
Expand Down Expand Up @@ -288,6 +288,8 @@ impl<C: Comments> ReactServerComponents<C> {
}
}
}

self.assert_invalid_api(module);
}

fn assert_client_graph(&self, imports: &Vec<ModuleImports>, module: &Module) {
Expand All @@ -305,10 +307,15 @@ impl<C: Comments> ReactServerComponents<C> {
}
}

self.assert_invalid_api(module);
}

fn assert_invalid_api(&self, module: &Module) {
// Assert `getServerSideProps` and `getStaticProps` exports.
let is_layout_or_page = Regex::new(r"/(page|layout)\.(ts|js)x?$")
.unwrap()
.is_match(&self.filepath);

if is_layout_or_page {
let mut span = DUMMY_SP;
let mut has_get_server_side_props = false;
Expand Down Expand Up @@ -389,7 +396,7 @@ impl<C: Comments> ReactServerComponents<C> {
.struct_span_err(
span,
format!(
"`{}` is not allowed in Client Components.",
"NEXT_RSC_ERR_INVALID_API: {}",
if has_get_server_side_props {
"getServerSideProps"
} else {
Expand Down
2 changes: 1 addition & 1 deletion packages/next-swc/crates/core/tests/errors.rs
Expand Up @@ -82,7 +82,7 @@ fn react_server_components_server_graph_errors(input: PathBuf) {
syntax(),
&|tr| {
server_components(
FileName::Real(PathBuf::from("/some-project/src/some-file.js")),
FileName::Real(PathBuf::from("/some-project/src/layout.js")),
next_swc::react_server_components::Config::WithOptions(
next_swc::react_server_components::Options { is_server: true },
),
Expand Down
@@ -1,5 +1,5 @@

x `getServerSideProps` is not allowed in Client Components.
x NEXT_RSC_ERR_INVALID_API: getServerSideProps
,-[input.js:1:1]
1 | export function getServerSideProps (){
: ^^^^^^^^^^^^^^^^^^
Expand Down
@@ -1,5 +1,5 @@

x `getStaticProps` is not allowed in Client Components.
x NEXT_RSC_ERR_INVALID_API: getStaticProps
,-[input.js:1:1]
1 | export function getStaticProps (){
: ^^^^^^^^^^^^^^
Expand Down
@@ -0,0 +1,6 @@
export function getServerSideProps (){
}

export default function () {
return null;
}
@@ -0,0 +1,4 @@
export function getServerSideProps() {}
export default function() {
return null;
}
@@ -0,0 +1,6 @@

x NEXT_RSC_ERR_INVALID_API: getServerSideProps
,-[input.js:1:1]
1 | export function getServerSideProps (){
: ^^^^^^^^^^^^^^^^^^
`----
@@ -0,0 +1,6 @@
export function getStaticProps (){
}

export default function () {
return null;
}
@@ -0,0 +1,4 @@
export function getStaticProps() {}
export default function() {
return null;
}
@@ -0,0 +1,6 @@

x NEXT_RSC_ERR_INVALID_API: getStaticProps
,-[input.js:1:1]
1 | export function getStaticProps (){
: ^^^^^^^^^^^^^^
`----
Expand Up @@ -16,6 +16,7 @@ function formatRSCErrorMessage(message: string): null | [string, string] {
const NEXT_RSC_ERR_CLIENT_DIRECTIVE = /.+NEXT_RSC_ERR_CLIENT_DIRECTIVE\n/s
const NEXT_RSC_ERR_CLIENT_DIRECTIVE_PAREN =
/.+NEXT_RSC_ERR_CLIENT_DIRECTIVE_PAREN\n/s
const NEXT_RSC_ERR_INVALID_API = /.+NEXT_RSC_ERR_INVALID_API: (.*?)\n/s

if (NEXT_RSC_ERR_REACT_API.test(message)) {
formattedMessage = message.replace(
Expand Down Expand Up @@ -62,6 +63,12 @@ function formatRSCErrorMessage(message: string): null | [string, string] {
`\n\n"use client" must be a directive, and placed before other expressions. Remove the parentheses and move it to the top of the file to resolve this issue.\n\n`
)
formattedVerboseMessage = '\n\nImport path:\n'
} else if (NEXT_RSC_ERR_INVALID_API.test(message)) {
formattedMessage = message.replace(
NEXT_RSC_ERR_INVALID_API,
`\n\n"$1" is not supported in app/. Read more: https://beta.nextjs.org/docs/data-fetching/fundamentals\n\n`
)
formattedVerboseMessage = '\n\nFile path:\n'
}

return [formattedMessage, formattedVerboseMessage]
Expand Down
14 changes: 0 additions & 14 deletions packages/next/server/app-render.tsx
Expand Up @@ -1127,20 +1127,6 @@ export async function renderToHTMLOrFlight(
}
}

// TODO-APP: move these errors to the loader instead?
// we will also need a migration doc here to link to
if (typeof layoutOrPageMod?.getServerSideProps === 'function') {
throw new Error(
`getServerSideProps is not supported in app/, detected in ${segment}`
)
}

if (typeof layoutOrPageMod?.getStaticProps === 'function') {
throw new Error(
`getStaticProps is not supported in app/, detected in ${segment}`
)
}

/**
* The React Component to render.
*/
Expand Down
4 changes: 2 additions & 2 deletions test/e2e/app-dir/rsc-errors.test.ts
Expand Up @@ -52,7 +52,7 @@ describe('app dir - rsc errors', () => {

expect(res.status).toBe(500)
expect(await res.text()).toContain(
'`getServerSideProps` is not allowed in Client Components'
'"getServerSideProps\\" is not supported in app/'
)
})

Expand All @@ -79,7 +79,7 @@ describe('app dir - rsc errors', () => {

expect(res.status).toBe(500)
expect(await res.text()).toContain(
'`getStaticProps` is not allowed in Client Components'
'"getStaticProps\\" is not supported in app/'
)
})

Expand Down