From cfcd4d144031e0cbbcf2d0bbcd0ba8f2d4902c6e Mon Sep 17 00:00:00 2001 From: Emily Xiong Date: Thu, 12 Dec 2024 10:05:21 -0800 Subject: [PATCH] fix(react): fix tailwind for react library and component (#29319) ## Current Behavior ## Expected Behavior ## Related Issue(s) Fixes https://github.com/nrwl/nx/issues/27954 --- .../packages/next/generators/component.json | 4 + .../packages/next/generators/library.json | 4 + .../packages/react/generators/component.json | 4 + .../packages/react/generators/library.json | 4 + .../__snapshots__/application.spec.ts.snap | 471 ++++++++++++++++++ .../application/application.spec.ts | 42 ++ .../next/src/generators/component/schema.json | 4 + .../next/src/generators/library/schema.json | 4 + .../__snapshots__/application.spec.ts.snap | 94 ++++ .../application/application.spec.ts | 18 + .../__snapshots__/component.spec.ts.snap | 81 +++ .../generators/component/component.spec.ts | 22 + .../component/files/__fileName__.__ext__ | 6 +- .../src/generators/component/schema.json | 4 + .../__snapshots__/library.spec.ts.snap | 55 ++ .../src/generators/library/library.spec.ts | 20 + .../react/src/generators/library/schema.json | 4 + 17 files changed, 838 insertions(+), 3 deletions(-) create mode 100644 packages/react/src/generators/component/__snapshots__/component.spec.ts.snap diff --git a/docs/generated/packages/next/generators/component.json b/docs/generated/packages/next/generators/component.json index f21be28991641..c708ed95b612b 100644 --- a/docs/generated/packages/next/generators/component.json +++ b/docs/generated/packages/next/generators/component.json @@ -38,6 +38,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/docs/generated/packages/next/generators/library.json b/docs/generated/packages/next/generators/library.json index d101fa4219834..5b3cc7a3aa220 100644 --- a/docs/generated/packages/next/generators/library.json +++ b/docs/generated/packages/next/generators/library.json @@ -40,6 +40,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/docs/generated/packages/react/generators/component.json b/docs/generated/packages/react/generators/component.json index e1fb4b811172e..09f3e95db015f 100644 --- a/docs/generated/packages/react/generators/component.json +++ b/docs/generated/packages/react/generators/component.json @@ -38,6 +38,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/docs/generated/packages/react/generators/library.json b/docs/generated/packages/react/generators/library.json index fa5b8dc3b5ad8..6133297c0d286 100644 --- a/docs/generated/packages/react/generators/library.json +++ b/docs/generated/packages/react/generators/library.json @@ -49,6 +49,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap index 9019c2808c9bc..ddfa88dfae1a6 100644 --- a/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/next/src/generators/application/__snapshots__/application.spec.ts.snap @@ -477,3 +477,474 @@ export default function Index() { } " `; + +exports[`app --style tailwind should generate tailwind styles 1`] = ` +"export default function Index() { + /* + * Replace the elements below with your own. + * + * Note: The corresponding styles are in the ./index.tailwind file. + */ + return ( +
+
+
+
+

+ Hello there, + Welcome myapp 👋 +

+
+ +
+
+

+ + + + You're up and running +

+ What's next? +
+
+ + + +
+
+ + + +
+

Next steps

+

Here are some things you can do with Nx:

+
+ + + + + Add UI library + +
+                # Generate UI lib
+                nx g @nx/next:library ui
+                # Add a component
+                nx g @nx/next:component ui/src/lib/button
+              
+
+
+ + + + + View project details + +
nx show project myapp --web
+
+
+ + + + + View interactive project graph + +
nx graph
+
+
+ + + + + Run affected commands + +
+                # see what's been affected by changes
+                nx affected:graph
+                # run tests for current changes
+                nx affected:test
+                # run e2e tests for current changes
+                nx affected:e2e
+              
+
+
+ +

+ Carefully crafted with + + + +

+
+
+
+ ); +} +" +`; diff --git a/packages/next/src/generators/application/application.spec.ts b/packages/next/src/generators/application/application.spec.ts index e2c5173944b45..a1977fc601f22 100644 --- a/packages/next/src/generators/application/application.spec.ts +++ b/packages/next/src/generators/application/application.spec.ts @@ -433,6 +433,48 @@ describe('app', () => { }); }); + describe('--style tailwind', () => { + it('should generate tailwind styles', async () => { + await applicationGenerator(tree, { + directory: 'myapp', + style: 'tailwind', + }); + + expect(tree.exists(`myapp/src/app/page.module.scss`)).toBeFalsy(); + expect(tree.exists(`myapp/src/app/global.css`)).toBeTruthy(); + + const indexContent = tree.read(`myapp/src/app/page.tsx`, 'utf-8'); + expect(indexContent).not.toContain(`import styles from './page.module`); + expect(indexContent).not.toContain( + `import styled from 'styled-components'` + ); + expect(indexContent).toMatchSnapshot(); + + expect(tree.read(`myapp/src/app/layout.tsx`, 'utf-8')) + .toMatchInlineSnapshot(` + "import './global.css'; + + export const metadata = { + title: 'Welcome to myapp', + description: 'Generated by create-nx-workspace', + }; + + export default function RootLayout({ + children, + }: { + children: React.ReactNode; + }) { + return ( + + {children} + + ); + } + " + `); + }); + }); + it('should setup jest with tsx support', async () => { const name = uniq(); diff --git a/packages/next/src/generators/component/schema.json b/packages/next/src/generators/component/schema.json index c35a59782b446..f4123eea0b4dd 100644 --- a/packages/next/src/generators/component/schema.json +++ b/packages/next/src/generators/component/schema.json @@ -41,6 +41,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/packages/next/src/generators/library/schema.json b/packages/next/src/generators/library/schema.json index 4ac42721138fa..357ba21e606c3 100644 --- a/packages/next/src/generators/library/schema.json +++ b/packages/next/src/generators/library/schema.json @@ -43,6 +43,10 @@ "value": "less", "label": "LESS [ https://lesscss.org ]" }, + { + "value": "tailwind", + "label": "tailwind [ https://tailwindcss.com/ ]" + }, { "value": "styled-components", "label": "styled-components [ https://styled-components.com ]" diff --git a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap index 0a05b6eb0842d..9029419e4bad2 100644 --- a/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap +++ b/packages/react/src/generators/application/__snapshots__/application.spec.ts.snap @@ -192,6 +192,40 @@ export default defineConfig({ " `; +exports[`app --style scss should generate scss styles 1`] = ` +"// Uncomment this line to use CSS modules +// import styles from './app.module.scss'; +import NxWelcome from "./nx-welcome"; + +export function App() { + return ( +
+ +
+ ); +} + +export default App; + + +" +`; + +exports[`app --style tailwind should not generate any styles files 1`] = ` +"import NxWelcome from './nx-welcome'; + +export function App() { + return ( +
+ +
+ ); +} + +export default App; +" +`; + exports[`app not nested should add vite types to tsconfigs 1`] = ` "/// import { defineConfig } from 'vite'; @@ -358,6 +392,66 @@ export function App() { export default App; +" +`; + +exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 1`] = ` +"import styled from 'styled-components'; +import NxWelcome from "./nx-welcome"; + +const StyledApp = styled.div\` + // Your style here +\`; + +export function App() { + return ( + + + + ); +} + +export default App; + +" +`; + +exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 2`] = ` +"import NxWelcome from "./nx-welcome"; + +export function App() { + return ( +
+ + +
+ ); +} + +export default App; + + +" +`; + +exports[`app should generate valid .babelrc JSON config for CSS-in-JS solutions 3`] = ` +"import styled from '@emotion/styled'; +import NxWelcome from "./nx-welcome"; + +const StyledApp = styled.div\` + // Your style here +\`; + +export function App() { + return ( + + + + ); +} + +export default App; + " `; diff --git a/packages/react/src/generators/application/application.spec.ts b/packages/react/src/generators/application/application.spec.ts index 1cd5c63075145..44826502ba28d 100644 --- a/packages/react/src/generators/application/application.spec.ts +++ b/packages/react/src/generators/application/application.spec.ts @@ -486,6 +486,8 @@ describe('app', () => { expect(() => { readJson(appTree, `my-app/.babelrc`); }).not.toThrow(); + const content = appTree.read('my-app/src/app/app.tsx').toString(); + expect(content).toMatchSnapshot(); } ); @@ -493,6 +495,8 @@ describe('app', () => { it('should generate scss styles', async () => { await applicationGenerator(appTree, { ...schema, style: 'scss' }); expect(appTree.exists('my-app/src/app/app.module.scss')).toEqual(true); + const content = appTree.read('my-app/src/app/app.tsx').toString(); + expect(content).toMatchSnapshot(); }); }); @@ -509,6 +513,20 @@ describe('app', () => { " `); }); + + it('should not generate any styles files', async () => { + await applicationGenerator(appTree, { ...schema, style: 'tailwind' }); + + expect(appTree.exists('my-app/src/app/app.tsx')).toBeTruthy(); + expect(appTree.exists('my-app/src/app/app.spec.tsx')).toBeTruthy(); + expect(appTree.exists('my-app/src/app/app.css')).toBeFalsy(); + expect(appTree.exists('my-app/src/app/app.scss')).toBeFalsy(); + expect(appTree.exists('my-app/src/app/app.module.css')).toBeFalsy(); + expect(appTree.exists('my-app/src/app/app.module.scss')).toBeFalsy(); + + const content = appTree.read('my-app/src/app/app.tsx').toString(); + expect(content).toMatchSnapshot(); + }); }); it('should setup jest with tsx support', async () => { diff --git a/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap b/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap new file mode 100644 index 0000000000000..e22f1d160f449 --- /dev/null +++ b/packages/react/src/generators/component/__snapshots__/component.spec.ts.snap @@ -0,0 +1,81 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`component --style @emotion/styled should use @emotion/styled as the styled API library 1`] = ` +"import styled from '@emotion/styled'; + +const StyledHello = styled.div\` + color: pink; +\`; +export function Hello() { + return ( + +

Welcome to Hello!

+
+ ); +} + +export default Hello; +" +`; + +exports[`component --style none should generate component files without styles 1`] = ` +"export function Hello() { + return ( +
+

Welcome to Hello!

+
+ ); +} + +export default Hello; +" +`; + +exports[`component --style styled-components should use styled-components as the styled API library 1`] = ` +"import styled from 'styled-components'; + +const StyledHello = styled.div\` + color: pink; +\`; +export function Hello() { + return ( + +

Welcome to Hello!

+
+ ); +} + +export default Hello; +" +`; + +exports[`component --style styled-jsx should use styled-jsx as the styled API library 1`] = ` +"export function Hello() { + return ( +
+ {' '} +

Welcome to Hello!

+
+ ); +} + +export default Hello; +" +`; + +exports[`component --style tailwind should not generate any style in component 1`] = ` +"export function Hello() { + return ( +
+

Welcome to Hello!

+
+ ); +} + +export default Hello; +" +`; diff --git a/packages/react/src/generators/component/component.spec.ts b/packages/react/src/generators/component/component.spec.ts index acb66237ed83c..89ca1c4ad43cb 100644 --- a/packages/react/src/generators/component/component.spec.ts +++ b/packages/react/src/generators/component/component.spec.ts @@ -217,6 +217,7 @@ describe('component', () => { expect(content).not.toContain('hello.scss'); expect(content).not.toContain('hello.module.css'); expect(content).not.toContain('hello.module.scss'); + expect(content).toMatchSnapshot(); }); }); @@ -236,6 +237,7 @@ describe('component', () => { const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString(); expect(content).toContain('styled-components'); expect(content).toContain(''); + expect(content).toMatchSnapshot(); }); it('should add dependencies to package.json', async () => { @@ -266,6 +268,7 @@ describe('component', () => { const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString(); expect(content).toContain('@emotion/styled'); expect(content).toContain(''); + expect(content).toMatchSnapshot(); }); it('should add dependencies to package.json', async () => { @@ -297,6 +300,7 @@ describe('component', () => { const content = appTree.read('my-lib/src/lib/hello/hello.tsx').toString(); expect(content).toContain('