|  | 
|  | 1 | +import { describe, expect } from 'vitest' | 
|  | 2 | +import { css, fetchStyles, html, retryAssertion, test, ts, txt } from '../utils' | 
|  | 3 | + | 
|  | 4 | +function createSetup(transformer: 'postcss' | 'lightningcss') { | 
|  | 5 | +  return { | 
|  | 6 | +    fs: { | 
|  | 7 | +      'package.json': txt` | 
|  | 8 | +        { | 
|  | 9 | +          "type": "module", | 
|  | 10 | +          "dependencies": { | 
|  | 11 | +            "@tailwindcss/vite": "workspace:^", | 
|  | 12 | +            "tailwindcss": "workspace:^" | 
|  | 13 | +          }, | 
|  | 14 | +          "devDependencies": { | 
|  | 15 | +            ${transformer === 'lightningcss' ? `"lightningcss": "^1.26.0",` : ''} | 
|  | 16 | +            "vite": "^5.3.5" | 
|  | 17 | +          } | 
|  | 18 | +        } | 
|  | 19 | +      `, | 
|  | 20 | +      'vite.config.ts': ts` | 
|  | 21 | +        import tailwindcss from '@tailwindcss/vite' | 
|  | 22 | +        import { defineConfig } from 'vite' | 
|  | 23 | +
 | 
|  | 24 | +        export default defineConfig({ | 
|  | 25 | +          css: ${transformer === 'postcss' ? '{}' : "{ transformer: 'lightningcss' }"}, | 
|  | 26 | +          build: { cssMinify: false }, | 
|  | 27 | +          plugins: [ | 
|  | 28 | +            tailwindcss(), | 
|  | 29 | +            { | 
|  | 30 | +              name: 'recolor', | 
|  | 31 | +              transform(code, id) { | 
|  | 32 | +                if (id.includes('.css')) { | 
|  | 33 | +                  return code.replace(/red/g, 'blue') | 
|  | 34 | +                } | 
|  | 35 | +              }, | 
|  | 36 | +            }, | 
|  | 37 | +          ], | 
|  | 38 | +        }) | 
|  | 39 | +      `, | 
|  | 40 | +      'index.html': html` | 
|  | 41 | +        <head> | 
|  | 42 | +          <link rel="stylesheet" href="./src/index.css" /> | 
|  | 43 | +        </head> | 
|  | 44 | +        <body> | 
|  | 45 | +          <div class="foo">Hello, world!</div> | 
|  | 46 | +        </body> | 
|  | 47 | +      `, | 
|  | 48 | +      'src/index.css': css` | 
|  | 49 | +        @import 'tailwindcss/theme' theme(reference); | 
|  | 50 | +        @import 'tailwindcss/utilities'; | 
|  | 51 | +
 | 
|  | 52 | +        .foo { | 
|  | 53 | +          color: red; | 
|  | 54 | +        } | 
|  | 55 | +      `, | 
|  | 56 | +    }, | 
|  | 57 | +  } | 
|  | 58 | +} | 
|  | 59 | + | 
|  | 60 | +for (let transformer of ['postcss', 'lightningcss'] as const) { | 
|  | 61 | +  describe(transformer, () => { | 
|  | 62 | +    test(`production build`, createSetup(transformer), async ({ fs, exec }) => { | 
|  | 63 | +      await exec('pnpm vite build') | 
|  | 64 | + | 
|  | 65 | +      let files = await fs.glob('dist/**/*.css') | 
|  | 66 | +      expect(files).toHaveLength(1) | 
|  | 67 | +      let [filename] = files[0] | 
|  | 68 | + | 
|  | 69 | +      await fs.expectFileToContain(filename, [ | 
|  | 70 | +        css` | 
|  | 71 | +          .foo { | 
|  | 72 | +            color: blue; | 
|  | 73 | +          } | 
|  | 74 | +        `, | 
|  | 75 | +      ]) | 
|  | 76 | +    }) | 
|  | 77 | + | 
|  | 78 | +    test(`dev mode`, createSetup(transformer), async ({ spawn, getFreePort, fs }) => { | 
|  | 79 | +      let port = await getFreePort() | 
|  | 80 | +      await spawn(`pnpm vite dev --port ${port}`) | 
|  | 81 | + | 
|  | 82 | +      await retryAssertion(async () => { | 
|  | 83 | +        let styles = await fetchStyles(port, '/index.html') | 
|  | 84 | +        expect(styles).toContain(css` | 
|  | 85 | +          .foo { | 
|  | 86 | +            color: blue; | 
|  | 87 | +          } | 
|  | 88 | +        `) | 
|  | 89 | +      }) | 
|  | 90 | + | 
|  | 91 | +      await retryAssertion(async () => { | 
|  | 92 | +        await fs.write( | 
|  | 93 | +          'src/index.css', | 
|  | 94 | +          css` | 
|  | 95 | +            @import 'tailwindcss/theme' theme(reference); | 
|  | 96 | +            @import 'tailwindcss/utilities'; | 
|  | 97 | +
 | 
|  | 98 | +            .foo { | 
|  | 99 | +              background-color: red; | 
|  | 100 | +            } | 
|  | 101 | +          `, | 
|  | 102 | +        ) | 
|  | 103 | + | 
|  | 104 | +        let styles = await fetchStyles(port) | 
|  | 105 | +        expect(styles).toContain(css` | 
|  | 106 | +          .foo { | 
|  | 107 | +            background-color: blue; | 
|  | 108 | +          } | 
|  | 109 | +        `) | 
|  | 110 | +      }) | 
|  | 111 | +    }) | 
|  | 112 | + | 
|  | 113 | +    test('watch mode', createSetup(transformer), async ({ spawn, fs }) => { | 
|  | 114 | +      await spawn(`pnpm vite build --watch`) | 
|  | 115 | + | 
|  | 116 | +      await retryAssertion(async () => { | 
|  | 117 | +        let files = await fs.glob('dist/**/*.css') | 
|  | 118 | +        expect(files).toHaveLength(1) | 
|  | 119 | +        let [, styles] = files[0] | 
|  | 120 | + | 
|  | 121 | +        expect(styles).toContain(css` | 
|  | 122 | +          .foo { | 
|  | 123 | +            color: blue; | 
|  | 124 | +          } | 
|  | 125 | +        `) | 
|  | 126 | +      }) | 
|  | 127 | + | 
|  | 128 | +      await retryAssertion(async () => { | 
|  | 129 | +        await fs.write( | 
|  | 130 | +          'src/index.css', | 
|  | 131 | +          css` | 
|  | 132 | +            @import 'tailwindcss/theme' theme(reference); | 
|  | 133 | +            @import 'tailwindcss/utilities'; | 
|  | 134 | +
 | 
|  | 135 | +            .foo { | 
|  | 136 | +              background-color: red; | 
|  | 137 | +            } | 
|  | 138 | +          `, | 
|  | 139 | +        ) | 
|  | 140 | + | 
|  | 141 | +        let files = await fs.glob('dist/**/*.css') | 
|  | 142 | +        expect(files).toHaveLength(1) | 
|  | 143 | +        let [, styles] = files[0] | 
|  | 144 | + | 
|  | 145 | +        expect(styles).toContain(css` | 
|  | 146 | +          .foo { | 
|  | 147 | +            background-color: blue; | 
|  | 148 | +          } | 
|  | 149 | +        `) | 
|  | 150 | +      }) | 
|  | 151 | +    }) | 
|  | 152 | +  }) | 
|  | 153 | +} | 
0 commit comments