Skip to content

Commit

Permalink
fix(next-swc): skips client/server only checks when running with Jest…
Browse files Browse the repository at this point in the history
… to unblock testing (#54891)

Co-authored-by: Jiachi Liu <inbox@huozhi.im>
  • Loading branch information
feugy and huozhi committed Sep 4, 2023
1 parent fd91ac4 commit 3338dd0
Show file tree
Hide file tree
Showing 54 changed files with 393 additions and 142 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Expand Up @@ -6,7 +6,8 @@
"browser": true,
"commonjs": true,
"es6": true,
"node": true
"node": true,
"jest": true
},
"parserOptions": {
"requireConfigFile": false,
Expand Down
8 changes: 7 additions & 1 deletion jest.config.js
Expand Up @@ -5,7 +5,13 @@ const createJestConfig = nextJest()
// Any custom config you want to pass to Jest
/** @type {import('jest').Config} */
const customJestConfig = {
testMatch: ['**/*.test.js', '**/*.test.ts', '**/*.test.tsx'],
testMatch: [
'**/*.test.js',
'**/*.test.ts',
'**/*.test.tsx',
'**/jest/**/*.test.jsx',
'**/jest/**/*.test.tsx',
],
setupFilesAfterEnv: ['<rootDir>/jest-setup-after-env.ts'],
verbose: true,
rootDir: 'test',
Expand Down
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -87,6 +87,7 @@
"@swc/cli": "0.1.55",
"@swc/core": "1.3.55",
"@swc/helpers": "0.5.1",
"@testing-library/jest-dom": "6.1.2",
"@testing-library/react": "13.0.0",
"@types/cheerio": "0.22.16",
"@types/cookie": "0.3.3",
Expand Down
6 changes: 5 additions & 1 deletion packages/next-swc/crates/core/src/lib.rs
Expand Up @@ -95,6 +95,9 @@ pub struct TransformOptions {
#[serde(default)]
pub is_server: bool,

#[serde(default)]
pub disable_checks: bool,

#[serde(default)]
pub server_components: Option<react_server_components::Config>,

Expand Down Expand Up @@ -190,7 +193,8 @@ where
file.name.clone(),
config.clone(),
comments.clone(),
opts.app_dir.clone()
opts.app_dir.clone(),
opts.disable_checks
)),
_ => Either::Right(noop()),
},
Expand Down
13 changes: 11 additions & 2 deletions packages/next-swc/crates/core/src/react_server_components.rs
Expand Up @@ -50,6 +50,7 @@ struct ReactServerComponents<C: Comments> {
invalid_client_imports: Vec<JsWord>,
invalid_server_react_apis: Vec<JsWord>,
invalid_server_react_dom_apis: Vec<JsWord>,
disable_checks: bool,
}

