Skip to content

Commit

Permalink
next-swc: Emit errors and add tests to next-ssg (#32254)
Browse files Browse the repository at this point in the history
## Bug

- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Errors have helpful link attached, see `contributing.md`

## Feature

- [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR.
- [ ] Related issues linked using `fixes #number`
- [ ] Integration tests added
- [ ] Documentation added
- [ ] Telemetry added. In case of a feature if it's used or not.
- [ ] Errors have helpful link attached, see `contributing.md`

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
  • Loading branch information
hanneslund committed Dec 16, 2021
1 parent f221f88 commit b0bd0ee
Show file tree
Hide file tree
Showing 14 changed files with 110 additions and 28 deletions.
94 changes: 66 additions & 28 deletions packages/next-swc/crates/core/src/next_ssg.rs
@@ -1,3 +1,4 @@
use easy_error::{bail, Error};
use fxhash::FxHashSet;
use std::mem::take;
use swc_common::pass::{Repeat, Repeated};
Expand All @@ -6,7 +7,7 @@ use swc_ecmascript::ast::*;
use swc_ecmascript::utils::ident::IdentLike;
use swc_ecmascript::visit::FoldWith;
use swc_ecmascript::{
utils::Id,
utils::{Id, HANDLER},
visit::{noop_fold_type, Fold},
};

Expand Down Expand Up @@ -43,7 +44,7 @@ struct State {
}

impl State {
fn is_data_identifier(&mut self, i: &Ident) -> bool {
fn is_data_identifier(&mut self, i: &Ident) -> Result<bool, Error> {
let ssg_exports = &[
"getStaticProps",
"getStaticPaths",
Expand All @@ -53,27 +54,39 @@ impl State {
if ssg_exports.contains(&&*i.sym) {
if &*i.sym == "getServerSideProps" {
if self.is_prerenderer {
panic!(
"You can not use getStaticProps or getStaticPaths with \
getServerSideProps. To use SSG, please remove getServerSideProps"
)
HANDLER.with(|handler| {
handler
.struct_span_err(
i.span,
"You can not use getStaticProps or getStaticPaths with \
getServerSideProps. To use SSG, please remove getServerSideProps",
)
.emit()
});
bail!("both ssg and ssr functions present");
}

self.is_server_props = true;
} else {
if self.is_server_props {
panic!(
"You can not use getStaticProps or getStaticPaths with \
getServerSideProps. To use SSG, please remove getServerSideProps"
)
HANDLER.with(|handler| {
handler
.struct_span_err(
i.span,
"You can not use getStaticProps or getStaticPaths with \
getServerSideProps. To use SSG, please remove getServerSideProps",
)
.emit()
});
bail!("both ssg and ssr functions present");
}

self.is_prerenderer = true;
}

true
Ok(true)
} else {
false
Ok(false)
}
}
}
Expand Down Expand Up @@ -135,7 +148,11 @@ impl Fold for Analyzer<'_> {

self.state.cur_declaring.insert(f.ident.to_id());

self.in_data_fn |= self.state.is_data_identifier(&f.ident);
if let Ok(is_data_identifier) = self.state.is_data_identifier(&f.ident) {
self.in_data_fn |= is_data_identifier;
} else {
return f;
}
tracing::trace!(
"ssg: Handling `{}{:?}`; in_data_fn = {:?}",
f.ident.sym,
Expand Down Expand Up @@ -194,8 +211,13 @@ impl Fold for Analyzer<'_> {
ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(e)) => match &e.decl {
Decl::Fn(f) => {
// Drop getStaticProps.
if self.state.is_data_identifier(&f.ident) {
return ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }));
if let Ok(is_data_identifier) = self.state.is_data_identifier(&f.ident)
{
if is_data_identifier {
return ModuleItem::Stmt(Stmt::Empty(EmptyStmt { span: DUMMY_SP }));
}
} else {
return s;
}
}

Expand Down Expand Up @@ -239,8 +261,12 @@ impl Fold for Analyzer<'_> {

match &v.name {
Pat::Ident(name) => {
if self.state.is_data_identifier(&name.id) {
self.in_data_fn = true;
if let Ok(is_data_identifier) = self.state.is_data_identifier(&name.id) {
if is_data_identifier {
self.in_data_fn = true;
}
} else {
return v;
}
}
_ => {}
Expand Down Expand Up @@ -472,23 +498,35 @@ impl Fold for NextSsg {
| ExportSpecifier::Named(ExportNamedSpecifier {
exported: Some(exported),
..
}) => !self.state.is_data_identifier(&exported),
ExportSpecifier::Named(s) => !self.state.is_data_identifier(&s.orig),
}) => self
.state
.is_data_identifier(&exported)
.map(|is_data_identifier| !is_data_identifier),
ExportSpecifier::Named(s) => self
.state
.is_data_identifier(&s.orig)
.map(|is_data_identifier| !is_data_identifier),
};

if !preserve {
tracing::trace!("Dropping a export specifier because it's a data identifier");
match preserve {
Ok(false) => {
tracing::trace!(
"Dropping a export specifier because it's a data identifier"
);

match s {
ExportSpecifier::Named(ExportNamedSpecifier { orig, .. }) => {
self.state.should_run_again = true;
self.state.refs_from_data_fn.insert(orig.to_id());
match s {
ExportSpecifier::Named(ExportNamedSpecifier { orig, .. }) => {
self.state.should_run_again = true;
self.state.refs_from_data_fn.insert(orig.to_id());
}
_ => {}
}
_ => {}

false
}
Ok(true) => true,
Err(_) => false,
}

preserve
});

n
Expand Down
7 changes: 7 additions & 0 deletions packages/next-swc/crates/core/tests/errors.rs
@@ -1,5 +1,6 @@
use next_swc::{
disallow_re_export_all_in_page::disallow_re_export_all_in_page, next_dynamic::next_dynamic,
next_ssg::next_ssg,
};
use std::path::PathBuf;
use swc_common::FileName;
Expand Down Expand Up @@ -42,3 +43,9 @@ fn next_dynamic_errors(input: PathBuf) {
&output,
);
}

#[fixture("tests/errors/next-ssg/**/input.js")]
fn next_ssg_errors(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");
test_fixture_allowing_error(syntax(), &|_tr| next_ssg(), &input, &output);
}
@@ -0,0 +1,2 @@
export async function getStaticPaths() {}
export const getServerSideProps = function getServerSideProps() {}
@@ -0,0 +1,3 @@
export var __N_SSG = true;
export const getServerSideProps = function getServerSideProps() {
}
@@ -0,0 +1,6 @@
error: You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps
--> input.js:2:14
|
2 | export const getServerSideProps = function getServerSideProps() {}
| ^^^^^^^^^^^^^^^^^^

@@ -0,0 +1,3 @@
const getStaticProps = async () => {}
export { a as getServerSideProps }

@@ -0,0 +1,6 @@
error: You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps
--> input.js:2:15
|
2 | export { a as getServerSideProps }
| ^^^^^^^^^^^^^^^^^^

@@ -0,0 +1,4 @@
export { a as getServerSideProps } from './input'
export { getStaticPaths } from 'a'


@@ -0,0 +1,6 @@
error: You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps
--> input.js:2:10
|
2 | export { getStaticPaths } from 'a'
| ^^^^^^^^^^^^^^

@@ -0,0 +1 @@
export { getStaticProps, getServerSideProps }
@@ -0,0 +1,6 @@
error: You can not use getStaticProps or getStaticPaths with getServerSideProps. To use SSG, please remove getServerSideProps
--> input.js:1:26
|
1 | export { getStaticProps, getServerSideProps }
| ^^^^^^^^^^^^^^^^^^

0 comments on commit b0bd0ee

Please sign in to comment.