Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support postcss sugarss #2436

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/playground/css/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ <h1>CSS</h1>
<p class="css-dep-sass">
@import dependency w/ sass enrtrypoints: this should be orange
</p>
<p>Imported SugarSS indent-based CSS syntax for PostCSS:</p>
<pre class="imported-sugarss"></pre>
</div>

<script type="module" src="./main.js"></script>
3 changes: 3 additions & 0 deletions packages/playground/css/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ text('.modules-sass-code', JSON.stringify(sassMod, null, 2))

import './dep.css'

import sss from './sugarss.sss'
text('.imported-sugarss', sss)

function text(el, text) {
document.querySelector(el).textContent = text
}
Expand Down
4 changes: 3 additions & 1 deletion packages/playground/css/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
"serve": "vite preview"
},
"devDependencies": {
"css-dep": "link:./css-dep",
"less": "^4.1.0",
"postcss-nested": "^5.0.3",
"postcss-simple-vars": "^6.0.3",
"sass": "^1.32.5",
"css-dep": "link:./css-dep"
"sugarss": "^3.0.3"
}
}
13 changes: 11 additions & 2 deletions packages/playground/css/postcss.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
module.exports = {
plugins: [require('postcss-nested')]
module.exports = (api) => {
if (/\.sss$/.test(api.file)) {
return {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick (non-blocking): I would prefer an initial object at the start of the function body and return it at the end of the function
Then in between you can add dynamically properties and extend it

So something like

  const config = {
    plugins: [require('postcss-nested')]
  }

  if (/\.sss$/.test(api.file)) {
    config.parser = 'sugarss'
    config.plugins.unshift(require('postcss-simple-vars'))
  }

  return config

May need to be extended with some type-safety or so

parser: 'sugarss',
plugins: [require('postcss-simple-vars'), require('postcss-nested')]
}
}

return {
plugins: [require('postcss-nested')]
}
}
4 changes: 4 additions & 0 deletions packages/playground/css/sugarss.sss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
$black: #000

.sugarss
border: thick double $black
33 changes: 21 additions & 12 deletions packages/vite/src/node/plugins/css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export interface CSSModulesOptions {
| null
}

const cssLangs = `\\.(css|less|sass|scss|styl|stylus|postcss)($|\\?)`
const cssLangs = `\\.(css|less|sass|scss|styl|stylus|postcss|sss)($|\\?)`
const cssLangRE = new RegExp(cssLangs)
const cssModuleRE = new RegExp(`\\.module${cssLangs}`)
const directRequestRE = /(\?|&)direct\b/
Expand Down Expand Up @@ -507,7 +507,7 @@ async function compileCSS(
// crawl them in order to register watch dependencies.
const needInlineImport = code.includes('@import')
const hasUrl = cssUrlRE.test(code) || cssImageSetRE.test(code)
const postcssConfig = await resolvePostcssConfig(config)
const postcssConfig = await resolvePostcssConfig(id, config)
const lang = id.match(cssLangRE)?.[1]

// 1. plain css that needs no processing
Expand Down Expand Up @@ -664,38 +664,47 @@ async function compileCSS(
interface PostCSSConfigResult {
options: Postcss.ProcessOptions
plugins: Postcss.Plugin[]
file?: string
}

let cachedPostcssConfig: PostCSSConfigResult | null | undefined
let cachedPostcssConfigPath: string | undefined | null

async function resolvePostcssConfig(
file: string,
config: ResolvedConfig
): Promise<PostCSSConfigResult | null> {
if (cachedPostcssConfig !== undefined) {
return cachedPostcssConfig
}

// inline postcss config via vite config
const inlineOptions = config.css?.postcss

if (isObject(inlineOptions)) {
const result = {
options: { ...inlineOptions },
plugins: inlineOptions.plugins || []
}
delete result.options.plugins
return (cachedPostcssConfig = result)

return result
}

if (cachedPostcssConfigPath === null) {
return null
}

try {
const searchPath =
typeof inlineOptions === 'string' ? inlineOptions : config.root
// @ts-ignore
return (cachedPostcssConfig = await postcssrc({}, searchPath))
cachedPostcssConfigPath ??
(typeof inlineOptions === 'string' ? inlineOptions : config.root)

const ctx = { file, env: config.mode }
const result = (await postcssrc(ctx, searchPath)) as PostCSSConfigResult
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is obviously very inefficient - I think a better way to do this is have two cached & resolved config values - one for SugarSS and one for normal CSS.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can cache the resolved config with a hash of the ctx object, but we'll need to replace ctx.file with ctx.type (the file extension without the dot).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another option is to provide a cache function like Babel does it:
https://babeljs.io/docs/en/config-files#apicache

cachedPostcssConfigPath = result.file

return result
} catch (e) {
if (!/No PostCSS Config found/.test(e.message)) {
throw e
}
return (cachedPostcssConfig = null)
return (cachedPostcssConfigPath = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought (dx): I'm a bit confused by this line
Could we split it into two lines?
I think it means the same as 🤔

cachedPostcssConfigPath = null
return null

}
}

Expand Down
12 changes: 0 additions & 12 deletions packages/vite/types/shims.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,18 +46,6 @@ declare module 'merge-source-map' {
export default function merge(oldMap: object, newMap: object): object
}

declare module 'postcss-load-config' {
import { ProcessOptions, Plugin } from 'postcss'
function load(
inline: any,
root: string
): Promise<{
options: ProcessOptions
plugins: Plugin[]
}>
export = load
}

declare module 'postcss-import' {
import { Plugin } from 'postcss'
const plugin: (options: {
Expand Down
23 changes: 22 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2079,7 +2079,7 @@ color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==

colorette@^1.2.1:
colorette@^1.2.1, colorette@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
Expand Down Expand Up @@ -6078,6 +6078,11 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4:
uniq "^1.0.1"
util-deprecate "^1.0.2"

postcss-simple-vars@^6.0.3:
version "6.0.3"
resolved "https://registry.yarnpkg.com/postcss-simple-vars/-/postcss-simple-vars-6.0.3.tgz#e66516c7fe980da3498f4a8ad400b9c53861806c"
integrity sha512-fkNn4Zio8vN4vIig9IFdb8lVlxWnYR769RgvxCM6YWlFKie/nQaOcaMMMFz/s4gsfHW4/5bJW+i57zD67mQU7g==

postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
Expand All @@ -6092,6 +6097,15 @@ postcss@^8.1.10, postcss@^8.2.1:
nanoid "^3.1.20"
source-map "^0.6.1"

postcss@^8.1.6:
version "8.2.7"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.7.tgz#48ed8d88b4de10afa0dfd1c3f840aa57b55c4d47"
integrity sha512-DsVLH3xJzut+VT+rYr0mtvOtpTjSyqDwPf5EZWXcb0uAKfitGpTY9Ec+afi2+TgdN8rWS9Cs88UDYehKo/RvOw==
dependencies:
colorette "^1.2.2"
nanoid "^3.1.20"
source-map "^0.6.1"

preact@^10.0.0:
version "10.5.12"
resolved "https://registry.yarnpkg.com/preact/-/preact-10.5.12.tgz#6a8ee8bf40a695c505df9abebacd924e4dd37704"
Expand Down Expand Up @@ -7363,6 +7377,13 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1, strip-json-comments@~3.1
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==

sugarss@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-3.0.3.tgz#bb2489961b98fbd15e4e35d6b9f4f2ee5547a6cb"
integrity sha512-uxa2bbuc+w7ov7DyYIhF6bM0qZF3UkFT5/nE8AJgboiVnKsBDbwxs++dehEIe1JNhpMaGJc37wGQ2QrrWey2Sg==
dependencies:
postcss "^8.1.6"

supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
Expand Down