Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- Make JS APIs available to plugins and configs in the Standalone CLI ([#15934](https://github.com/tailwindlabs/tailwindcss/pull/15934))
- Vite: Don't crash when importing a virtual module in JavaScript that ends in `.css` ([#16780](https://github.com/tailwindlabs/tailwindcss/pull/16780))

## [4.0.8] - 2025-02-21
Expand Down
109 changes: 108 additions & 1 deletion integrations/cli/standalone.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os from 'node:os'
import path from 'node:path'
import { candidate, css, html, json, test } from '../utils'
import { candidate, css, html, js, json, test } from '../utils'

const STANDALONE_BINARY = (() => {
switch (os.platform()) {
Expand Down Expand Up @@ -56,3 +56,110 @@ test(
])
},
)

test(
'includes js APIs for plugins',
{
fs: {
'package.json': json`
{
"dependencies": {}
}
`,
'index.html': html`
<div class="underline example1 example2 example3"></div>
`,
'src/index.css': css`
@import 'tailwindcss/theme' theme(reference);
@import 'tailwindcss/utilities';
@plugin './plugin.js';
@plugin './plugin.cjs';
@plugin './plugin.ts';
`,
'src/plugin.js': js`
import plugin from 'tailwindcss/plugin'

// Make sure all available JS APIs can be imported and used
import * as tw from 'tailwindcss'
import colors from 'tailwindcss/colors'
import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette'
import defaultTheme from 'tailwindcss/defaultTheme'
import * as pkg from 'tailwindcss/package.json'

export default plugin(function ({ addUtilities }) {
addUtilities({
'.example1': {
'--version': pkg.version,
'--default-theme': typeof defaultTheme,
'--flatten-color-palette': typeof flattenColorPalette,
'--colors': typeof colors,
'--core': typeof tw,
color: 'red',
},
})
})
`,
'src/plugin.cjs': js`
const plugin = require('tailwindcss/plugin')

// Make sure all available JS APIs can be imported and used
const tw = require('tailwindcss')
const colors = require('tailwindcss/colors')
const flattenColorPalette = require('tailwindcss/lib/util/flattenColorPalette')
const defaultTheme = require('tailwindcss/defaultTheme')
const pkg = require('tailwindcss/package.json')

module.exports = plugin(function ({ addUtilities }) {
addUtilities({
'.example2': {
'--version': pkg.version,
'--default-theme': typeof defaultTheme,
'--flatten-color-palette': typeof flattenColorPalette,
'--colors': typeof colors,
'--core': typeof tw,
color: 'red',
},
})
})
`,
'src/plugin.ts': js`
import plugin from 'tailwindcss/plugin'

// Make sure all available JS APIs can be imported and used
import * as tw from 'tailwindcss'
import colors from 'tailwindcss/colors'
import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette'
import defaultTheme from 'tailwindcss/defaultTheme'
import * as pkg from 'tailwindcss/package.json'

export interface PluginOptions {
}

export default plugin(function ({ addUtilities }) {
addUtilities({
'.example3': {
'--version': pkg.version,
'--default-theme': typeof defaultTheme,
'--flatten-color-palette': typeof flattenColorPalette,
'--colors': typeof colors,
'--core': typeof tw,
color: 'red',
},
})
})
`,
},
},
async ({ fs, exec }) => {
await exec(
`${path.resolve(__dirname, `../../packages/@tailwindcss-standalone/dist/${STANDALONE_BINARY}`)} --input src/index.css --output dist/out.css`,
)

await fs.expectFileToContain('dist/out.css', [
candidate`underline`,
candidate`example1`,
candidate` example2`,
candidate`example3`,
])
},
)
4 changes: 2 additions & 2 deletions packages/@tailwindcss-standalone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
"@parcel/watcher-linux-x64-glibc": "^2.5.1",
"@parcel/watcher-linux-x64-musl": "^2.5.1",
"@parcel/watcher-win32-x64": "^2.5.1",
"@types/bun": "^1.2.2",
"bun": "1.1.43",
"@types/bun": "^1.2.3",
"bun": "^1.2.3",
"lightningcss-darwin-arm64": "^1.29.1",
"lightningcss-darwin-x64": "^1.29.1",
"lightningcss-linux-arm64-gnu": "^1.29.1",
Expand Down
36 changes: 36 additions & 0 deletions packages/@tailwindcss-standalone/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,4 +71,40 @@ globalThis.__tw_readFile = async (path, encoding) => {
return fs.readFileSync(path, encoding)
}

// We use a plugin to make sure that the JS APIs are bundled with the standalone
// CLI and can be imported inside configs and plugins
Bun.plugin({
name: 'bundle-tailwindcss-apis',
target: 'bun',
async setup(build) {
// These imports must be static strings otherwise they won't be bundled
let bundled = {
tailwindcss: await import('tailwindcss'),
'tailwindcss/colors': await import('tailwindcss/colors'),
'tailwindcss/colors.js': await import('tailwindcss/colors'),
'tailwindcss/plugin': await import('tailwindcss/plugin'),
'tailwindcss/plugin.js': await import('tailwindcss/plugin'),
'tailwindcss/package.json': await import('tailwindcss/package.json'),
'tailwindcss/lib/util/flattenColorPalette': await import(
'tailwindcss/lib/util/flattenColorPalette'
),
'tailwindcss/lib/util/flattenColorPalette.js': await import(
'tailwindcss/lib/util/flattenColorPalette'
),
'tailwindcss/defaultTheme': await import('tailwindcss/defaultTheme'),
'tailwindcss/defaultTheme.js': await import('tailwindcss/defaultTheme'),
}

for (let [id, exports] of Object.entries(bundled)) {
build.module(id, () => ({
loader: 'object',
exports: {
...exports,
__esModule: true,
},
}))
}
},
})

await import('../../@tailwindcss-cli/src/index.ts')
2 changes: 1 addition & 1 deletion playgrounds/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"devDependencies": {
"@types/react": "^19.0.10",
"@types/react-dom": "^19.0.4",
"bun": "^1.1.29",
"bun": "^1.2.3",
"vite": "catalog:"
}
}
Loading
Loading