Skip to content

Commit

Permalink
Add error checks and tests to next-dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
Hannes Lund committed Nov 22, 2021
1 parent c2e73ea commit 63bd6a5
Show file tree
Hide file tree
Showing 16 changed files with 152 additions and 1 deletion.
35 changes: 35 additions & 0 deletions errors/invalid-dynamic-arguments.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Invalid argument in `next/dynamic` call

#### Why This Error Occurred

You have passed an invalid argument to a `next/dynamic` call.

- The `import()` call must be inside the `dynamic()` call.
- The options object literal must be created inside the `dynamic()` call.

#### Possible Ways to Fix It

**Before**

```jsx
import dynamic from 'next/dynamic'

const module = () => import('../components/hello')
const options = { loading: () => <p>...</p>, ssr: false }
const DynamicComponent = dynamic(module, options)
```

**After**

```jsx
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic(() => import('../components/hello'), {
loading: () => <p>...</p>,
ssr: false,
})
```

### Useful Links

- [Dynamic Import](https://nextjs.org/docs/advanced-features/dynamic-import)
4 changes: 4 additions & 0 deletions errors/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,10 @@
{
"title": "experimental-jest-transformer",
"path": "/errors/experimental-jest-transformer.md"
},
{
"title": "invalid-dynamic-arguments",
"path": "/errors/invalid-dynamic-arguments.md"
}
]
}
Expand Down
25 changes: 25 additions & 0 deletions packages/next-swc/crates/core/src/next_dynamic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,37 @@ impl Fold for NextDynamicPatcher {
});
return expr;
}
if expr.args.len() == 2 {
match &*expr.args[1].expr {
Expr::Object(_) => {},
_ => {
HANDLER.with(|handler| {
handler
.struct_span_err(
identifier.span,
"Second argument must be an object literal.\nRead more: https://nextjs.org/docs/messages/invalid-dynamic-arguments",
)
.emit();
});
return expr;
}
}
}

self.is_next_dynamic_first_arg = true;
expr.args[0].expr = expr.args[0].expr.clone().fold_with(self);
self.is_next_dynamic_first_arg = false;


if let None = self.dynamically_imported_specifier {
HANDLER.with(|handler| {
handler
.struct_span_err(
identifier.span,
"import() has to be inside the dynamic() call.\nRead more: https://nextjs.org/docs/messages/invalid-dynamic-arguments",
)
.emit();
});
return expr;
}

Expand Down
21 changes: 20 additions & 1 deletion packages/next-swc/crates/core/tests/errors.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use next_swc::disallow_re_export_all_in_page::disallow_re_export_all_in_page;
use next_swc::{
disallow_re_export_all_in_page::disallow_re_export_all_in_page, next_dynamic::next_dynamic,
};
use std::path::PathBuf;
use swc_common::FileName;
use swc_ecma_transforms_testing::test_fixture_allowing_error;
use swc_ecmascript::parser::{EsConfig, Syntax};
use testing::fixture;
Expand All @@ -22,3 +25,19 @@ fn re_export_all_in_page(input: PathBuf) {
&output,
);
}

#[fixture("tests/errors/next-dynamic/**/input.js")]
fn next_dynamic_errors(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");
test_fixture_allowing_error(
syntax(),
&|_tr| {
next_dynamic(
FileName::Real(PathBuf::from("/some-project/src/some-file.js")),
Some("/some-project/src".into()),
)
},
&input,
&output,
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dynamic from 'next/dynamic'

const module = () => import('../components/hello')
const DynamicComponentWithCustomLoading = dynamic(module)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import dynamic from 'next/dynamic'

const module = () => import('../components/hello')
const DynamicComponentWithCustomLoading = dynamic(module)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: import() has to be inside the dynamic() call.
Read more: https://nextjs.org/docs/messages/invalid-dynamic-arguments
--> input.js:4:43
|
4 | const DynamicComponentWithCustomLoading = dynamic(module)
| ^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic()
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import dynamic from 'next/dynamic'

const DynamicComponent = dynamic()
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
error: next/dynamic requires at least one argument
--> input.js:3:26
|
3 | const DynamicComponent = dynamic()
| ^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import dynamic from 'next/dynamic'

const options = { loading: () => <p>...</p>, ssr: false }
const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello'),
options
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import dynamic from 'next/dynamic';

const options = { loading: () => <p>...</p>, ssr: false };
const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello'),
options
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
error: Second argument must be an object literal.
Read more: https://nextjs.org/docs/messages/invalid-dynamic-arguments
--> input.js:4:43
|
4 | const DynamicComponentWithCustomLoading = dynamic(
| ^^^^^^^

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import dynamic from 'next/dynamic'

const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello'),
{ loading: () => <p>...</p> },
"3rd"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import dynamic from 'next/dynamic'

const DynamicComponentWithCustomLoading = dynamic(
() => import('../components/hello'),
{ loading: () => <p>...</p> },
"3rd"
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
error: next/dynamic only accepts 2 arguments
--> input.js:3:43
|
3 | const DynamicComponentWithCustomLoading = dynamic(
| ^^^^^^^

0 comments on commit 63bd6a5

Please sign in to comment.