CodeSampleX

示例

tailwindcss 4.3.3: Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export

已验证示例 — npm tailwindcss 4.3.3: Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build…

sha256:7e8fea6fcad1e429a66c2ec7cabadab555fed65be50225e20dee895a0a8de843

本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。 提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。 MIT-0

执行证据

声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。

证据依据
签名契约通过
验证回执
3
构建过它的签名密钥
3
声明的环境 node linux x64 node node npm

验证运行环境

环境 契约 阶段 运行日期
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-16
node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18
node 22 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1node:22-alpine@sha256:c610fcdfb1d5…
2026-09-08

案例

HOW
目标
Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export
包
符号
  • tailwindcss
  • compile
  • loadStylesheet
  • loadModule
  • build
  • default
环境
node
创建时间
2026-08-16T07:54:12Z

契约

  1. assert default export throws when invoked as PostCSS plugin directing callers to @tailwindcss/postcss
  2. assert compile rejects when @import is used without providing loadStylesheet
  3. assert compile rejects when @plugin is used without providing loadModule
  4. assert compile returns compiler object with sync build method after resolving stylesheets and plugins
  5. assert compiler.build emits CSS rules matching candidate list and resolves @theme variables and @utility rules
  6. assert compiler.build ignores invalid and unreferenced candidates without error

文件

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • test/contract.mjs

下载源代码构件 (tar.gz)

源代码

NOTES.md
# Notes: tailwindcss v4 Programmatic API & Default Export Trap

## search_known_solution Response
`search_known_solution` found sample `sha256:52605f9f976b90b774ec86bcad38e5a02628014fd02d62a8b0b8937afdd907fc` ("Generate CSS with tailwind v4, which replaced tailwind.config.js with CSS-first config" demonstrating `@tailwindcss/postcss` integration with PostCSS). This sample addresses the core `tailwindcss` package's programmatic JS compilation API (`compile`, `loadStylesheet`, `loadModule`, `compiler.build`) and its default export trap.

## What a Model Would Have Written Instead
A model expecting Tailwind CSS v3 conventions reaches for `import tailwindcss from 'tailwindcss'` and invokes it as a PostCSS plugin (`tailwindcss(config)`), or attempts programmatic compilation via `await compile(css)` expecting automatic filesystem resolution or a direct CSS string return value.

## How the Wrong Version Fails
Loudly at runtime: calling the default export throws `Error: It looks like you're trying to use 'tailwindcss' directly as a PostCSS plugin...` because PostCSS integration moved to `@tailwindcss/postcss`, and calling `compile()` with `@import` or `@plugin` without custom `loadStylesheet` / `loadModule` callbacks throws `Error: No 'loadStylesheet' function provided to 'compile'` or `Error: No 'loadModule' function provided to 'compile'` as the v4 compiler is decoupled from filesystem I/O.
csx.json
{"case":{"caseId":"case:sha256:ee1aaf2f33c7f0b23b36e6f947131a3b86bddbd20c8d01a03c0116fb25c96b2a","contract":["assert default export throws when invoked as PostCSS plugin directing callers to @tailwindcss/postcss","assert compile rejects when @import is used without providing loadStylesheet","assert compile rejects when @plugin is used without providing loadModule","assert compile returns compiler object with sync build method after resolving stylesheets and plugins","assert compiler.build emits CSS rules matching candidate list and resolves @theme variables and @utility rules","assert compiler.build ignores invalid and unreferenced candidates without error"],"goal":"Compile CSS programmatically with tailwindcss v4 using compile, loadStylesheet, loadModule, and synchronous compiler.build instead of invoking default export","kind":"HOW","packages":["pkg:npm/tailwindcss@4.3.3"],"schemaVersion":1,"symbols":["tailwindcss","compile","loadStylesheet","loadModule","build","default"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/tailwindcss@4.3.3"],"schemaVersion":1,"symbols":["tailwindcss","compile","loadStylesheet","loadModule","build","default"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "npm-tailwindcss-api",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "npm-tailwindcss-api",
      "version": "1.0.0",
      "license": "MIT-0",
      "dependencies": {
        "tailwindcss": "4.3.3"
      }
    },
    "node_modules/tailwindcss": {
      "version": "4.3.3",
      "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.3.3.tgz",
      "integrity": "sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==",
      "license": "MIT"
    }
  }
}
package.json
{
  "name": "npm-tailwindcss-api",
  "version": "1.0.0",
  "private": true,
  "type": "module",
  "license": "MIT-0",
  "dependencies": {
    "tailwindcss": "4.3.3"
  }
}
test/contract.mjs
import { strict as assert } from 'node:assert';
import fs from 'node:fs/promises';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import tailwindDefault, { compile } from 'tailwindcss';
import plugin from 'tailwindcss/plugin';

