Skip to content

Commit

Permalink
fix(cli): avoid require in prettier config during tailwind setup (#…
Browse files Browse the repository at this point in the history
…10183)

**Problem**
With the recent switch to prettier v3 we have some new constraints on
how we write our prettier config. One of these is the need to avoid
`require` statements. The tailwind setup command in the CLI was adding
this to the config file and causing runtime errors on commands like
lint.

**Changes**
1. Switches the setup command to simply insert the name of the plugin.
See [here](https://prettier.io/docs/en/plugins#using-plugins) as to
guidance on this.
> Strings provided to plugins are ultimately passed to [import()
expression](https://nodejs.org/api/esm.html#import-expressions), so you
can provide a module/package name, a path, or anything else import()
takes.
2. Regenerated the test project fixture and in so doing it bumped the
`prettier-plugin-tailwindcss` version. You can also see some formatting
for graphql tags have altered as a result of the upgrades.

---------

Co-authored-by: Dominic Saadi <dominiceliassaadi@gmail.com>
  • Loading branch information
Josh-Walker-GM and jtoar committed Mar 12, 2024
1 parent e31be10 commit e74b55c
Show file tree
Hide file tree
Showing 11 changed files with 80 additions and 80 deletions.
6 changes: 6 additions & 0 deletions .changesets/10183.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
- fix(cli): avoid `require` in prettier config during tailwind setup (#10183) by @Josh-Walker-GM

With the recent switch to prettier v3 we are no longer able to use `require` within the `prettier.config.js`
config file. This change prevents the tailwind setup CLI command from adding a require statement when it adds
the `'prettier-plugin-tailwindcss'` plugin and instead it simply inserts the plugin name as a string. This
fixes commands such as `yarn rw lint` which would have failed in the presence of such a `require` statement.
2 changes: 1 addition & 1 deletion __fixtures__/fragment-test-project/prettier.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ module.exports = {
},
],
tailwindConfig: './web/config/tailwind.config.js',
plugins: [require('prettier-plugin-tailwindcss')],
plugins: ['prettier-plugin-tailwindcss'],
}
2 changes: 1 addition & 1 deletion __fixtures__/fragment-test-project/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"autoprefixer": "^10.4.16",
"postcss": "^8.4.33",
"postcss-loader": "^7.3.4",
"prettier-plugin-tailwindcss": "0.4.1",
"prettier-plugin-tailwindcss": "^0.5.12",
"tailwindcss": "^3.4.1"
}
}
2 changes: 1 addition & 1 deletion __fixtures__/test-project/prettier.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ module.exports = {
},
],
tailwindConfig: './web/config/tailwind.config.js',
plugins: [require('prettier-plugin-tailwindcss')],
plugins: ['prettier-plugin-tailwindcss'],
}
2 changes: 1 addition & 1 deletion __fixtures__/test-project/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"autoprefixer": "^10.4.18",
"postcss": "^8.4.35",
"postcss-loader": "^8.1.1",
"prettier-plugin-tailwindcss": "0.4.1",
"prettier-plugin-tailwindcss": "^0.5.12",
"tailwindcss": "^3.4.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,21 @@ import type {

import BlogPost from 'src/components/BlogPost'

export const QUERY: TypedDocumentNode<
BlogPostsQuery,
BlogPostsQueryVariables
> = gql`
query BlogPostsQuery {
blogPosts: posts {
id
title
body
author {
email
fullName
export const QUERY: TypedDocumentNode<BlogPostsQuery, BlogPostsQueryVariables> =
gql`
query BlogPostsQuery {
blogPosts: posts {
id
title
body
author {
email
fullName
}
createdAt
}
createdAt
}
}
`
`

export const Loading = () => <div>Loading...</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@ import type {

import Contacts from 'src/components/Contact/Contacts'

export const QUERY: TypedDocumentNode<
FindContacts,
FindContactsVariables
> = gql`
query FindContacts {
contacts {
id
name
email
message
createdAt
export const QUERY: TypedDocumentNode<FindContacts, FindContactsVariables> =
gql`
query FindContacts {
contacts {
id
name
email
message
createdAt
}
}
}
`
`

export const Loading = () => <div>Loading...</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@ import type {

import Post from 'src/components/Post/Post'

export const QUERY: TypedDocumentNode<
FindPostById,
FindPostByIdVariables
> = gql`
query FindPostById($id: Int!) {
post: post(id: $id) {
id
title
body
authorId
createdAt
export const QUERY: TypedDocumentNode<FindPostById, FindPostByIdVariables> =
gql`
query FindPostById($id: Int!) {
post: post(id: $id) {
id
title
body
authorId
createdAt
}
}
}
`
`

export const Loading = () => <div>Loading...</div>

