diff --git a/docs/generated/packages/remix/generators/setup-tailwind.json b/docs/generated/packages/remix/generators/setup-tailwind.json index 2b41acb0af06d..af89b153595e9 100644 --- a/docs/generated/packages/remix/generators/setup-tailwind.json +++ b/docs/generated/packages/remix/generators/setup-tailwind.json @@ -18,8 +18,7 @@ "type": "string", "description": "The name of the project to add tailwind to", "$default": { "$source": "projectName" }, - "x-prompt": "What project would you like to add Tailwind to?", - "pattern": "^[a-zA-Z].*$" + "x-prompt": "What project would you like to add Tailwind to?" }, "skipFormat": { "type": "boolean", diff --git a/packages/remix/src/generators/setup-tailwind/__snapshots__/setup-tailwind.impl.spec.ts.snap b/packages/remix/src/generators/setup-tailwind/__snapshots__/setup-tailwind.impl.spec.ts.snap index 899be3df978b4..c6a9a31a7a500 100644 --- a/packages/remix/src/generators/setup-tailwind/__snapshots__/setup-tailwind.impl.spec.ts.snap +++ b/packages/remix/src/generators/setup-tailwind/__snapshots__/setup-tailwind.impl.spec.ts.snap @@ -43,7 +43,7 @@ exports[`setup-tailwind generator should add a tailwind config to an application ScrollRestoration, } from '@remix-run/react'; import type { MetaFunction, LinksFunction } from '@remix-run/node'; -import twStyles from './tailwind.css'; +import './tailwind.css'; export const meta: MetaFunction = () => [ { @@ -52,7 +52,6 @@ export const meta: MetaFunction = () => [ ]; export const links: LinksFunction = () => [ - { rel: 'stylesheet', href: twStyles }, { rel: 'preconnect', href: 'https://fonts.googleapis.com' }, { rel: 'preconnect', diff --git a/packages/remix/src/generators/setup-tailwind/schema.json b/packages/remix/src/generators/setup-tailwind/schema.json index 9b49050ae7d2a..a718e00600379 100644 --- a/packages/remix/src/generators/setup-tailwind/schema.json +++ b/packages/remix/src/generators/setup-tailwind/schema.json @@ -17,8 +17,7 @@ "$default": { "$source": "projectName" }, - "x-prompt": "What project would you like to add Tailwind to?", - "pattern": "^[a-zA-Z].*$" + "x-prompt": "What project would you like to add Tailwind to?" }, "skipFormat": { "type": "boolean", diff --git a/packages/remix/src/generators/setup-tailwind/setup-tailwind.impl.ts b/packages/remix/src/generators/setup-tailwind/setup-tailwind.impl.ts index 666e41127b007..99e7446132c4c 100644 --- a/packages/remix/src/generators/setup-tailwind/setup-tailwind.impl.ts +++ b/packages/remix/src/generators/setup-tailwind/setup-tailwind.impl.ts @@ -5,39 +5,34 @@ import { installPackagesTask, joinPathFragments, readProjectConfiguration, + stripIndents, type Tree, } from '@nx/devkit'; -import { upsertLinksFunction } from '../../utils/upsert-links-function'; import { autoprefixerVersion, postcssVersion, tailwindVersion, } from '../../utils/versions'; import type { SetupTailwindSchema } from './schema'; +import { insertStatementAfterImports } from '../../utils/insert-statement-after-imports'; export default async function setupTailwind( tree: Tree, options: SetupTailwindSchema ) { const project = readProjectConfiguration(tree, options.project); - if (project.projectType !== 'application') { - throw new Error( - `Project "${options.project}" is not an application. Please ensure the project is an application.` - ); - } generateFiles(tree, joinPathFragments(__dirname, 'files'), project.root, { tpl: '', }); const pathToRoot = joinPathFragments(project.root, 'app/root.tsx'); - upsertLinksFunction( + + insertStatementAfterImports( tree, pathToRoot, - 'twStyles', - './tailwind.css', - `{ rel: "stylesheet", href: twStyles }` + stripIndents`import './tailwind.css';` ); addDependenciesToPackageJson( diff --git a/packages/remix/src/utils/upsert-links-function.spec.ts b/packages/remix/src/utils/upsert-links-function.spec.ts deleted file mode 100644 index ccf75dcfac28d..0000000000000 --- a/packages/remix/src/utils/upsert-links-function.spec.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { stripIndents } from '@nx/devkit'; -import { createTreeWithEmptyWorkspace } from '@nx/devkit/testing'; -import { upsertLinksFunction } from './upsert-links-function'; - -describe('upsertLinksFunctions', () => { - it('should add the imports and the link function when it does not exist', () => { - // ARRANGE - const tree = createTreeWithEmptyWorkspace(); - tree.write(`root.tsx`, ``); - - // ACT - upsertLinksFunction( - tree, - 'root.tsx', - 'styles', - './tailwind.css', - '{ rel: "stylesheet", href: styles }' - ); - - // ASSERT - expect(tree.read('root.tsx', 'utf-8')).toMatchInlineSnapshot(` - "import type { LinksFunction } from '@remix-run/node'; - import styles from "./tailwind.css"; - export const links: LinksFunction = () => [ - { rel: "stylesheet", href: styles }, - ];" - `); - }); - - it('should update an existing links function with the new object', () => { - // ARRANGE - const tree = createTreeWithEmptyWorkspace(); - tree.write( - `root.tsx`, - stripIndents`import type { LinksFunction } from '@remix-run/node'; - - export const links: LinksFunction = () => [ - { rel: "icon", href: "/favicon.png" type: "image/png" } - ` - ); - - // ACT - upsertLinksFunction( - tree, - 'root.tsx', - 'styles', - './tailwind.css', - '{ rel: "stylesheet", href: styles }' - ); - - // ASSERT - expect(tree.read('root.tsx', 'utf-8')).toMatchInlineSnapshot(` - "import type { LinksFunction } from '@remix-run/node'; - import styles from "./tailwind.css"; - - export const links: LinksFunction = () => [ - { rel: "stylesheet", href: styles }, - { rel: "icon", href: "/favicon.png" type: "image/png" }" - `); - }); -}); diff --git a/packages/remix/src/utils/upsert-links-function.ts b/packages/remix/src/utils/upsert-links-function.ts deleted file mode 100644 index aac4c79c358fb..0000000000000 --- a/packages/remix/src/utils/upsert-links-function.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { stripIndents, type Tree } from '@nx/devkit'; -import { tsquery } from '@phenomnomnominal/tsquery'; -import { insertImport } from './insert-import'; -import { insertStatementAfterImports } from './insert-statement-after-imports'; - -export function upsertLinksFunction( - tree: Tree, - filePath: string, - importName: string, - importPath: string, - linkObject: string -) { - insertImport(tree, filePath, 'LinksFunction', '@remix-run/node', { - typeOnly: true, - }); - insertStatementAfterImports( - tree, - filePath, - stripIndents`import ${importName} from "${importPath}";` - ); - - const fileContents = tree.read(filePath, 'utf-8'); - const LINKS_FUNCTION_SELECTOR = - 'VariableDeclaration:has(TypeReference > Identifier[name=LinksFunction])'; - const ast = tsquery.ast(fileContents); - - const linksFunctionNodes = tsquery(ast, LINKS_FUNCTION_SELECTOR, { - visitAllChildren: true, - }); - if (linksFunctionNodes.length === 0) { - insertStatementAfterImports( - tree, - filePath, - stripIndents`export const links: LinksFunction = () => [ - ${linkObject}, -];` - ); - } else { - const linksArrayNodes = tsquery( - linksFunctionNodes[0], - 'ArrayLiteralExpression', - { visitAllChildren: true } - ); - const arrayNode = linksArrayNodes[0]; - const updatedFileContents = `${fileContents.slice( - 0, - arrayNode.getStart() + 1 - )}\n${linkObject},${fileContents.slice(arrayNode.getStart() + 1)}`; - tree.write(filePath, updatedFileContents); - } -}