diff --git a/packages/css/src/plugin.ts b/packages/css/src/plugin.ts index 7cf316bb6..beed06803 100644 --- a/packages/css/src/plugin.ts +++ b/packages/css/src/plugin.ts @@ -12,7 +12,10 @@ import { } from './options.ts' import { CssPostPlugin, type CssStyles } from './post.ts' import { processWithPostCSS as runPostCSS } from './postcss.ts' -import { compilePreprocessor, getPreprocessorLang } from './preprocessors.ts' +import { + compilePreprocessor, + getPreprocessorLangFromId, +} from './preprocessors.ts' import { CSS_LANGS_RE, CSS_MODULE_RE, @@ -315,7 +318,7 @@ async function processWithLightningCSS( logger: Logger, isModule: boolean, ): Promise { - const lang = getPreprocessorLang(cleanId) + const lang = getPreprocessorLangFromId(id) const cssModules = resolveCssModulesConfig( config.css.modules, isModule, @@ -378,7 +381,7 @@ async function processWithPostCSS( config: CssPluginConfig, isModule: boolean, ): Promise { - const lang = getPreprocessorLang(cleanId) + const lang = getPreprocessorLangFromId(id) if (lang) { const preResult = await compilePreprocessor( diff --git a/packages/css/src/preprocessors.ts b/packages/css/src/preprocessors.ts index 4477412b1..0b313d55c 100644 --- a/packages/css/src/preprocessors.ts +++ b/packages/css/src/preprocessors.ts @@ -2,6 +2,7 @@ import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath, pathToFileURL } from 'node:url' import { getSassResolver, resolveWithResolver } from './resolve.ts' +import { CSS_LANGS_RE } from './utils.ts' import type { PreprocessorOptions } from './options.ts' export type PreprocessorLang = 'sass' | 'scss' | 'less' | 'styl' | 'stylus' @@ -26,6 +27,14 @@ export function getPreprocessorLang( return PREPROCESSOR_LANGS[ext] } +export function getPreprocessorLangFromId( + id: string, +): PreprocessorLang | undefined { + const match = CSS_LANGS_RE.exec(id) + if (!match) return + return PREPROCESSOR_LANGS[match[1]] +} + export function compilePreprocessor( lang: PreprocessorLang, code: string, diff --git a/packages/css/src/utils.ts b/packages/css/src/utils.ts index 85cbdbf07..4620ea66b 100644 --- a/packages/css/src/utils.ts +++ b/packages/css/src/utils.ts @@ -1,7 +1,6 @@ export const RE_CSS: RegExp = /\.css$/ export const RE_INLINE: RegExp = /[?&]inline\b/ -export const CSS_LANGS_RE: RegExp = - /\.(?:css|less|sass|scss|styl|stylus)(?:$|\?)/ +export const CSS_LANGS_RE: RegExp = /\.(css|less|sass|scss|styl|stylus)(?:$|\?)/ export const RE_CSS_INLINE: RegExp = /\.(?:css|less|sass|scss|styl|stylus)\?(?:.*&)?inline\b/ diff --git a/tests/__snapshots__/issues/848.snap.md b/tests/__snapshots__/issues/848.snap.md new file mode 100644 index 000000000..084823c28 --- /dev/null +++ b/tests/__snapshots__/issues/848.snap.md @@ -0,0 +1,33 @@ +## index.mjs + +```mjs +import { createElementBlock, openBlock } from "vue"; +//#region \0/plugin-vue/export-helper +var export_helper_default = (sfc, props) => { + const target = sfc.__vccOpts || sfc; + for (const [key, val] of props) target[key] = val; + return target; +}; +//#endregion +//#region App.vue +const _sfc_main = {}; +function _sfc_render(_ctx, _cache) { + return openBlock(), createElementBlock("button", null, "Click"); +} +var App_default = /* @__PURE__ */ export_helper_default(_sfc_main, [["render", _sfc_render]]); +//#endregion +export { App_default as App }; + +``` + +## style.css + +```css +button { + padding: 10px 20px; + border: 1px solid #ccc; + border-radius: 5px; + font-size: 1.2em; +} + +``` diff --git a/tests/issues.test.ts b/tests/issues.test.ts index 1ff2e3780..73ec19ed5 100644 --- a/tests/issues.test.ts +++ b/tests/issues.test.ts @@ -197,6 +197,38 @@ describe('issues', () => { expect(fileMap['style.css']).toContain('.btn') }) + test('#848', async (context) => { + const Vue = (await import('unplugin-vue/rolldown')).default + const { outputFiles, fileMap } = await testBuild({ + context, + files: { + 'index.ts': `export { default as App } from './App.vue'`, + 'App.vue': ` +`, + }, + options: { + plugins: [Vue({ isProduction: true })], + deps: { skipNodeModulesBundle: true }, + }, + }) + expect(outputFiles).toContain('style.css') + const css = fileMap['style.css'] + expect(css).toContain('padding') + expect(css).toContain('border-radius') + expect(css).not.toContain('@mixin') + expect(css).not.toContain('@include') + }) + test('#772', async (context) => { const { fileMap, outputFiles } = await testBuild({ context,