123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import { css } from './util/run'
- const fs = require('fs')
- const path = require('path')
- const postcss = require('postcss')
- const tailwind = require('../src/index.js')
- const sharedState = require('../src/lib/sharedState.js')
- const configPath = path.resolve(__dirname, './context-reuse.tailwind.config.js')
- function run(input, config = {}, from = null) {
- let { currentTestName } = expect.getState()
- from = `${path.resolve(__filename)}?test=${currentTestName}&${from}`
- return postcss(tailwind(config)).process(input, { from })
- }
- beforeEach(async () => {
- let config = {
- content: [path.resolve(__dirname, './context-reuse.test.html')],
- corePlugins: { preflight: false },
- }
- await fs.promises.writeFile(configPath, `module.exports = ${JSON.stringify(config)};`)
- })
- afterEach(async () => {
- await fs.promises.unlink(configPath)
- })
- test('re-uses the context across multiple files with the same config', async () => {
- let results = [
- await run(`@tailwind utilities;`, configPath, `id=1`),
- // Using @apply directives should still re-use the context
- // They depend on the config but do not the other way around
- await run(`body { @apply bg-blue-400; }`, configPath, `id=2`),
- await run(`body { @apply text-red-400; }`, configPath, `id=3`),
- await run(`body { @apply mb-4; }`, configPath, `id=4`),
- ]
- let dependencies = results.map((result) => {
- return result.messages
- .filter((message) => message.type === 'dependency')
- .map((message) => message.file)
- })
- // The content files don't have any utilities in them so this should be empty
- expect(results[0].css).toMatchFormattedCss(css``)
- // However, @apply is being used so we want to verify that they're being inlined into the CSS rules
- expect(results[1].css).toMatchFormattedCss(css`
- body {
- --tw-bg-opacity: 1;
- background-color: rgb(96 165 250 / var(--tw-bg-opacity));
- }
- `)
- expect(results[2].css).toMatchFormattedCss(css`
- body {
- --tw-text-opacity: 1;
- color: rgb(248 113 113 / var(--tw-text-opacity));
- }
- `)
- expect(results[3].css).toMatchFormattedCss(css`
- body {
- margin-bottom: 1rem;
- }
- `)
- // Files with @tailwind directives depends on the PostCSS tree, config, AND any content files
- expect(dependencies[0]).toEqual([
- path.resolve(__dirname, 'context-reuse.test.html'),
- path.resolve(__dirname, 'context-reuse.tailwind.config.js'),
- ])
- // @apply depends only on the containing PostCSS tree *and* the config file but no content files
- // as they cannot affect the outcome of the @apply directives
- expect(dependencies[1]).toEqual([path.resolve(__dirname, 'context-reuse.tailwind.config.js')])
- expect(dependencies[2]).toEqual([path.resolve(__dirname, 'context-reuse.tailwind.config.js')])
- expect(dependencies[3]).toEqual([path.resolve(__dirname, 'context-reuse.tailwind.config.js')])
- // And none of this should have resulted in multiple contexts being created
- expect(sharedState.contextSourcesMap.size).toBe(1)
- })
- test('updates layers when any CSS containing @tailwind directives changes', async () => {
- let result
- // Compile the initial version once
- let input = css`
- @tailwind utilities;
- @layer utilities {
- .custom-utility {
- color: orange;
- }
- }
- `
- result = await run(input, configPath, `id=1`)
- expect(result.css).toMatchFormattedCss(css`
- .only\:custom-utility:only-child {
- color: orange;
- }
- `)
- // Save the file with a change
- input = css`
- @tailwind utilities;
- @layer utilities {
- .custom-utility {
- color: blue;
- }
- }
- `
- result = await run(input, configPath, `id=1`)
- expect(result.css).toMatchFormattedCss(css`
- .only\:custom-utility:only-child {
- color: #00f;
- }
- `)
- })
|