diff --git a/CHANGELOG.md b/CHANGELOG.md index ad96c9d..2c43d1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] -- Nothing yet! +- Support TypeScript configs and plugins when using v4 ([#342](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/pull/342)) ## [0.6.10] - 2025-01-15 diff --git a/package-lock.json b/package-lock.json index a86fc2c..a68430d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "prettier-plugin-tailwindcss", - "version": "0.6.9", + "version": "0.6.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "prettier-plugin-tailwindcss", - "version": "0.6.9", + "version": "0.6.10", "license": "MIT", "devDependencies": { "@babel/types": "^7.24.7", @@ -15,6 +15,7 @@ "@prettier/plugin-pug": "^3.0", "@shopify/prettier-plugin-liquid": "^1.4.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@types/node": "^22.10.9", "@zackad/prettier-plugin-twig": "^0.14.1", "ast-types": "^0.14.2", "clear-module": "^4.1.2", @@ -23,6 +24,7 @@ "esbuild": "^0.19.8", "escalade": "^3.1.1", "import-sort-style-module": "^6.0.0", + "jiti": "^2.4.2", "jsesc": "^2.5.2", "license-checker": "^25.0.1", "line-column": "^1.0.2", @@ -1917,6 +1919,16 @@ "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", "dev": true }, + "node_modules/@types/node": { + "version": "22.10.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.9.tgz", + "integrity": "sha512-Ir6hwgsKyNESl/gLOcEz3krR4CBGgliDqBQ2ma4wIhEx0w+xnoeTq3tdrNw15kU3SxogDjOgv9sqdtLW8mIHaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.20.0" + } + }, "node_modules/@types/unist": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", @@ -3930,12 +3942,13 @@ "dev": true }, "node_modules/jiti": { - "version": "1.21.6", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.6.tgz", - "integrity": "sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", "dev": true, + "license": "MIT", "bin": { - "jiti": "bin/jiti.js" + "jiti": "lib/jiti-cli.mjs" } }, "node_modules/jju": { @@ -6679,6 +6692,16 @@ "node": ">=10.13.0" } }, + "node_modules/tailwindcss/node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, "node_modules/tailwindcss/node_modules/postcss-import": { "version": "15.1.0", "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-15.1.0.tgz", @@ -7448,6 +7471,13 @@ "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", "dev": true }, + "node_modules/undici-types": { + "version": "6.20.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "dev": true, + "license": "MIT" + }, "node_modules/unist-util-stringify-position": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", diff --git a/package.json b/package.json index 68ce542..08d8b64 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ "@prettier/plugin-pug": "^3.0", "@shopify/prettier-plugin-liquid": "^1.4.0", "@trivago/prettier-plugin-sort-imports": "^4.3.0", + "@types/node": "^22.10.9", "@zackad/prettier-plugin-twig": "^0.14.1", "ast-types": "^0.14.2", "clear-module": "^4.1.2", @@ -47,6 +48,7 @@ "esbuild": "^0.19.8", "escalade": "^3.1.1", "import-sort-style-module": "^6.0.0", + "jiti": "^2.4.2", "jsesc": "^2.5.2", "license-checker": "^25.0.1", "line-column": "^1.0.2", diff --git a/src/config.ts b/src/config.ts index 8a02126..a01e183 100644 --- a/src/config.ts +++ b/src/config.ts @@ -4,6 +4,7 @@ import * as path from 'path' import { pathToFileURL } from 'url' import clearModule from 'clear-module' import escalade from 'escalade/sync' +import { createJiti, Jiti } from 'jiti' import postcss from 'postcss' // @ts-ignore import postcssImport from 'postcss-import' @@ -156,10 +157,12 @@ async function loadTailwindConfig( */ function createLoader({ legacy, + jiti, filepath, onError, }: { legacy: boolean + jiti: Jiti filepath: string onError: (id: string, error: unknown, resourceType: string) => T }) { @@ -172,7 +175,7 @@ function createLoader({ let url = pathToFileURL(resolved) url.searchParams.append('t', cacheKey) - return await import(url.href).then((m) => m.default ?? m) + return await jiti.import(url.href, { default: true }) } catch (err) { return onError(id, err, resourceType) } @@ -209,6 +212,12 @@ async function loadV4( // If the user doesn't define an entrypoint then we use the default theme entryPoint = entryPoint ?? `${pkgDir}/theme.css` + // Create a Jiti instance that can be used to load plugins and config files + let jiti = createJiti(import.meta.url, { + moduleCache: false, + fsCache: false, + }) + let importBasePath = path.dirname(entryPoint) // Resolve imports in the entrypoint to a flat CSS tree @@ -242,6 +251,7 @@ async function loadV4( // v4.0.0-alpha.25+ loadModule: createLoader({ legacy: false, + jiti, filepath: entryPoint, onError: (id, err, resourceType) => { console.error(`Unable to load ${resourceType}: ${id}`, err) @@ -266,6 +276,7 @@ async function loadV4( // v4.0.0-alpha.24 and below loadPlugin: createLoader({ legacy: true, + jiti, filepath: entryPoint, onError(id, err) { console.error(`Unable to load plugin: ${id}`, err) @@ -276,6 +287,7 @@ async function loadV4( loadConfig: createLoader({ legacy: true, + jiti, filepath: entryPoint, onError(id, err) { console.error(`Unable to load config: ${id}`, err) diff --git a/tests/fixtures.test.ts b/tests/fixtures.test.ts index e6d6582..82fdd24 100644 --- a/tests/fixtures.test.ts +++ b/tests/fixtures.test.ts @@ -70,7 +70,7 @@ let fixtures = [ }, { name: 'v4: configs and plugins', - dir: 'v4/configs', + dir: 'v4/css-loading-js', ext: 'html', }, ] diff --git a/tests/fixtures/v4/basic/package-lock.json b/tests/fixtures/v4/basic/package-lock.json index 9c8e2d7..1d19184 100644 --- a/tests/fixtures/v4/basic/package-lock.json +++ b/tests/fixtures/v4/basic/package-lock.json @@ -5,13 +5,14 @@ "packages": { "": { "dependencies": { - "tailwindcss": "^4.0.0-alpha.34" + "tailwindcss": "^4.0.0" } }, "node_modules/tailwindcss": { - "version": "4.0.0-alpha.34", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.0-alpha.34.tgz", - "integrity": "sha512-SST1h774z+bVCLTpRz4TYpjJLIcomZH1HBF4OPY1YusONUYqg0/XTq0N++12mNeyu6mK7VbFIkkNtf636yudWQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.0.tgz", + "integrity": "sha512-ULRPI3A+e39T7pSaf1xoi58AqqJxVCLg8F/uM5A3FadUbnyDTgltVnXJvdkTjwCOGA6NazqHVcwPJC5h2vRYVQ==", + "license": "MIT" } } } diff --git a/tests/fixtures/v4/basic/package.json b/tests/fixtures/v4/basic/package.json index 9c56072..fd0174c 100644 --- a/tests/fixtures/v4/basic/package.json +++ b/tests/fixtures/v4/basic/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "tailwindcss": "^4.0.0-alpha.34" + "tailwindcss": "^4.0.0" }, "prettier": { "tailwindStylesheet": "./app.css" diff --git a/tests/fixtures/v4/configs/app.css b/tests/fixtures/v4/configs/app.css deleted file mode 100644 index bd6458d..0000000 --- a/tests/fixtures/v4/configs/app.css +++ /dev/null @@ -1,8 +0,0 @@ -@import "tailwindcss"; - -@config "./tailwind.config.mjs"; -@plugin "./my-plugin.mjs"; - -@theme { - --color-tomato: tomato; -} diff --git a/tests/fixtures/v4/configs/index.html b/tests/fixtures/v4/configs/index.html deleted file mode 100644 index 296b7d7..0000000 --- a/tests/fixtures/v4/configs/index.html +++ /dev/null @@ -1,3 +0,0 @@ -
diff --git a/tests/fixtures/v4/configs/my-plugin.mjs b/tests/fixtures/v4/configs/my-plugin.mjs deleted file mode 100644 index bbbd63d..0000000 --- a/tests/fixtures/v4/configs/my-plugin.mjs +++ /dev/null @@ -1,13 +0,0 @@ -import plugin from 'tailwindcss/plugin' - -export default plugin(function ({ addUtilities }) { - addUtilities({ - '.from-plugin-1': { - width: '100%', - }, - '.from-plugin-2': { - color: 'red', - margin: '2rem', - }, - }) -}) diff --git a/tests/fixtures/v4/configs/output.html b/tests/fixtures/v4/configs/output.html deleted file mode 100644 index 6b4aae0..0000000 --- a/tests/fixtures/v4/configs/output.html +++ /dev/null @@ -1,3 +0,0 @@ -
diff --git a/tests/fixtures/v4/configs/package-lock.json b/tests/fixtures/v4/configs/package-lock.json deleted file mode 100644 index d71d14b..0000000 --- a/tests/fixtures/v4/configs/package-lock.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "configs", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "dependencies": { - "tailwindcss": "^4.0.0-alpha.34" - } - }, - "node_modules/tailwindcss": { - "version": "4.0.0-alpha.34", - "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.0-alpha.34.tgz", - "integrity": "sha512-SST1h774z+bVCLTpRz4TYpjJLIcomZH1HBF4OPY1YusONUYqg0/XTq0N++12mNeyu6mK7VbFIkkNtf636yudWQ==" - } - } -} diff --git a/tests/fixtures/v4/css-loading-js/app.css b/tests/fixtures/v4/css-loading-js/app.css new file mode 100644 index 0000000..a99a8e3 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/app.css @@ -0,0 +1,21 @@ +@import 'tailwindcss'; + +/* Load ESM versions */ +@config './esm/my-config.mjs'; +@plugin './esm/my-plugin.mjs'; + +/* Load Common JS versions */ +@config './cjs/my-config.cjs'; +@plugin './cjs/my-plugin.cjs'; + +/* Load TypeScript versions */ +@config './ts/my-config.ts'; +@plugin './ts/my-plugin.ts'; + +/* Attempt to load files that do not exist */ +@config './missing-confg.mjs'; +@plugin './missing-plugin.mjs'; + +@theme { + --color-tomato: tomato; +} diff --git a/tests/fixtures/v4/css-loading-js/cjs/my-config.cjs b/tests/fixtures/v4/css-loading-js/cjs/my-config.cjs new file mode 100644 index 0000000..9d2eec3 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/cjs/my-config.cjs @@ -0,0 +1,9 @@ +module.exports = { + theme: { + extend: { + colors: { + 'cjs-from-config': 'black', + }, + }, + }, +} diff --git a/tests/fixtures/v4/css-loading-js/cjs/my-plugin.cjs b/tests/fixtures/v4/css-loading-js/cjs/my-plugin.cjs new file mode 100644 index 0000000..4d234ad --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/cjs/my-plugin.cjs @@ -0,0 +1,24 @@ +const plugin = require('tailwindcss/plugin') + +module.exports = plugin( + ({ addUtilities }) => { + addUtilities({ + '.utility-cjs-from-plugin': { + color: 'black' + }, + '.utility-cjs-from-plugin-2': { + width: '100%', + height: '100%', + }, + }) + }, + { + theme: { + extend: { + colors: { + 'cjs-from-plugin': 'black', + }, + }, + }, + }, +) diff --git a/tests/fixtures/v4/configs/tailwind.config.mjs b/tests/fixtures/v4/css-loading-js/esm/my-config.mjs similarity index 67% rename from tests/fixtures/v4/configs/tailwind.config.mjs rename to tests/fixtures/v4/css-loading-js/esm/my-config.mjs index 9c3cfa7..0862924 100644 --- a/tests/fixtures/v4/configs/tailwind.config.mjs +++ b/tests/fixtures/v4/css-loading-js/esm/my-config.mjs @@ -2,8 +2,8 @@ export default { theme: { extend: { colors: { - "from-config": "#3490dc", + 'esm-from-config': 'black', }, }, }, -}; +} diff --git a/tests/fixtures/v4/css-loading-js/esm/my-plugin.mjs b/tests/fixtures/v4/css-loading-js/esm/my-plugin.mjs new file mode 100644 index 0000000..dd17b16 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/esm/my-plugin.mjs @@ -0,0 +1,24 @@ +import plugin from 'tailwindcss/plugin' + +export default plugin( + ({ addUtilities }) => { + addUtilities({ + '.utility-esm-from-plugin': { + color: 'black' + }, + '.utility-esm-from-plugin-2': { + width: '100%', + height: '100%', + }, + }) + }, + { + theme: { + extend: { + colors: { + 'esm-from-plugin': 'black', + }, + }, + }, + }, +) diff --git a/tests/fixtures/v4/css-loading-js/index.html b/tests/fixtures/v4/css-loading-js/index.html new file mode 100644 index 0000000..ac9e9b3 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/index.html @@ -0,0 +1,3 @@ +
diff --git a/tests/fixtures/v4/css-loading-js/output.html b/tests/fixtures/v4/css-loading-js/output.html new file mode 100644 index 0000000..8634fdb --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/output.html @@ -0,0 +1,3 @@ +
diff --git a/tests/fixtures/v4/css-loading-js/package-lock.json b/tests/fixtures/v4/css-loading-js/package-lock.json new file mode 100644 index 0000000..6060186 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/package-lock.json @@ -0,0 +1,18 @@ +{ + "name": "css-loading-js", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "tailwindcss": "^4.0.0" + } + }, + "node_modules/tailwindcss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.0.0.tgz", + "integrity": "sha512-ULRPI3A+e39T7pSaf1xoi58AqqJxVCLg8F/uM5A3FadUbnyDTgltVnXJvdkTjwCOGA6NazqHVcwPJC5h2vRYVQ==", + "license": "MIT" + } + } +} diff --git a/tests/fixtures/v4/configs/package.json b/tests/fixtures/v4/css-loading-js/package.json similarity index 70% rename from tests/fixtures/v4/configs/package.json rename to tests/fixtures/v4/css-loading-js/package.json index 9c56072..fd0174c 100644 --- a/tests/fixtures/v4/configs/package.json +++ b/tests/fixtures/v4/css-loading-js/package.json @@ -1,6 +1,6 @@ { "dependencies": { - "tailwindcss": "^4.0.0-alpha.34" + "tailwindcss": "^4.0.0" }, "prettier": { "tailwindStylesheet": "./app.css" diff --git a/tests/fixtures/v4/css-loading-js/ts/my-config.ts b/tests/fixtures/v4/css-loading-js/ts/my-config.ts new file mode 100644 index 0000000..a726229 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/ts/my-config.ts @@ -0,0 +1,11 @@ +import type { Config } from 'tailwindcss' + +export default { + theme: { + extend: { + colors: { + 'ts-from-config': 'black', + }, + }, + }, +} satisfies Config diff --git a/tests/fixtures/v4/css-loading-js/ts/my-plugin.ts b/tests/fixtures/v4/css-loading-js/ts/my-plugin.ts new file mode 100644 index 0000000..40b89a9 --- /dev/null +++ b/tests/fixtures/v4/css-loading-js/ts/my-plugin.ts @@ -0,0 +1,24 @@ +import plugin from 'tailwindcss/plugin' + +export default plugin( + ({ addUtilities }) => { + addUtilities({ + '.utility-ts-from-plugin': { + color: 'black' + }, + '.utility-ts-from-plugin-2': { + width: '100%', + height: '100%', + }, + }) + }, + { + theme: { + extend: { + colors: { + 'ts-from-plugin': 'black', + }, + }, + }, + }, +)