// 1. Assert default export throws when invoked as PostCSS plugin
assert.strictEqual(typeof tailwindDefault, 'function', 'default export should be a function');
assert.throws(
  () => {
    tailwindDefault();
  },
  {
    name: 'Error',
    message: /PostCSS plugin has moved to a separate package.*@tailwindcss\/postcss/,
  },
  'calling tailwindcss default export must throw PostCSS plugin deprecation error'
);

// 2. Assert compile throws when @import is present without loadStylesheet
await assert.rejects(
  async () => {
    await compile('@import "tailwindcss";', { base: process.cwd() });
  },
  {
    name: 'Error',
    message: /No `loadStylesheet` function provided to `compile`/,
  },
  'compile must reject with missing loadStylesheet error when @import is used without loader'
);

// 3. Assert compile throws when @plugin is present without loadModule
const tailwindPkgDir = path.dirname(fileURLToPath(import.meta.resolve('tailwindcss/package.json')));
async function mockLoadStylesheet(id, base) {
  if (id === 'tailwindcss' || id === 'tailwindcss/index.css') {
    const cssPath = path.join(tailwindPkgDir, 'index.css');
    const content = await fs.readFile(cssPath, 'utf8');
    return { path: cssPath, base: tailwindPkgDir, content };
  }
  const resolved = path.resolve(base, id);
  const content = await fs.readFile(resolved, 'utf8');
  return { path: resolved, base: path.dirname(resolved), content };
}

await assert.rejects(
  async () => {
    await compile('@import "tailwindcss";\n@plugin "custom-plugin";', {
      base: process.cwd(),
      loadStylesheet: mockLoadStylesheet,
    });
  },
  {
    name: 'Error',
    message: /No `loadModule` function provided to `compile`/,
  },
  'compile must reject with missing loadModule error when @plugin is used without loader'
);

// 4. Set up custom plugin and compile with both loadStylesheet and loadModule
const customPlugin = plugin(function ({ addUtilities }) {
  addUtilities({
    '.skew-15': {
      transform: 'skewY(15deg)',
    },
  });
});

async function mockLoadModule(id, base, resourceHint) {
  if (id === 'custom-plugin') {
    return {
      path: 'virtual:custom-plugin',
      base,
      module: customPlugin,
    };
  }
  throw new Error(`Unknown module: ${id}`);
}

const inputCss = `
@import "tailwindcss";
@plugin "custom-plugin";
@theme {
  --color-accent: #e11d48;
}
@utility btn-primary {
  background-color: var(--color-accent);
  padding: 0.5rem 1rem;
}
`;

const compiler = await compile(inputCss, {
  base: process.cwd(),
  loadStylesheet: mockLoadStylesheet,
  loadModule: mockLoadModule,
});

// Assert shape of returned compiler object
assert.strictEqual(typeof compiler, 'object', 'compile must resolve to compiler object');
assert.strictEqual(typeof compiler.build, 'function', 'compiler must expose a build function');
assert.ok(Array.isArray(compiler.sources), 'compiler must expose sources array');

// 5. Assert compiler.build generates CSS for requested candidates and custom definitions
const candidates = [
  'btn-primary',
  'skew-15',
  'hover:skew-15',
  'text-accent',
  'p-4',
  'opacity-50',
  'nonexistent-helper-class',
];

const outputCss = compiler.build(candidates);
assert.strictEqual(typeof outputCss, 'string', 'build must return a CSS string synchronously');

// Assert custom utility and theme variables are emitted
assert.ok(outputCss.includes('.btn-primary'), 'emits .btn-primary utility class');
assert.ok(outputCss.includes('--color-accent: #e11d48') || outputCss.includes('#e11d48'), 'emits @theme token definition');
assert.ok(outputCss.includes('var(--color-accent)'), 'btn-primary references theme custom property');

// Assert plugin utility and variant are emitted
assert.ok(outputCss.includes('skewY(15deg)'), 'emits skew-15 transform from JS plugin');
assert.ok(outputCss.includes('.hover\\:skew-15:hover'), 'emits hover variant for plugin utility');

// Assert standard utility classes are emitted
assert.ok(outputCss.includes('.text-accent'), 'emits text-accent color utility');
assert.ok(outputCss.includes('.p-4'), 'emits p-4 padding utility');
assert.ok(outputCss.includes('.opacity-50'), 'emits opacity-50 utility');

// 6. Assert unrequested/unscanned utilities and invalid candidates are NOT emitted
assert.ok(!outputCss.includes('nonexistent-helper-class'), 'ignores invalid candidates');
assert.ok(!outputCss.includes('.m-8'), 'does not emit unrequested m-8 utility');
assert.ok(!outputCss.includes('.rotate-45'), 'does not emit unrequested rotate-45 utility');

console.log('CONTRACT PASS: tailwindcss programmatic API behaves as specified');

原始种子者

csx-seed