Expand Down
66 changes: 33 additions & 33 deletions packages/cli/src/commands/setup/ui/libraries/tailwindcss.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const tailwindDirectives = [
/** @param {string} indexCSS */
const tailwindDirectivesExist = (indexCSS) =>
tailwindDirectives.every((tailwindDirective) =>
indexCSS.includes(tailwindDirective)
indexCSS.includes(tailwindDirective),
)

const tailwindImportsAndNotes = [
Expand All @@ -65,11 +65,11 @@ const recommendedVSCodeExtensions = [
const recommendationTexts = {
'csstools.postcss': terminalLink(
'PostCSS Language Support',
'https://marketplace.visualstudio.com/items?itemName=csstools.postcss'
'https://marketplace.visualstudio.com/items?itemName=csstools.postcss',
),
'bradlc.vscode-tailwindcss': terminalLink(
'Tailwind CSS IntelliSense',
'https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss'
'https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss',
),
}

Expand All @@ -84,7 +84,7 @@ async function recommendExtensionsToInstall() {
const { stdout } = await execa('code', ['--list-extensions'])
const installedExtensions = stdout.split('\n').map((ext) => ext.trim())
recommendations = recommendedVSCodeExtensions.filter(
(ext) => !installedExtensions.includes(ext)
(ext) => !installedExtensions.includes(ext),
)
} catch {
// `code` probably not in PATH so can't check for installed extensions.
Expand All @@ -97,8 +97,8 @@ async function recommendExtensionsToInstall() {
console.log(
c.info(
'For the best experience we recommend that you install the following ' +
(recommendations.length === 1 ? 'extension:' : 'extensions:')
)
(recommendations.length === 1 ? 'extension:' : 'extensions:'),
),
)

recommendations.forEach((extension) => {
Expand All @@ -115,7 +115,7 @@ export const handler = async ({ force, install }) => {
})
const rwPaths = getPaths()

const projectPackages = ['prettier-plugin-tailwindcss@0.4.1']
const projectPackages = ['prettier-plugin-tailwindcss@^0.5.12']

const webWorkspacePackages = [
'postcss',
Expand Down Expand Up @@ -146,7 +146,7 @@ export const handler = async ({ force, install }) => {
},
},
],
{ rendererOptions: { collapseSubtasks: false } }
{ rendererOptions: { collapseSubtasks: false } },
)
},
},
Expand All @@ -169,7 +169,7 @@ export const handler = async ({ force, install }) => {
},
},
],
{ rendererOptions: { collapseSubtasks: false } }
{ rendererOptions: { collapseSubtasks: false } },
)
},
},
Expand All @@ -184,12 +184,12 @@ export const handler = async ({ force, install }) => {

if (!force && fs.existsSync(postCSSConfigPath)) {
throw new Error(
'PostCSS config already exists.\nUse --force to override existing config.'
'PostCSS config already exists.\nUse --force to override existing config.',
)
} else {
const postCSSConfig = fs.readFileSync(
path.join(__dirname, '../templates/postcss.config.js.template'),
'utf-8'
'utf-8',
)

return outputFileSync(postCSSConfigPath, postCSSConfig)
Expand All @@ -201,7 +201,7 @@ export const handler = async ({ force, install }) => {
task: async () => {
const tailwindConfigPath = path.join(
rwPaths.web.config,
'tailwind.config.js'
'tailwind.config.js',
)

if (fs.existsSync(tailwindConfigPath)) {
Expand All @@ -210,7 +210,7 @@ export const handler = async ({ force, install }) => {
fs.unlinkSync(tailwindConfigPath)
} else {
throw new Error(
'Tailwindcss config already exists.\nUse --force to override existing config.'
'Tailwindcss config already exists.\nUse --force to override existing config.',
)
}
}
Expand All @@ -223,7 +223,7 @@ export const handler = async ({ force, install }) => {
const tailwindConfig = fs.readFileSync(tailwindConfigPath, 'utf-8')
const newTailwindConfig = tailwindConfig.replace(
'content: []',
"content: ['src/**/*.{js,jsx,ts,tsx}']"
"content: ['src/**/*.{js,jsx,ts,tsx}']",
)
fs.writeFileSync(tailwindConfigPath, newTailwindConfig)
},
Expand Down Expand Up @@ -268,12 +268,12 @@ export const handler = async ({ force, install }) => {
'scaffold',
'templates',
'assets',
'scaffold.tailwind.css.template'
)
'scaffold.tailwind.css.template',
),
)
fs.writeFileSync(
path.join(rwPaths.web.src, 'scaffold.css'),
tailwindScaffoldTemplate
tailwindScaffoldTemplate,
)
} else {
task.skip('Skipping scaffold.css override')
Expand All @@ -285,7 +285,7 @@ export const handler = async ({ force, install }) => {
task: (_ctx, task) => {
const VS_CODE_EXTENSIONS_PATH = path.join(
rwPaths.base,
'.vscode/extensions.json'
'.vscode/extensions.json',
)

if (!usingVSCode()) {
Expand All @@ -295,7 +295,7 @@ export const handler = async ({ force, install }) => {
if (fs.existsSync(VS_CODE_EXTENSIONS_PATH)) {
const originalExtensionsFile = fs.readFileSync(
VS_CODE_EXTENSIONS_PATH,
'utf-8'
'utf-8',
)
originalExtensionsJson = JSON.parse(originalExtensionsFile)
}
Expand All @@ -308,7 +308,7 @@ export const handler = async ({ force, install }) => {
}
fs.writeFileSync(
VS_CODE_EXTENSIONS_PATH,
JSON.stringify(newExtensionsJson, null, 2)
JSON.stringify(newExtensionsJson, null, 2),
)
}
},
Expand All @@ -318,14 +318,14 @@ export const handler = async ({ force, install }) => {
task: async (_ctx) => {
const prettierConfigPath = path.join(
rwPaths.base,
'prettier.config.js'
'prettier.config.js',
)
// Add tailwindcss ordering plugin to prettier
const prettierConfig = fs.readFileSync(prettierConfigPath, 'utf-8')
const tailwindConfigPath = path
.relative(
rwPaths.base,
path.posix.join(rwPaths.web.config, 'tailwind.config.js')
path.posix.join(rwPaths.web.config, 'tailwind.config.js'),
)
.replaceAll('\\', '/')

Expand All @@ -334,17 +334,17 @@ export const handler = async ({ force, install }) => {
if (force) {
newPrettierConfig = newPrettierConfig.replace(
/tailwindConfig: .*(,)?/,
`tailwindConfig: './${tailwindConfigPath}',`
`tailwindConfig: './${tailwindConfigPath}',`,
)
} else {
throw new Error(
'tailwindConfig setting already exists in prettier configuration.\nUse --force to override existing config.'
'tailwindConfig setting already exists in prettier configuration.\nUse --force to override existing config.',
)
}
} else {
newPrettierConfig = newPrettierConfig.replace(
/,(\n\s*)(\}\n?)$/,
`,\n tailwindConfig: './${tailwindConfigPath}',$1$2`
`,\n tailwindConfig: './${tailwindConfigPath}',$1$2`,
)
}

Expand All @@ -356,45 +356,45 @@ export const handler = async ({ force, install }) => {
task: async (_ctx, task) => {
const prettierConfigPath = path.join(
rwPaths.base,
'prettier.config.js'
'prettier.config.js',
)
// Add tailwindcss ordering plugin to prettier
const prettierConfig = fs.readFileSync(prettierConfigPath, 'utf-8')

let newPrettierConfig = prettierConfig
if (newPrettierConfig.includes('plugins: [')) {
const pluginsMatch = newPrettierConfig.match(
/plugins: \[[\sa-z\(\)'\-,]*]/
/plugins: \[[\sa-z\(\)'\-,]*]/,
)

const matched = pluginsMatch && pluginsMatch[0]

if (
matched &&
(matched.includes("require('prettier-plugin-tailwindcss')") ||
matched.includes('require("prettier-plugin-tailwindcss")'))
(matched.includes("'prettier-plugin-tailwindcss'") ||
matched.includes('"prettier-plugin-tailwindcss"'))
) {
task.skip(
'tailwindcss-plugin-prettier already required in plugins'
'tailwindcss-plugin-prettier already required in plugins',
)
} else {
newPrettierConfig = newPrettierConfig.replace(
/plugins: \[(\n\s+)*/,
`plugins: [$1require('prettier-plugin-tailwindcss'),$1`
`plugins: [$'prettier-plugin-tailwindcss',$1`,
)
}
} else {
newPrettierConfig = newPrettierConfig.replace(
/,(\n\s*)(\}\n?)$/,
`,\n plugins: [require('prettier-plugin-tailwindcss')],$1$2`
`,\n plugins: ['prettier-plugin-tailwindcss'],$1$2`,
)
}

fs.writeFileSync(prettierConfigPath, newPrettierConfig)
},
},
],
{ rendererOptions: { collapseSubtasks: false } }
{ rendererOptions: { collapseSubtasks: false } },
)

try {
Expand Down
2 changes: 1 addition & 1 deletion tasks/test-project/tasks.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ async function webTasks(outputPath, { linkWithLatestFwBuild, verbose }) {
// @NOTE: use rwfw, because calling the copy function doesn't seem to work here
task: () =>
execa(
'yarn workspace web add -D postcss postcss-loader tailwindcss autoprefixer prettier-plugin-tailwindcss@0.4.1',
'yarn workspace web add -D postcss postcss-loader tailwindcss autoprefixer prettier-plugin-tailwindcss@^0.5.12',
[],
getExecaOptions(outputPath)
),
Expand Down
Loading

0 comments on commit e74b55c

Please sign in to comment.