mirror of
https://github.com/vitejs/vite.git
synced 2024-11-21 14:48:41 +00:00
chore: port tests over
This port isn't the best. Vite builds are ran multiple times with different modules configuration. The ideal abstraction is to have unit tests instead and Vite should "trust" that it works, but this will do for now. I also skipped lightningcss tests for now. Check css-modules-lightningcss.spec.ts for notes.
This commit is contained in:
parent
0b13c294b6
commit
ece9f720fd
458
playground/css-modules/__tests__/css-modules.spec.ts
Normal file
458
playground/css-modules/__tests__/css-modules.spec.ts
Normal file
@ -0,0 +1,458 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import { describe, expect, test } from 'vitest'
|
||||||
|
import { type InlineConfig, type Rollup, build } from 'vite'
|
||||||
|
import { base64Module, isBuild, isServe, page } from '~utils'
|
||||||
|
|
||||||
|
async function getStyleMatchingId(id: string) {
|
||||||
|
const styleTags = page.locator(`style[data-vite-dev-id*=${id}]`)
|
||||||
|
let code = ''
|
||||||
|
for (const style of await styleTags.all()) {
|
||||||
|
code += await style.textContent()
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
async function viteBuild(root: string, inlineConfig?: InlineConfig) {
|
||||||
|
const built = await build({
|
||||||
|
root: path.resolve(__dirname, root),
|
||||||
|
configFile: false,
|
||||||
|
envFile: false,
|
||||||
|
logLevel: 'error',
|
||||||
|
...inlineConfig,
|
||||||
|
build: {
|
||||||
|
// Prevents CSS minification from handling the de-duplication of classes
|
||||||
|
minify: false,
|
||||||
|
write: false,
|
||||||
|
lib: {
|
||||||
|
entry: 'index.js',
|
||||||
|
formats: ['es'],
|
||||||
|
},
|
||||||
|
...inlineConfig?.build,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!Array.isArray(built)) {
|
||||||
|
throw new TypeError('Build result is not an array')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { output } = built[0]!
|
||||||
|
const css = output.find(
|
||||||
|
(file) => file.type === 'asset' && file.fileName.endsWith('.css'),
|
||||||
|
) as Rollup.OutputAsset | undefined
|
||||||
|
|
||||||
|
return {
|
||||||
|
js: output[0].code,
|
||||||
|
css: css?.source.toString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test.runIf(isBuild)('Multi CSS modules', async () => {
|
||||||
|
const { js, css } = await viteBuild('../multi-css-modules', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
generateScopedName: 'asdf_[local]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
className1: expect.stringMatching(/^asdf_className1\s+asdf_util-class$/),
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/^asdf_class-name2\s+asdf_util-class$/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(css).toMatch('--file: "style1.module.css"')
|
||||||
|
expect(css).toMatch('--file: "style2.module.css"')
|
||||||
|
|
||||||
|
// Ensure that PostCSS is applied to the composed files
|
||||||
|
expect(css).toMatch('--file: "utils1.css?.module.css"')
|
||||||
|
expect(css).toMatch('--file: "utils2.css?.module.css"')
|
||||||
|
|
||||||
|
// Util is not duplicated
|
||||||
|
const utilClass = Array.from(css!.matchAll(/foo/g))
|
||||||
|
expect(utilClass.length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
describe.runIf(isBuild)('localsConvention', () => {
|
||||||
|
test('camelCase', async () => {
|
||||||
|
const { js } = await viteBuild('../multi-css-modules', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: 'camelCase',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
default: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('camelCaseOnly', async () => {
|
||||||
|
const { js } = await viteBuild('../multi-css-modules', {
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: 'camelCaseOnly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
default: {
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dashes', async () => {
|
||||||
|
const { js } = await viteBuild('../multi-css-modules', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: 'dashes',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
default: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('dashesOnly', async () => {
|
||||||
|
const { js } = await viteBuild('../multi-css-modules', {
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: 'dashesOnly',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
default: {
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('function', async () => {
|
||||||
|
const { js } = await viteBuild('../multi-css-modules', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: (originalClassname) => `${originalClassname}123`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
className1123: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
'class-name2123': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1123: expect.stringMatching(
|
||||||
|
/_className1_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
'class-name2123': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
'class-name2123': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
'class-name2123': expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isBuild)('globalModulePaths', async () => {
|
||||||
|
const { js, css } = await viteBuild('../global-module', {
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
globalModulePaths: [/global\.module\.css/],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
default: {
|
||||||
|
title: expect.stringMatching(/^_title_\w{5}/),
|
||||||
|
},
|
||||||
|
title: expect.stringMatching(/^_title_\w{5}/),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(css).toMatch('.page {')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isBuild)('inline', async () => {
|
||||||
|
const { js } = await viteBuild('../inline-query')
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
|
||||||
|
expect(typeof exported.default).toBe('string')
|
||||||
|
expect(exported.default).toMatch('--file: "style.module.css?inline"')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isBuild)('getJSON', async () => {
|
||||||
|
type JSON = {
|
||||||
|
inputFile: string
|
||||||
|
exports: Record<string, string>
|
||||||
|
outputFile: string
|
||||||
|
}
|
||||||
|
const jsons: JSON[] = []
|
||||||
|
|
||||||
|
await viteBuild('../multi-css-modules', {
|
||||||
|
css: {
|
||||||
|
modules: {
|
||||||
|
localsConvention: 'camelCaseOnly',
|
||||||
|
getJSON: (inputFile, exports, outputFile) => {
|
||||||
|
jsons.push({
|
||||||
|
inputFile,
|
||||||
|
exports,
|
||||||
|
outputFile,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// This plugin treats each CSS Module as a JS module so it emits on each module
|
||||||
|
// rather than the final "bundle" which postcss-module emits on
|
||||||
|
expect(jsons).toHaveLength(4)
|
||||||
|
jsons.sort((a, b) => a.inputFile.localeCompare(b.inputFile))
|
||||||
|
|
||||||
|
const [style1, style2, utils1, utils2] = jsons
|
||||||
|
expect(style1).toMatchObject({
|
||||||
|
inputFile: expect.stringMatching(/style1\.module\.css$/),
|
||||||
|
exports: {
|
||||||
|
className1: expect.stringMatching(/_className1_\w+ _util-class_\w+/),
|
||||||
|
className2: expect.stringMatching(
|
||||||
|
/_class-name2_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
outputFile: expect.stringMatching(/style1\.module\.css$/),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(style2).toMatchObject({
|
||||||
|
inputFile: expect.stringMatching(/style2\.module\.css$/),
|
||||||
|
exports: {
|
||||||
|
className2: expect.stringMatching(/_class-name2_\w+ _util-class_\w+/),
|
||||||
|
},
|
||||||
|
outputFile: expect.stringMatching(/style2\.module\.css$/),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(utils1).toMatchObject({
|
||||||
|
inputFile: expect.stringMatching(/utils1\.css\?\.module\.css$/),
|
||||||
|
exports: {
|
||||||
|
unusedClass: expect.stringMatching(/_unused-class_\w+/),
|
||||||
|
utilClass: expect.stringMatching(/_util-class_\w+/),
|
||||||
|
},
|
||||||
|
outputFile: expect.stringMatching(/utils1\.css\?\.module\.css$/),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(utils2).toMatchObject({
|
||||||
|
inputFile: expect.stringMatching(/utils2\.css\?\.module\.css$/),
|
||||||
|
exports: {
|
||||||
|
utilClass: expect.stringMatching(/_util-class_\w+/),
|
||||||
|
},
|
||||||
|
outputFile: expect.stringMatching(/utils2\.css\?\.module\.css$/),
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isBuild)('Empty CSS Module', async () => {
|
||||||
|
const { js, css } = await viteBuild('../empty-css-module', {
|
||||||
|
css: {
|
||||||
|
postcss: {},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
default: {},
|
||||||
|
})
|
||||||
|
expect(css).toBeUndefined()
|
||||||
|
})
|
||||||
|
|
||||||
|
describe('@value', () => {
|
||||||
|
test.runIf(isBuild)('build', async () => {
|
||||||
|
const { js, css } = await viteBuild('../css-modules-value', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
default: {
|
||||||
|
'class-name1': expect.stringMatching(
|
||||||
|
/^_class-name1_\w+ _util-class_\w+ _util-class_\w+$/,
|
||||||
|
),
|
||||||
|
'class-name2': expect.stringMatching(/^_class-name2_\w+$/),
|
||||||
|
},
|
||||||
|
'class-name1': expect.stringMatching(
|
||||||
|
/_class-name1_\w+ _util-class_\w+ _util-class_\w+/,
|
||||||
|
),
|
||||||
|
'class-name2': expect.stringMatching(/^_class-name2_\w+$/),
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(css).toMatch('color: #fff')
|
||||||
|
expect(css).toMatch('border: #fff')
|
||||||
|
expect(css).toMatch('color: #000')
|
||||||
|
expect(css).toMatch('border: #000')
|
||||||
|
expect(css).toMatch('border: 1px solid black')
|
||||||
|
|
||||||
|
// Ensure that PostCSS is applied to the composed files
|
||||||
|
expect(css).toMatch('--file: "style.module.css"')
|
||||||
|
expect(css).toMatch('--file: "utils1.css?.module.css"')
|
||||||
|
expect(css).toMatch('--file: "utils2.css?.module.css"')
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isServe)('dev server', async () => {
|
||||||
|
const code = await getStyleMatchingId('css-modules-value')
|
||||||
|
|
||||||
|
expect(code).toMatch('color: #fff')
|
||||||
|
expect(code).toMatch('border: #fff')
|
||||||
|
expect(code).toMatch('color: #000')
|
||||||
|
expect(code).toMatch('border: #000')
|
||||||
|
expect(code).toMatch('border: 1px solid black')
|
||||||
|
|
||||||
|
// Ensure that PostCSS is applied to the composed files
|
||||||
|
expect(code).toMatch('--file: "style.module.css"')
|
||||||
|
expect(code).toMatch('--file: "utils1.css?.module.css"')
|
||||||
|
expect(code).toMatch('--file: "utils2.css?.module.css"')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe.runIf(isBuild)('error handling', () => {
|
||||||
|
test('missing class export', async () => {
|
||||||
|
await expect(() =>
|
||||||
|
viteBuild('../missing-class-export', {
|
||||||
|
logLevel: 'silent',
|
||||||
|
}),
|
||||||
|
).rejects.toThrow(
|
||||||
|
'[vite:css-modules] Cannot resolve "non-existent" from "./utils.css"',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('exporting a non-safe class name via esm doesnt throw', async () => {
|
||||||
|
await viteBuild('../module-namespace')
|
||||||
|
})
|
||||||
|
})
|
@ -0,0 +1,306 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import { describe, expect, test } from 'vitest'
|
||||||
|
import { type InlineConfig, type Rollup, build } from 'vite'
|
||||||
|
import { Features } from 'lightningcss'
|
||||||
|
import {
|
||||||
|
base64Module,
|
||||||
|
getCssSourceMaps,
|
||||||
|
isBuild,
|
||||||
|
isServe,
|
||||||
|
page,
|
||||||
|
viteTestUrl,
|
||||||
|
} from '~utils'
|
||||||
|
|
||||||
|
/*
|
||||||
|
Skipped most tests for now because:
|
||||||
|
1. For some reason, dev and build exports classes as `"l9uHSq_button": "l9uHSq_l9uHSq_button"` (double hash)
|
||||||
|
2. I don't undertstand how sourcemaps is being tested
|
||||||
|
3. The `vite-css-modules` implementation sidesteps the initial parsing to postcss, which we don't want when
|
||||||
|
using lightningcss. postcss should be completely not used.
|
||||||
|
*/
|
||||||
|
|
||||||
|
async function getStyleMatchingId(id: string) {
|
||||||
|
const styleTags = page.locator(`style[data-vite-dev-id*=${id}]`)
|
||||||
|
let code = ''
|
||||||
|
for (const style of await styleTags.all()) {
|
||||||
|
code += await style.textContent()
|
||||||
|
}
|
||||||
|
return code
|
||||||
|
}
|
||||||
|
|
||||||
|
async function viteBuild(root: string, inlineConfig?: InlineConfig) {
|
||||||
|
const built = await build({
|
||||||
|
root: path.resolve(__dirname, root),
|
||||||
|
configFile: false,
|
||||||
|
envFile: false,
|
||||||
|
logLevel: 'error',
|
||||||
|
...inlineConfig,
|
||||||
|
build: {
|
||||||
|
// Prevents CSS minification from handling the de-duplication of classes
|
||||||
|
minify: false,
|
||||||
|
write: false,
|
||||||
|
lib: {
|
||||||
|
entry: 'index.js',
|
||||||
|
formats: ['es'],
|
||||||
|
},
|
||||||
|
...inlineConfig?.build,
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
postcss: {},
|
||||||
|
...inlineConfig?.css,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!Array.isArray(built)) {
|
||||||
|
throw new TypeError('Build result is not an array')
|
||||||
|
}
|
||||||
|
|
||||||
|
const { output } = built[0]!
|
||||||
|
const css = output.find(
|
||||||
|
(file) => file.type === 'asset' && file.fileName.endsWith('.css'),
|
||||||
|
) as Rollup.OutputAsset | undefined
|
||||||
|
|
||||||
|
return {
|
||||||
|
js: output[0].code,
|
||||||
|
css: css?.source.toString(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
test.runIf(isBuild).skip('Configured', async () => {
|
||||||
|
const { js, css } = await viteBuild('../../multi-css-modules', {
|
||||||
|
css: {
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
className1: expect.stringMatching(
|
||||||
|
/^[\w-]+_className1\s+[\w-]+_util-class$/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
className1: expect.stringMatching(
|
||||||
|
/^[\w-]+_className1\s+[\w-]+_util-class$/,
|
||||||
|
),
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/^[\w-]+_class-name2\s+[\w-]+_util-class\s+[\w-]+_util-class$/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/^[\w-]+_class-name2\s+[\w-]+_util-class$/,
|
||||||
|
),
|
||||||
|
default: {
|
||||||
|
'class-name2': expect.stringMatching(
|
||||||
|
/^[\w-]+_class-name2\s+[\w-]+_util-class$/,
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Util is not duplicated
|
||||||
|
const utilClass = Array.from(css!.matchAll(/foo/g))
|
||||||
|
expect(utilClass.length).toBe(1)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isBuild).skip('Empty CSS Module', async () => {
|
||||||
|
const { js, css } = await viteBuild('../../empty-css-module', {
|
||||||
|
css: {
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
default: {},
|
||||||
|
})
|
||||||
|
expect(css).toBe('\n')
|
||||||
|
})
|
||||||
|
|
||||||
|
test('reserved keywords', async () => {
|
||||||
|
const { js } = await viteBuild('../../reserved-keywords', {
|
||||||
|
build: {
|
||||||
|
target: 'es2022',
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style: {
|
||||||
|
default: {
|
||||||
|
export: 'fk9XWG_export V_YH-W_with',
|
||||||
|
import: 'fk9XWG_import V_YH-W_if',
|
||||||
|
},
|
||||||
|
export: 'fk9XWG_export V_YH-W_with',
|
||||||
|
import: 'fk9XWG_import V_YH-W_if',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe.skip('Custom property dependencies', () => {
|
||||||
|
test.runIf(isBuild)('build', async () => {
|
||||||
|
const { js, css } = await viteBuild(
|
||||||
|
'../../lightningcss-custom-properties-from',
|
||||||
|
{
|
||||||
|
css: {
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
lightningcss: {
|
||||||
|
cssModules: {
|
||||||
|
dashedIdents: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log(js)
|
||||||
|
|
||||||
|
const exported = await import(base64Module(js))
|
||||||
|
expect(exported).toMatchObject({
|
||||||
|
style1: {
|
||||||
|
button: expect.stringMatching(/^[\w-]+_button$/),
|
||||||
|
},
|
||||||
|
style2: {
|
||||||
|
input: expect.stringMatching(/^[\w-]+input$/),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const variableNameMatches = Array.from(css!.matchAll(/(\S+): hotpink/g))!
|
||||||
|
expect(variableNameMatches.length).toBe(1)
|
||||||
|
|
||||||
|
const variableName = variableNameMatches[0]![1]
|
||||||
|
expect(css).toMatch(`color: var(${variableName})`)
|
||||||
|
expect(css).toMatch(`background: var(${variableName})`)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isServe)('serve', async () => {
|
||||||
|
await page.goto(viteTestUrl + '/lightningcss.html')
|
||||||
|
const code = await getStyleMatchingId('lightningcss-custom-properties-from')
|
||||||
|
|
||||||
|
const variableNameMatches = Array.from(code.matchAll(/(\S+): hotpink/g))!
|
||||||
|
expect(variableNameMatches.length).toBe(1)
|
||||||
|
|
||||||
|
const variableName = variableNameMatches[0]![1]
|
||||||
|
expect(code).toMatch(`color: var(${variableName})`)
|
||||||
|
expect(code).toMatch(`background: var(${variableName})`)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
describe.skip('Other configs', () => {
|
||||||
|
test.runIf(isBuild)('build', async () => {
|
||||||
|
const { css } = await viteBuild('../../lightningcss-features', {
|
||||||
|
css: {
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
lightningcss: {
|
||||||
|
include: Features.Nesting,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(css).toMatch(/\.[\w-]+_button\.[\w-]+_primary/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.runIf(isServe).skip('dev server', async () => {
|
||||||
|
await page.goto(viteTestUrl + '/lightningcss.html')
|
||||||
|
const code = await getStyleMatchingId('lightningcss-features')
|
||||||
|
|
||||||
|
const cssSourcemaps = getCssSourceMaps(code)
|
||||||
|
expect(cssSourcemaps.length).toBe(0)
|
||||||
|
|
||||||
|
expect(code).toMatch(/\.[\w-]+_button\.[\w-]+_primary/)
|
||||||
|
})
|
||||||
|
|
||||||
|
test.skip('devSourcemap', async () => {
|
||||||
|
const code = await getStyleMatchingId('lightningcss-custom-properties-from')
|
||||||
|
|
||||||
|
const cssSourcemaps = getCssSourceMaps(code)
|
||||||
|
expect(cssSourcemaps.length).toBe(3)
|
||||||
|
// I'm skeptical these source maps are correct
|
||||||
|
// Seems lightningCSS is providing these source maps
|
||||||
|
expect(cssSourcemaps).toMatchObject([
|
||||||
|
{
|
||||||
|
version: 3,
|
||||||
|
file: expect.stringMatching(/^style1\.module\.css$/),
|
||||||
|
mappings: 'AAAA',
|
||||||
|
names: [],
|
||||||
|
ignoreList: [],
|
||||||
|
sources: [expect.stringMatching(/^style1\.module\.css$/)],
|
||||||
|
sourcesContent: [
|
||||||
|
'.button {\n\tbackground: var(--accent-color from "./vars.module.css");\n}',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 3,
|
||||||
|
file: expect.stringMatching(/^style2\.module\.css$/),
|
||||||
|
mappings: 'AAAA',
|
||||||
|
names: [],
|
||||||
|
ignoreList: [],
|
||||||
|
sources: [expect.stringMatching(/^style2\.module\.css$/)],
|
||||||
|
sourcesContent: [
|
||||||
|
'.input {\n\tcolor: var(--accent-color from "./vars.module.css");\n}',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 3,
|
||||||
|
sourceRoot: null,
|
||||||
|
mappings: 'AAAA',
|
||||||
|
sources: [expect.stringMatching(/^vars\.module\.css$/)],
|
||||||
|
sourcesContent: [':root {\n\t--accent-color: hotpink;\n}'],
|
||||||
|
names: [],
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
|
||||||
|
test.skip('devSourcemap with Vue.js', async () => {
|
||||||
|
const code = await getStyleMatchingId('vue')
|
||||||
|
const cssSourcemaps = getCssSourceMaps(code)
|
||||||
|
expect(cssSourcemaps.length).toBe(2)
|
||||||
|
expect(cssSourcemaps).toMatchObject([
|
||||||
|
{
|
||||||
|
version: 3,
|
||||||
|
mappings: 'AAKA;;;;ACLA',
|
||||||
|
names: [],
|
||||||
|
sources: [expect.stringMatching(/\/comp\.vue$/), '\u0000<no source>'],
|
||||||
|
sourcesContent: [
|
||||||
|
'<template>\n' +
|
||||||
|
'\t<p :class="$style[\'css-module\']"><css> module</p>\n' +
|
||||||
|
'</template>\n' +
|
||||||
|
'\n' +
|
||||||
|
'<style module>\n' +
|
||||||
|
'.css-module {\n' +
|
||||||
|
"\tcomposes: util-class from './utils.css';\n" +
|
||||||
|
'\tcolor: red;\n' +
|
||||||
|
'}\n' +
|
||||||
|
'</style>',
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
file: expect.stringMatching(/\/comp\.vue$/),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 3,
|
||||||
|
mappings: 'AAAA;;;;;AAKA;;;;ACLA',
|
||||||
|
names: [],
|
||||||
|
sources: [expect.stringMatching(/\/utils\.css$/), '\u0000<no source>'],
|
||||||
|
sourcesContent: [
|
||||||
|
'.util-class {\n' +
|
||||||
|
"\t--name: 'foo';\n" +
|
||||||
|
'\tcolor: blue;\n' +
|
||||||
|
'}\n' +
|
||||||
|
'\n' +
|
||||||
|
'.unused-class {\n' +
|
||||||
|
'\tcolor: yellow;\n' +
|
||||||
|
'}',
|
||||||
|
null,
|
||||||
|
],
|
||||||
|
file: expect.stringMatching(/\/utils\.css$/),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
})
|
||||||
|
})
|
2
playground/css-modules/css-modules-value/index.js
Normal file
2
playground/css-modules/css-modules-value/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.css'
|
||||||
|
export { default } from './style.module.css'
|
12
playground/css-modules/css-modules-value/style.module.css
Normal file
12
playground/css-modules/css-modules-value/style.module.css
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
@value primary as p1, simple-border from './utils1.css';
|
||||||
|
@value primary as p2 from './utils2.css';
|
||||||
|
|
||||||
|
.class-name1 {
|
||||||
|
color: p1;
|
||||||
|
border: simple-border;
|
||||||
|
composes: util-class from './utils1.css';
|
||||||
|
composes: util-class from './utils2.css';
|
||||||
|
}
|
||||||
|
.class-name2 {
|
||||||
|
color: p2;
|
||||||
|
}
|
6
playground/css-modules/css-modules-value/utils1.css
Normal file
6
playground/css-modules/css-modules-value/utils1.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
@value primary: #fff;
|
||||||
|
@value simple-border: 1px solid black;
|
||||||
|
|
||||||
|
.util-class {
|
||||||
|
border: primary;
|
||||||
|
}
|
5
playground/css-modules/css-modules-value/utils2.css
Normal file
5
playground/css-modules/css-modules-value/utils2.css
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
@value primary: #000;
|
||||||
|
|
||||||
|
.util-class {
|
||||||
|
border: primary;
|
||||||
|
}
|
2
playground/css-modules/empty-css-module/index.js
Normal file
2
playground/css-modules/empty-css-module/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.css'
|
||||||
|
export { default } from './style.module.css'
|
6
playground/css-modules/global-module/global.module.css
Normal file
6
playground/css-modules/global-module/global.module.css
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
.page {
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
:local(.title) {
|
||||||
|
color: green;
|
||||||
|
}
|
2
playground/css-modules/global-module/index.js
Normal file
2
playground/css-modules/global-module/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './global.module.css'
|
||||||
|
export { default } from './global.module.css'
|
67
playground/css-modules/index.html
Normal file
67
playground/css-modules/index.html
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<h1>CSS Modules</h1>
|
||||||
|
|
||||||
|
<p>css-modules-value</p>
|
||||||
|
<pre class="css-modules-value"></pre>
|
||||||
|
|
||||||
|
<p>empty-css-module</p>
|
||||||
|
<pre class="empty-css-module"></pre>
|
||||||
|
|
||||||
|
<p>global-module</p>
|
||||||
|
<pre class="global-module"></pre>
|
||||||
|
|
||||||
|
<p>inline-query</p>
|
||||||
|
<pre class="inline-query"></pre>
|
||||||
|
|
||||||
|
<p>module-namespace</p>
|
||||||
|
<pre class="module-namespace"></pre>
|
||||||
|
|
||||||
|
<p>multi-css-modules</p>
|
||||||
|
<pre class="multi-css-modules"></pre>
|
||||||
|
|
||||||
|
<p>reserved-keywords</p>
|
||||||
|
<pre class="reserved-keywords"></pre>
|
||||||
|
|
||||||
|
<p>scss-modules</p>
|
||||||
|
<pre class="scss-modules"></pre>
|
||||||
|
|
||||||
|
<p>scss-modules-mixed</p>
|
||||||
|
<pre class="scss-modules-mixed"></pre>
|
||||||
|
|
||||||
|
<p>vue</p>
|
||||||
|
<pre class="vue"></pre>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import * as cssModulesValue from './css-modules-value'
|
||||||
|
text('.css-modules-value', JSON.stringify(cssModulesValue, null, 2))
|
||||||
|
|
||||||
|
import * as emptyCssModule from './empty-css-module'
|
||||||
|
text('.empty-css-module', JSON.stringify(emptyCssModule, null, 2))
|
||||||
|
|
||||||
|
import * as globalModule from './global-module'
|
||||||
|
text('.global-module', JSON.stringify(globalModule, null, 2))
|
||||||
|
|
||||||
|
import * as inlineQuery from './inline-query'
|
||||||
|
text('.inline-query', JSON.stringify(inlineQuery, null, 2))
|
||||||
|
|
||||||
|
import * as moduleNamespace from './module-namespace'
|
||||||
|
text('.module-namespace', JSON.stringify(moduleNamespace, null, 2))
|
||||||
|
|
||||||
|
import * as multiCssModules from './multi-css-modules'
|
||||||
|
text('.multi-css-modules', JSON.stringify(multiCssModules, null, 2))
|
||||||
|
|
||||||
|
import * as reservedKeywords from './reserved-keywords'
|
||||||
|
text('.reserved-keywords', JSON.stringify(reservedKeywords, null, 2))
|
||||||
|
|
||||||
|
import * as scssModules from './scss-modules'
|
||||||
|
text('.scss-modules', JSON.stringify(scssModules, null, 2))
|
||||||
|
|
||||||
|
import * as scssModulesMixed from './scss-modules-mixed'
|
||||||
|
text('.scss-modules-mixed', JSON.stringify(scssModulesMixed, null, 2))
|
||||||
|
|
||||||
|
import * as vue from './vue'
|
||||||
|
text('.vue', JSON.stringify(vue, null, 2))
|
||||||
|
|
||||||
|
function text(el, text) {
|
||||||
|
document.querySelector(el).textContent = text
|
||||||
|
}
|
||||||
|
</script>
|
2
playground/css-modules/inline-query/index.js
Normal file
2
playground/css-modules/inline-query/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.css?inline'
|
||||||
|
export { default } from './style.module.css?inline'
|
4
playground/css-modules/inline-query/style.module.css
Normal file
4
playground/css-modules/inline-query/style.module.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.class-name1 {
|
||||||
|
composes: util-class from './utils.css';
|
||||||
|
color: red;
|
||||||
|
}
|
8
playground/css-modules/inline-query/utils.css
Normal file
8
playground/css-modules/inline-query/utils.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.util-class {
|
||||||
|
--name: 'foo';
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unused-class {
|
||||||
|
color: yellow;
|
||||||
|
}
|
@ -0,0 +1,2 @@
|
|||||||
|
export { default as style1 } from './style1.module.css'
|
||||||
|
export { default as style2 } from './style2.module.css'
|
@ -0,0 +1,3 @@
|
|||||||
|
.button {
|
||||||
|
background: var(--accent-color from './vars.module.css');
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
.input {
|
||||||
|
color: var(--accent-color from './vars.module.css');
|
||||||
|
}
|
@ -0,0 +1,3 @@
|
|||||||
|
:root {
|
||||||
|
--accent-color: hotpink;
|
||||||
|
}
|
2
playground/css-modules/lightningcss-features/index.js
Normal file
2
playground/css-modules/lightningcss-features/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.css'
|
||||||
|
export { default } from './style.module.css'
|
@ -0,0 +1,5 @@
|
|||||||
|
.button {
|
||||||
|
&.primary {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
22
playground/css-modules/lightningcss.html
Normal file
22
playground/css-modules/lightningcss.html
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<h1>CSS Modules lightningcss</h1>
|
||||||
|
|
||||||
|
<p>lightningcss-custom-properties-from</p>
|
||||||
|
<pre class="lightningcss-custom-properties-from"></pre>
|
||||||
|
|
||||||
|
<p>lightningcss-features</p>
|
||||||
|
<pre class="lightningcss-features"></pre>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import * as lightningcssCustomPropertiesFrom from './lightningcss-custom-properties-from'
|
||||||
|
text(
|
||||||
|
'.lightningcss-custom-properties-from',
|
||||||
|
JSON.stringify(lightningcssCustomPropertiesFrom, null, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
import * as lightningcssFeatures from './lightningcss-features'
|
||||||
|
text('.lightningcss-features', JSON.stringify(lightningcssFeatures, null, 2))
|
||||||
|
|
||||||
|
function text(el, text) {
|
||||||
|
document.querySelector(el).textContent = text
|
||||||
|
}
|
||||||
|
</script>
|
2
playground/css-modules/missing-class-export/index.js
Normal file
2
playground/css-modules/missing-class-export/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.css'
|
||||||
|
export { default } from './style.module.css'
|
@ -0,0 +1,4 @@
|
|||||||
|
.className1 {
|
||||||
|
composes: non-existent from './utils.css';
|
||||||
|
color: red;
|
||||||
|
}
|
1
playground/css-modules/module-namespace/index.js
Normal file
1
playground/css-modules/module-namespace/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import('./style.module.css')
|
3
playground/css-modules/module-namespace/style.module.css
Normal file
3
playground/css-modules/module-namespace/style.module.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.class-name {
|
||||||
|
color: red;
|
||||||
|
}
|
2
playground/css-modules/multi-css-modules/index.js
Normal file
2
playground/css-modules/multi-css-modules/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * as style1 from './style1.module.css'
|
||||||
|
export * as style2 from './style2.module.css'
|
@ -0,0 +1,9 @@
|
|||||||
|
.className1 {
|
||||||
|
composes: util-class from './utils1.css';
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.class-name2 {
|
||||||
|
composes: util-class from './utils1.css';
|
||||||
|
composes: util-class from './utils2.css';
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
.class-name2 {
|
||||||
|
composes: util-class from './utils1.css';
|
||||||
|
color: red;
|
||||||
|
}
|
8
playground/css-modules/multi-css-modules/utils1.css
Normal file
8
playground/css-modules/multi-css-modules/utils1.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.util-class {
|
||||||
|
--name: 'foo';
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unused-class {
|
||||||
|
color: yellow;
|
||||||
|
}
|
4
playground/css-modules/multi-css-modules/utils2.css
Normal file
4
playground/css-modules/multi-css-modules/utils2.css
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.util-class {
|
||||||
|
--name: 'bar';
|
||||||
|
color: green;
|
||||||
|
}
|
20
playground/css-modules/package.json
Normal file
20
playground/css-modules/package.json
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"name": "@vitejs/test-css-modules",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"dev:lightningcss": "vite --config=vite.config-lightningcss.js",
|
||||||
|
"build:lightningcss": "vite --config=vite.config-lightningcss.js build",
|
||||||
|
"preview:lightningcss": "vite --config=vite.config-lightningcss.js preview"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
|
"lightningcss": "^1.24.1",
|
||||||
|
"postcss": "^8.4.36",
|
||||||
|
"sass": "^1.72.0",
|
||||||
|
"vue": "^3.4.21"
|
||||||
|
}
|
||||||
|
}
|
19
playground/css-modules/postcss.config.js
Normal file
19
playground/css-modules/postcss.config.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import path from 'node:path'
|
||||||
|
import postcss from 'postcss'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
plugins: [
|
||||||
|
/**
|
||||||
|
* PostCSS plugin that adds a "--file" CSS variable to indicate PostCSS
|
||||||
|
* has been successfully applied
|
||||||
|
*/
|
||||||
|
(root) => {
|
||||||
|
const newRule = postcss.rule({ selector: ':root' })
|
||||||
|
newRule.append({
|
||||||
|
prop: '--file',
|
||||||
|
value: JSON.stringify(path.basename(root.source.input.file)),
|
||||||
|
})
|
||||||
|
root.append(newRule)
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
1
playground/css-modules/reserved-keywords/index.js
Normal file
1
playground/css-modules/reserved-keywords/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * as style from './style.module.css'
|
@ -0,0 +1,8 @@
|
|||||||
|
.import {
|
||||||
|
composes: if from './utils.css';
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.export {
|
||||||
|
composes: with from './utils.css';
|
||||||
|
}
|
8
playground/css-modules/reserved-keywords/utils.css
Normal file
8
playground/css-modules/reserved-keywords/utils.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.if {
|
||||||
|
--name: 'foo';
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.with {
|
||||||
|
color: yellow;
|
||||||
|
}
|
3
playground/css-modules/scss-modules-mixed/css.module.css
Normal file
3
playground/css-modules/scss-modules-mixed/css.module.css
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
.text-primary {
|
||||||
|
composes: text-primary from './scss.module.scss';
|
||||||
|
}
|
2
playground/css-modules/scss-modules-mixed/index.js
Normal file
2
playground/css-modules/scss-modules-mixed/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './css.module.css'
|
||||||
|
export { default } from './css.module.css'
|
@ -0,0 +1,7 @@
|
|||||||
|
$primary: #cc0000;
|
||||||
|
|
||||||
|
// comment
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
color: $primary;
|
||||||
|
}
|
2
playground/css-modules/scss-modules/index.js
Normal file
2
playground/css-modules/scss-modules/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './style.module.scss'
|
||||||
|
export { default } from './style.module.scss'
|
7
playground/css-modules/scss-modules/style.module.scss
Normal file
7
playground/css-modules/scss-modules/style.module.scss
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
$primary: #cc0000;
|
||||||
|
|
||||||
|
// comment
|
||||||
|
|
||||||
|
.text-primary {
|
||||||
|
color: $primary;
|
||||||
|
}
|
27
playground/css-modules/vite.config-lightningcss.js
Normal file
27
playground/css-modules/vite.config-lightningcss.js
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { Features } from 'lightningcss'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
css: {
|
||||||
|
devSourcemap: true,
|
||||||
|
transformer: 'lightningcss',
|
||||||
|
lightningcss: {
|
||||||
|
include: Features.Nesting,
|
||||||
|
cssModules: {
|
||||||
|
dashedIdents: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
build: {
|
||||||
|
// Prevents CSS minification from handling the de-duplication of classes
|
||||||
|
minify: false,
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
lightningcss: resolve(__dirname, 'lightningcss.html'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
16
playground/css-modules/vite.config.js
Normal file
16
playground/css-modules/vite.config.js
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { resolve } from 'node:path'
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [vue()],
|
||||||
|
build: {
|
||||||
|
// Prevents CSS minification from handling the de-duplication of classes
|
||||||
|
minify: false,
|
||||||
|
rollupOptions: {
|
||||||
|
input: {
|
||||||
|
main: resolve(__dirname, 'index.html'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
10
playground/css-modules/vue/Comp.vue
Normal file
10
playground/css-modules/vue/Comp.vue
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<p :class="$style['css-module']"><css> module</p>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style module>
|
||||||
|
.css-module {
|
||||||
|
composes: util-class from './utils.css';
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
1
playground/css-modules/vue/index.js
Normal file
1
playground/css-modules/vue/index.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { default as Comp } from './Comp.vue'
|
8
playground/css-modules/vue/utils.css
Normal file
8
playground/css-modules/vue/utils.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.util-class {
|
||||||
|
--name: 'foo';
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unused-class {
|
||||||
|
color: yellow;
|
||||||
|
}
|
@ -9,7 +9,7 @@ import type {
|
|||||||
ElementHandle,
|
ElementHandle,
|
||||||
Locator,
|
Locator,
|
||||||
} from 'playwright-chromium'
|
} from 'playwright-chromium'
|
||||||
import type { DepOptimizationMetadata, Manifest } from 'vite'
|
import type { DepOptimizationMetadata, Manifest, Rollup } from 'vite'
|
||||||
import { normalizePath } from 'vite'
|
import { normalizePath } from 'vite'
|
||||||
import { fromComment } from 'convert-source-map'
|
import { fromComment } from 'convert-source-map'
|
||||||
import type { Assertion } from 'vitest'
|
import type { Assertion } from 'vitest'
|
||||||
@ -408,3 +408,25 @@ export function promiseWithResolvers<T>(): PromiseWithResolvers<T> {
|
|||||||
})
|
})
|
||||||
return { promise, resolve, reject }
|
return { promise, resolve, reject }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const base64Module = (code: string) =>
|
||||||
|
`data:text/javascript;base64,${Buffer.from(code).toString('base64')}`
|
||||||
|
|
||||||
|
export const getCssSourceMaps = (code: string) => {
|
||||||
|
const cssSourcemaps = Array.from(
|
||||||
|
code.matchAll(
|
||||||
|
/\/*# sourceMappingURL=data:application\/json;base64,(.+?) \*\//g,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
const maps = cssSourcemaps.map(
|
||||||
|
([, base64]) =>
|
||||||
|
JSON.parse(
|
||||||
|
Buffer.from(base64!, 'base64').toString('utf8'),
|
||||||
|
) as Rollup.SourceMap,
|
||||||
|
)
|
||||||
|
|
||||||
|
maps.sort((a, b) => a.sources[0]!.localeCompare(b.sources[0]!))
|
||||||
|
|
||||||
|
return maps
|
||||||
|
}
|
||||||
|
147
pnpm-lock.yaml
147
pnpm-lock.yaml
@ -173,7 +173,7 @@ importers:
|
|||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
vitepress:
|
vitepress:
|
||||||
specifier: 1.0.0-rc.45
|
specifier: 1.0.0-rc.45
|
||||||
version: 1.0.0-rc.45(typescript@5.2.2)
|
version: 1.0.0-rc.45(@types/node@20.11.28)(typescript@5.2.2)
|
||||||
vue:
|
vue:
|
||||||
specifier: ^3.4.21
|
specifier: ^3.4.21
|
||||||
version: 3.4.21(typescript@5.2.2)
|
version: 3.4.21(typescript@5.2.2)
|
||||||
@ -613,6 +613,24 @@ importers:
|
|||||||
specifier: ^1.24.1
|
specifier: ^1.24.1
|
||||||
version: 1.24.1
|
version: 1.24.1
|
||||||
|
|
||||||
|
playground/css-modules:
|
||||||
|
devDependencies:
|
||||||
|
'@vitejs/plugin-vue':
|
||||||
|
specifier: ^5.0.4
|
||||||
|
version: 5.0.4(vite@packages+vite)(vue@3.4.21)
|
||||||
|
lightningcss:
|
||||||
|
specifier: ^1.24.1
|
||||||
|
version: 1.24.1
|
||||||
|
postcss:
|
||||||
|
specifier: ^8.4.36
|
||||||
|
version: 8.4.36
|
||||||
|
sass:
|
||||||
|
specifier: ^1.72.0
|
||||||
|
version: 1.72.0
|
||||||
|
vue:
|
||||||
|
specifier: ^3.4.21
|
||||||
|
version: 3.4.21(typescript@5.2.2)
|
||||||
|
|
||||||
playground/css-sourcemap:
|
playground/css-sourcemap:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
less:
|
less:
|
||||||
@ -3941,21 +3959,6 @@ packages:
|
|||||||
typescript: 5.2.2
|
typescript: 5.2.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@rollup/pluginutils@5.0.4(rollup@3.29.4):
|
|
||||||
resolution: {integrity: sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g==}
|
|
||||||
engines: {node: '>=14.0.0'}
|
|
||||||
peerDependencies:
|
|
||||||
rollup: ^1.20.0||^2.0.0||^3.0.0
|
|
||||||
peerDependenciesMeta:
|
|
||||||
rollup:
|
|
||||||
optional: true
|
|
||||||
dependencies:
|
|
||||||
'@types/estree': 1.0.5
|
|
||||||
estree-walker: 2.0.2
|
|
||||||
picomatch: 2.3.1
|
|
||||||
rollup: 3.29.4
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@rollup/pluginutils@5.1.0(rollup@3.29.4):
|
/@rollup/pluginutils@5.1.0(rollup@3.29.4):
|
||||||
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
|
resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
|
||||||
engines: {node: '>=14.0.0'}
|
engines: {node: '>=14.0.0'}
|
||||||
@ -4318,12 +4321,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/node@20.10.0:
|
|
||||||
resolution: {integrity: sha512-D0WfRmU9TQ8I9PFx9Yc+EBHw+vSpIub4IDvQivcp26PtPrdMGAq5SDcpXEo/epqa/DXotVpekHiLNTg3iaKXBQ==}
|
|
||||||
dependencies:
|
|
||||||
undici-types: 5.26.5
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/node@20.11.28:
|
/@types/node@20.11.28:
|
||||||
resolution: {integrity: sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==}
|
resolution: {integrity: sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -4344,7 +4341,7 @@ packages:
|
|||||||
/@types/prompts@2.4.9:
|
/@types/prompts@2.4.9:
|
||||||
resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==}
|
resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.10.0
|
'@types/node': 20.11.28
|
||||||
kleur: 3.0.3
|
kleur: 3.0.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@ -4549,6 +4546,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@vitejs/plugin-vue@5.0.4(vite@5.2.2)(vue@3.4.21):
|
||||||
|
resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
vite: '*'
|
||||||
|
vue: ^3.2.25
|
||||||
|
dependencies:
|
||||||
|
vite: 5.2.2(@types/node@20.11.28)
|
||||||
|
vue: 3.4.21(typescript@5.2.2)
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@vitejs/plugin-vue@5.0.4(vite@packages+vite)(vue@3.4.21):
|
/@vitejs/plugin-vue@5.0.4(vite@packages+vite)(vue@3.4.21):
|
||||||
resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
|
resolution: {integrity: sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
@ -7500,13 +7508,6 @@ packages:
|
|||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
'@jridgewell/sourcemap-codec': 1.4.15
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/magic-string@0.30.4:
|
|
||||||
resolution: {integrity: sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg==}
|
|
||||||
engines: {node: '>=12'}
|
|
||||||
dependencies:
|
|
||||||
'@jridgewell/sourcemap-codec': 1.4.15
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/magic-string@0.30.8:
|
/magic-string@0.30.8:
|
||||||
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
resolution: {integrity: sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==}
|
||||||
engines: {node: '>=12'}
|
engines: {node: '>=12'}
|
||||||
@ -8581,7 +8582,7 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
icss-utils: 5.1.0(postcss@8.4.36)
|
icss-utils: 5.1.0(postcss@8.4.36)
|
||||||
postcss: 8.4.36
|
postcss: 8.4.36
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.16
|
||||||
postcss-value-parser: 4.2.0
|
postcss-value-parser: 4.2.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
@ -8595,7 +8596,7 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
postcss: 8.4.36
|
postcss: 8.4.36
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.16
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/postcss-modules-values@4.0.0(postcss@8.4.36):
|
/postcss-modules-values@4.0.0(postcss@8.4.36):
|
||||||
@ -8621,10 +8622,10 @@ packages:
|
|||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
postcss: 8.4.36
|
postcss: 8.4.36
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.16
|
||||||
|
|
||||||
/postcss-selector-parser@6.0.11:
|
/postcss-selector-parser@6.0.16:
|
||||||
resolution: {integrity: sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==}
|
resolution: {integrity: sha512-A0RVJrX+IUkVZbW3ClroRWurercFhieevHB38sr2+l9eUClMqome3LmEmnhlNy+5Mr2EYN6B2Kaw9wYdd+VHiw==}
|
||||||
engines: {node: '>=4'}
|
engines: {node: '>=4'}
|
||||||
dependencies:
|
dependencies:
|
||||||
cssesc: 3.0.0
|
cssesc: 3.0.0
|
||||||
@ -9589,7 +9590,7 @@ packages:
|
|||||||
postcss-js: 4.0.1(postcss@8.4.36)
|
postcss-js: 4.0.1(postcss@8.4.36)
|
||||||
postcss-load-config: 4.0.2(postcss@8.4.36)(ts-node@10.9.2)
|
postcss-load-config: 4.0.2(postcss@8.4.36)(ts-node@10.9.2)
|
||||||
postcss-nested: 6.0.1(postcss@8.4.36)
|
postcss-nested: 6.0.1(postcss@8.4.36)
|
||||||
postcss-selector-parser: 6.0.11
|
postcss-selector-parser: 6.0.16
|
||||||
resolve: 1.22.4
|
resolve: 1.22.4
|
||||||
sucrase: 3.32.0
|
sucrase: 3.32.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
@ -9874,7 +9875,7 @@ packages:
|
|||||||
'@rollup/plugin-json': 6.0.0(rollup@3.29.4)
|
'@rollup/plugin-json': 6.0.0(rollup@3.29.4)
|
||||||
'@rollup/plugin-node-resolve': 15.2.1(rollup@3.29.4)
|
'@rollup/plugin-node-resolve': 15.2.1(rollup@3.29.4)
|
||||||
'@rollup/plugin-replace': 5.0.2(rollup@3.29.4)
|
'@rollup/plugin-replace': 5.0.2(rollup@3.29.4)
|
||||||
'@rollup/pluginutils': 5.0.4(rollup@3.29.4)
|
'@rollup/pluginutils': 5.1.0(rollup@3.29.4)
|
||||||
chalk: 5.3.0
|
chalk: 5.3.0
|
||||||
citty: 0.1.4
|
citty: 0.1.4
|
||||||
consola: 3.2.3
|
consola: 3.2.3
|
||||||
@ -9883,7 +9884,7 @@ packages:
|
|||||||
globby: 13.2.2
|
globby: 13.2.2
|
||||||
hookable: 5.5.3
|
hookable: 5.5.3
|
||||||
jiti: 1.20.0
|
jiti: 1.20.0
|
||||||
magic-string: 0.30.4
|
magic-string: 0.30.8
|
||||||
mkdist: 1.3.0(typescript@5.2.2)
|
mkdist: 1.3.0(typescript@5.2.2)
|
||||||
mlly: 1.4.2
|
mlly: 1.4.2
|
||||||
pathe: 1.1.2
|
pathe: 1.1.2
|
||||||
@ -10075,7 +10076,7 @@ packages:
|
|||||||
- rollup
|
- rollup
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vite-node@1.4.0:
|
/vite-node@1.4.0(@types/node@20.11.28):
|
||||||
resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==}
|
resolution: {integrity: sha512-VZDAseqjrHgNd4Kh8icYHWzTKSCZMhia7GyHfhtzLW33fZlG9SwsB6CEhgyVOWkJfJ2pFLrp/Gj1FSfAiqH9Lw==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
@ -10084,12 +10085,55 @@ packages:
|
|||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
pathe: 1.1.2
|
pathe: 1.1.2
|
||||||
picocolors: 1.0.0
|
picocolors: 1.0.0
|
||||||
vite: link:packages/vite
|
vite: 5.2.2(@types/node@20.11.28)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
- supports-color
|
- supports-color
|
||||||
|
- terser
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/vitepress@1.0.0-rc.45(typescript@5.2.2):
|
/vite@5.2.2(@types/node@20.11.28):
|
||||||
|
resolution: {integrity: sha512-FWZbz0oSdLq5snUI0b6sULbz58iXFXdvkZfZWR/F0ZJuKTSPO7v72QPXt6KqYeMFb0yytNp6kZosxJ96Nr/wDQ==}
|
||||||
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@types/node': ^18.0.0 || >=20.0.0
|
||||||
|
less: '*'
|
||||||
|
lightningcss: ^1.21.0
|
||||||
|
sass: '*'
|
||||||
|
stylus: '*'
|
||||||
|
sugarss: '*'
|
||||||
|
terser: ^5.4.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
less:
|
||||||
|
optional: true
|
||||||
|
lightningcss:
|
||||||
|
optional: true
|
||||||
|
sass:
|
||||||
|
optional: true
|
||||||
|
stylus:
|
||||||
|
optional: true
|
||||||
|
sugarss:
|
||||||
|
optional: true
|
||||||
|
terser:
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@types/node': 20.11.28
|
||||||
|
esbuild: 0.20.1
|
||||||
|
postcss: 8.4.36
|
||||||
|
rollup: 4.13.0
|
||||||
|
optionalDependencies:
|
||||||
|
fsevents: 2.3.3
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/vitepress@1.0.0-rc.45(@types/node@20.11.28)(typescript@5.2.2):
|
||||||
resolution: {integrity: sha512-/OiYsu5UKpQKA2c0BAZkfyywjfauDjvXyv6Mo4Ra57m5n4Bxg1HgUGoth1CLH2vwUbR/BHvDA9zOM0RDvgeSVQ==}
|
resolution: {integrity: sha512-/OiYsu5UKpQKA2c0BAZkfyywjfauDjvXyv6Mo4Ra57m5n4Bxg1HgUGoth1CLH2vwUbR/BHvDA9zOM0RDvgeSVQ==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -10106,7 +10150,7 @@ packages:
|
|||||||
'@shikijs/core': 1.1.5
|
'@shikijs/core': 1.1.5
|
||||||
'@shikijs/transformers': 1.1.5
|
'@shikijs/transformers': 1.1.5
|
||||||
'@types/markdown-it': 13.0.7
|
'@types/markdown-it': 13.0.7
|
||||||
'@vitejs/plugin-vue': 5.0.4(vite@packages+vite)(vue@3.4.21)
|
'@vitejs/plugin-vue': 5.0.4(vite@5.2.2)(vue@3.4.21)
|
||||||
'@vue/devtools-api': 7.0.14
|
'@vue/devtools-api': 7.0.14
|
||||||
'@vueuse/core': 10.7.2(vue@3.4.21)
|
'@vueuse/core': 10.7.2(vue@3.4.21)
|
||||||
'@vueuse/integrations': 10.7.2(focus-trap@7.5.4)(vue@3.4.21)
|
'@vueuse/integrations': 10.7.2(focus-trap@7.5.4)(vue@3.4.21)
|
||||||
@ -10114,10 +10158,11 @@ packages:
|
|||||||
mark.js: 8.11.1
|
mark.js: 8.11.1
|
||||||
minisearch: 6.3.0
|
minisearch: 6.3.0
|
||||||
shiki: 1.1.5
|
shiki: 1.1.5
|
||||||
vite: link:packages/vite
|
vite: 5.2.2(@types/node@20.11.28)
|
||||||
vue: 3.4.21(typescript@5.2.2)
|
vue: 3.4.21(typescript@5.2.2)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- '@algolia/client-search'
|
- '@algolia/client-search'
|
||||||
|
- '@types/node'
|
||||||
- '@types/react'
|
- '@types/react'
|
||||||
- '@vue/composition-api'
|
- '@vue/composition-api'
|
||||||
- async-validator
|
- async-validator
|
||||||
@ -10127,12 +10172,18 @@ packages:
|
|||||||
- fuse.js
|
- fuse.js
|
||||||
- idb-keyval
|
- idb-keyval
|
||||||
- jwt-decode
|
- jwt-decode
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
- nprogress
|
- nprogress
|
||||||
- qrcode
|
- qrcode
|
||||||
- react
|
- react
|
||||||
- react-dom
|
- react-dom
|
||||||
|
- sass
|
||||||
- search-insights
|
- search-insights
|
||||||
- sortablejs
|
- sortablejs
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- terser
|
||||||
- typescript
|
- typescript
|
||||||
- universal-cookie
|
- universal-cookie
|
||||||
dev: true
|
dev: true
|
||||||
@ -10180,12 +10231,18 @@ packages:
|
|||||||
strip-literal: 2.0.0
|
strip-literal: 2.0.0
|
||||||
tinybench: 2.5.1
|
tinybench: 2.5.1
|
||||||
tinypool: 0.8.2
|
tinypool: 0.8.2
|
||||||
vite: link:packages/vite
|
vite: 5.2.2(@types/node@20.11.28)
|
||||||
vite-node: 1.4.0
|
vite-node: 1.4.0(@types/node@20.11.28)
|
||||||
why-is-node-running: 2.2.2
|
why-is-node-running: 2.2.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- acorn
|
- acorn
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
- supports-color
|
- supports-color
|
||||||
|
- terser
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/void-elements@3.1.0:
|
/void-elements@3.1.0:
|
||||||
|
Loading…
Reference in New Issue
Block a user