struct ModuleImports {
Expand Down Expand Up @@ -128,7 +129,7 @@ impl<C: Comments> ReactServerComponents<C> {
if is_action_file {
panic_both_directives(expr_stmt.span)
}
} else {
} else if !self.disable_checks {
HANDLER.with(|handler| {
handler
.struct_span_err(
Expand Down Expand Up @@ -333,6 +334,9 @@ impl<C: Comments> ReactServerComponents<C> {
}

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

fn assert_client_graph(&self, imports: &[ModuleImports], module: &Module) {
if self.disable_checks {
return;
}
for import in imports {
let source = import.source.0.clone();
if self.invalid_client_imports.contains(&source) {
Expand Down Expand Up @@ -560,12 +567,14 @@ pub fn server_components<C: Comments>(
config: Config,
comments: C,
app_dir: Option<PathBuf>,
disable_checks: bool,
) -> impl Fold + VisitMut {
let is_server: bool = match config {
let is_server: bool = match &config {
Config::WithOptions(x) => x.is_server,
_ => true,
};
as_folder(ReactServerComponents {
disable_checks,
is_server,
comments,
filepath: filename.to_string(),
Expand Down
4 changes: 4 additions & 0 deletions packages/next-swc/crates/core/tests/errors.rs
Expand Up @@ -97,6 +97,7 @@ fn react_server_components_server_graph_errors(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false,
)
},
&input,
Expand All @@ -121,6 +122,7 @@ fn react_server_components_client_graph_errors(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false,
)
},
&input,
Expand Down Expand Up @@ -167,6 +169,7 @@ fn react_server_actions_server_errors(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false
),
server_actions(
&FileName::Real("/app/item.js".into()),
Expand Down Expand Up @@ -202,6 +205,7 @@ fn react_server_actions_client_errors(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false
),
server_actions(
&FileName::Real("/app/item.js".into()),
Expand Down
46 changes: 46 additions & 0 deletions packages/next-swc/crates/core/tests/fixture.rs
Expand Up @@ -325,6 +325,29 @@ fn react_server_components_server_graph_fixture(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false,
)
},
&input,
&output,
Default::default(),
);
}

#[fixture("tests/fixture/react-server-components/server-graph-no-checks/**/input.js")]
fn react_server_components_no_checks_server_graph_fixture(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");
test_fixture(
syntax(),
&|tr| {
server_components(
FileName::Real(PathBuf::from("/some-project/src/some-file.js")),
next_swc::react_server_components::Config::WithOptions(
next_swc::react_server_components::Options { is_server: true },
),
tr.comments.as_ref().clone(),
None,
true,
)
},
&input,
Expand All @@ -346,6 +369,29 @@ fn react_server_components_client_graph_fixture(input: PathBuf) {
),
tr.comments.as_ref().clone(),
None,
false,
)
},
&input,
&output,
Default::default(),
);
}

#[fixture("tests/fixture/react-server-components/client-graph-no-checks/**/input.js")]
fn react_server_components_no_checks_client_graph_fixture(input: PathBuf) {
let output = input.parent().unwrap().join("output.js");
test_fixture(
syntax(),
&|tr| {
server_components(
FileName::Real(PathBuf::from("/some-project/src/some-file.js")),
next_swc::react_server_components::Config::WithOptions(
next_swc::react_server_components::Options { is_server: false },
),
tr.comments.as_ref().clone(),
None,
true,
)
},
&input,
Expand Down
@@ -0,0 +1,13 @@
// This is a comment.

'use strict'

/**
* This is a comment.
*/

import 'client-only'

export default function () {
return null
}
@@ -0,0 +1,8 @@
// This is a comment.
'use strict';
/**
* This is a comment.
*/ import 'client-only';
export default function() {
return null;
}
@@ -0,0 +1,5 @@
export function getServerSideProps() {}

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

export default function () {
return null
}
@@ -0,0 +1,4 @@
export function getStaticProps() {}
export default function() {
return null;
}
@@ -0,0 +1,13 @@
// This is a comment.

'use strict'

/**
* This is a comment.
*/

import 'server-only'

export default function () {
return null
}
@@ -0,0 +1,8 @@
// This is a comment.
'use strict';
/**
* This is a comment.
*/ import 'server-only';
export default function() {
return null;
}
@@ -0,0 +1,8 @@
import 'react'

// prettier-ignore
'use client'

export default function () {
return null
}
@@ -0,0 +1,4 @@
import 'react';
export default function() {
return null;
}
@@ -0,0 +1,13 @@
// This is a comment.

'use strict'

/**
* This is a comment.
*/

import 'client-only'

export default function () {
return null
}
@@ -0,0 +1,8 @@
// This is a comment.
'use strict';
/**
* This is a comment.
*/ import 'client-only';
export default function() {
return null;
}
@@ -0,0 +1,6 @@
export default function () {
return null
}

// prettier-ignore
'use client'
@@ -0,0 +1,3 @@
export default function() {
return null;
}
@@ -0,0 +1,5 @@
export function getServerSideProps() {}

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

export default function () {
return null
}
@@ -0,0 +1,4 @@
export function getStaticProps() {}
export default function() {
return null;
}
@@ -0,0 +1,21 @@
import { useState } from 'react'

import { createContext } from 'react'

import { useEffect, useImperativeHandle } from 'react'

import {
Component,
createFactory,
PureComponent,
useDeferredValue,
useInsertionEffect,
useLayoutEffect,
useReducer,
useRef,
useSyncExternalStore,
} from 'react'

export default function () {
return null
}
@@ -0,0 +1,7 @@
import { useState } from 'react';
import { createContext } from 'react';
import { useEffect, useImperativeHandle } from 'react';
import { Component, createFactory, PureComponent, useDeferredValue, useInsertionEffect, useLayoutEffect, useReducer, useRef, useSyncExternalStore } from 'react';
export default function() {
return null;
}
@@ -0,0 +1,10 @@
import { findDOMNode, flushSync, unstable_batchedUpdates } from 'react-dom'

import {
experimental_useOptimistic as useOptimistic,
experimental_useFormStatus,
} from 'react-dom'

export default function () {
return null
}
@@ -0,0 +1,5 @@
import { findDOMNode, flushSync, unstable_batchedUpdates } from 'react-dom';
import { experimental_useOptimistic as useOptimistic, experimental_useFormStatus } from 'react-dom';
export default function() {
return null;
}
@@ -0,0 +1,15 @@
// This is a comment.

'use strict'

/**
* This is a comment.
*/

import 'react-dom/server'

import 'react-dom/client'

export default function () {
return null
}

0 comments on commit 3338dd0

Please sign in to comment.