Less.js: ๋นˆ ์„ ํƒ๊ธฐ(๊ทœ์น™ ์ง‘ํ•ฉ) ์œ ์ง€ ์˜ต์…˜

์— ๋งŒ๋“  2012๋…„ 10์›” 28์ผ  ยท  28์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: less/less.js

๋นˆ ์„ ํƒ๊ธฐ๋ฅผ ์œ ์ง€ํ•˜๋Š” ์˜ต์…˜์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ตœ์†Œํ•œ ๋‚ด๊ฐ€ ์ง์ ‘ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋Š” ํŒŒ์ผ์„ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ? ๋ฐฉํ™”๋ฒ”์„ ํ†ตํ•œ ์Šคํƒ€์ผ๋ง์„ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

feature request low priority needs decision up-for-grabs

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

@chetzof ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ์ง€๋งŒ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์— ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค :

์„ ํƒ๊ธฐ { /**/ }

๋ฐฉํ™”๋ฒ”์—์„œ๋Š” ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

๋ชจ๋“  28 ๋Œ“๊ธ€

:empty ์˜์‚ฌ ์„ ํƒ๊ธฐ๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๊นŒ?

http://reference.sitepoint.com/css/pseudoclass-empty

์•„๋‹ˆ์š”, ์•„๋งˆ๋„ "๊ทœ์น™"์ด๋ผ๊ณ  ๋ถˆ๋Ÿฌ์•ผ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.)
๋‚ด ๋ง์€

.selector {}
a.nother{
   .selector {}
}

CSS๋กœ ์ปดํŒŒ์ผํ•˜๋ฉด ์‚ญ์ œ๋ฉ๋‹ˆ๋‹ค.

์™œ ๊ทธ๊ฒƒ๋“ค์„ ์œ ์ง€ํ•˜๊ณ  ์‹ถ์Šต๋‹ˆ๊นŒ? ๊ทธ๋“ค์€ ์ƒ์„ฑ๋œ CSS ํŒŒ์ผ์—์„œ ๊ณต๋ฐฑ์œผ๋กœ ์•„๋ฌด๊ฒƒ๋„ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‹น์‹ ์€ ๋‹น์‹ ์ด Firebug๋ฅผ ํ†ตํ•ด ์Šคํƒ€์ผ๋ง์„ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๊ณ  ๋งํ•˜์ง€๋งŒ ๋‚˜๋Š” ๋‹น์‹ ์˜ ์ ‘๊ทผ ๋ฐฉ์‹์ด ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

  1. ์š”์†Œ ๋˜๋Š” ์š”์†Œ ๊ทธ๋ฃน์— ๋Œ€ํ•ด less ํŒŒ์ผ์— ๋นˆ ๊ทœ์น™์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋ฐฉํ™”๋ฒ”์„ ์—ด๊ณ  ์ž‘์—…ํ•˜๋ ค๋Š” ์š”์†Œ๋ฅผ ์„ ํƒํ•˜๋ฉด ๋‚ด๊ฐ€ ๋งŒ๋“  ๋นˆ ๊ทœ์น™์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
  3. ๋‚˜๋Š” ๊ทธ ๋นˆ ๊ทœ์น™ ์•ˆ์— ์Šคํƒ€์ผ์„ ์”๋‹ˆ๋‹ค.
  4. https://github.com/ronniekk/css-x-fire ํ”Œ๋Ÿฌ๊ทธ์ธ์€ firebug์—์„œ ๋ณ€๊ฒฝํ•œ ๋‚ด์šฉ์„ ๋” ์ ์€ ํŒŒ์ผ๋กœ ๋‹ค์‹œ ๋™๊ธฐํ™”ํ•˜๊ณ , ๋นˆ ๊ทœ์น™์„ ์ฐพ๊ณ , firebug์—์„œ ์ง€์ •ํ•œ ์Šคํƒ€์ผ์„ ๊ฑฐ๊ธฐ์— ๋„ฃ์Šต๋‹ˆ๋‹ค.

์š”๊ตฌ ์‚ฌํ•ญ์€ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋‹ค์‹œ ๋™๊ธฐํ™”ํ•˜๋ ค๋ฉด ๊ทœ์น™์ด ์ด๋ฏธ ์กด์žฌํ•ด์•ผ ํ•˜๋ฉฐ, ๋ถ„๋ช…ํžˆ ์š”์†Œ์— ์ด์ „์— ์Šคํƒ€์ผ์ด ์—†์—ˆ๋‹ค๋ฉด ์ฒ˜์Œ์œผ๋กœ ๋นˆ ๊ทœ์น™์„ ๋งŒ๋“ค์–ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ˆœ์ˆ˜ CSS๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ž‘๋™ํ–ˆ์ง€๋งŒ ์ด์ œ LESS๋กœ ์ „ํ™˜ํ–ˆ์„ ๋•Œ ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๋นˆ ๊ทœ์น™์„ ์‚ญ์ œํ•˜๊ณ  ํ”Œ๋Ÿฌ๊ทธ์ธ์ด ์Šคํƒ€์ผ์„ ๋‹ค์‹œ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋งค์šฐ ์ข์€ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ผ๋Š” ๊ฒƒ์„ ์•Œ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค ...

์ด๊ฒƒ์€ _๋งค์šฐ_ ํŠน์ •ํ•œ ์‚ฌ์šฉ ์‚ฌ๋ก€์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ์‚ฌ๋žŒ๋“ค์€ CSS๋ฅผ ๋œ ์ตœ์ ํ™”ํ•˜๊ณ  ๋นˆ ๊ทœ์น™์„ ๋‚จ๊ฒจ๋‘์ง€ _์•Š์Šต๋‹ˆ๋‹ค_.

์Šคํƒ€์ผ์„ ์ž๋™์œผ๋กœ ์ƒˆ๋กœ ๊ณ ์น˜๋ ค๋ฉด less.watch() ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

<script type="text/javascript">
     less.env = "development";
     less.watch();
</script>

๋˜๋Š” URL์— #!watch ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์—ฌ๊ธฐ์— ๋ช‡ ๊ฐ€์ง€ ์ œ์•ˆ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. http://www.paulsprangers.com/2011/04/quick-tip-less-js-in-development-and-watch-mode/

@Soviut์˜ ์ข‹์€ ์กฐ์–ธ. ๋˜ํ•œ ๋งˆ์Œ์— ๋“ค์ง€ ์•Š์œผ๋ฉด ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์œ„ํ•ด ๊ฐ€์งœ ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค.

temp: ruleset;

๋™์˜. @agatronic ์˜ ์†”๋ฃจ์…˜์€ ๋‹ค๋ฅธ ๋ชจ๋“  LESS ํŒŒ์ผ์ด ๋น„ํšจ์œจ์ ์ธ CSS๋ฅผ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ณ  ํ•„์š”ํ•œ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

@agatronic ๊ทธ๊ฒŒ ๋‚ด๊ฐ€ LESS๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ•œ ์ดํ›„๋กœ ์ง€๋‚œ 2์ฃผ ๋™์•ˆ ํ•˜๊ณ  ์žˆ๋˜ ์ผ์ด์ง€๋งŒ, ๊ทธ๋Ÿฐ ๊ฐ€์งœ ๊ทœ์น™์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์„ ์žŠ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ช‡ ๋ฒˆ์ด๋‚˜ ๊ทธ๋Ÿฐ ๊ฐ€์งœ ๊ทœ์น™์ด ์ƒ์‚ฐ์— ๋“ค์–ด๊ฐ”์Šต๋‹ˆ๋‹ค.

@Soviut ๋ถˆํ–‰ํžˆ๋„ ๊ทธ๊ฒƒ์€ ์™„์ „ํžˆ ๋‹ค๋ฅธ ์›Œํฌ ํ”Œ๋กœ์šฐ์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” Less๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๊ทธ๊ฒƒ์„ ํฌ๊ธฐํ•  ์ค€๋น„๊ฐ€๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค ... ๋˜ํ•œ ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋” ์ ์€ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ํŽ˜์ด์ง€๋กœ๋“œ๊ฐ€ 500-700ms์—์„œ 2-3 ์ดˆ๋กœ ์ฆ๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ์˜ต์…˜์ด ์ถ”๊ฐ€๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ์ดํ•ดํ•˜๊ณ  ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฌธ์ œ๊ฐ€ ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ์–ด๋–ค ์†Œ์Šค ์ฝ”๋“œ ํŒŒ์ผ์—์„œ ์Šค์Šค๋กœ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ์‹ค ์ˆ˜ ์žˆ๋‚˜์š”?

์ด๊ฒƒ์„ ๋ณ€๊ฒฝํ•ด๋ณด์‹ญ์‹œ์˜ค

https://github.com/cloudhead/less.js/blob/master/lib/less/tree/ruleset.js#L187

@chetzof ๋‚˜๋Š” ์ด๊ฒƒ์— ๋Œ€ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์•Œ์•„ ๋ƒˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์ด ์ตœ์„ ์˜ ๋ฐฉ๋ฒ•์€ ์•„๋‹ˆ์ง€๋งŒ ์ฐพ๊ณ  ์žˆ๋Š” ๊ฒƒ์— ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” ๊ทธ๋ ‡๊ฒŒ ๋‘์—ˆ์Šต๋‹ˆ๋‹ค :

์„ ํƒ๊ธฐ { /**/ }

๋ฐฉํ™”๋ฒ”์—์„œ๋Š” ๋น„์–ด ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ฉ๋‹ˆ๋‹ค.

@d4ng3rmax ์ฟจํฌ์ธํŠธ!
@chetzof๊ฐ€ ์–ธ๊ธ‰ํ•œ ๊ฒƒ๊ณผ ๋™์ผํ•œ ๊ฐœ๋ฐœ ์›Œํฌํ”Œ๋กœ๊ฐ€ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
๊ณ ๋งˆ์›Œ.

์ด๊ฒƒ์€ css-modules ๊ฐœ๋ฐœํ•˜๋Š” ๋™์•ˆ ๊ผญ ํ•„์š”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์Šค์บํด๋”ฉ ๋™์•ˆ ๋ชจ๋“  ์„ ํƒ์ž๋ฅผ ์ƒ์šฉ๊ตฌ๋กœ ๋งŒ๋“  ๋‹ค์Œ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง ๊ท€์ฐฎ์€ ์ผ์ž…๋‹ˆ๋‹ค.

.main {
/*! keep */
}

.loading {
/*! keep */
}

.button {
/*! keep */
}

.form {
/*! keep */
}

@garkin CSS ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ด์™€ ๊ฐ™์€ ์„ ํƒ๊ธฐ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์œ„ํ•œ ์ถ”๋ก /์‚ฌ์šฉ ์‚ฌ๋ก€๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๊ฐ€์ ธ์˜ค๊ธฐ ๋‹จ๊ณ„์—์„œ undefined ๋ฉ๋‹ˆ๋‹ค.

import * as React from 'react'
import * as cx from 'classnames';
import css from './home.less';

export class Home extends React.Component {
    render() {
        const isLoading = true;
        return <div className={cx(css.main, {
            [css.loading]: isLoading
         })}>
            Home
        </div>
    }
}

์ด๋กœ ์ธํ•ด ๋Ÿฐํƒ€์ž„ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ํ•ซ ๋ชจ๋“ˆ ๊ต์ฒด๊ฐ€ ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค. ์„ ํƒ๊ธฐ๊ฐ€ ์ œ๊ฑฐ๋˜์ง€ ์•Š๋„๋ก ํ•˜๋ฉด ์ด๋Ÿฌํ•œ ๋ชจ๋“  ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ ์Šค์บํด๋”ฉ ์ค‘์—๋Š” ์„ ํƒ์ž๊ฐ€ ์ œ๊ฑฐ๋˜๊ณ  ์ด๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ปดํŒŒ์ผ๋Ÿฌ์™€ ์‹ธ์›Œ์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ํ•ญ์ƒ ์—ผ๋‘์— ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ๋ชจ๋“  /*! keep */ ๋Œ“๊ธ€์€ ํ–ฅํ›„ ์–ธ์  ๊ฐ€๋Š” ์ œ๊ฑฐ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

@garkin ํ ... ๊ทธ๋ƒฅ ์Šคํƒ€์ผ์‹œํŠธ ์ž‘์„ฑ์„ ๋๋‚ด๋Š” ๊ฒŒ ๋‹ต ์•„๋‹Œ๊ฐ€์š”? ์ด ๊ฐœ๋ฐœ ๋ฐฉ์‹์œผ๋กœ๋งŒ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ๋‚ด๊ฐ€ ์ผํ•˜๋Š” ๊ณณ์—์„œ๋Š” ํŒ€์— ๋”ฐ๋ผ Less ๋ฐ Sass๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํ˜„์žฌ Sass ๋นŒ๋“œ ์„ค์ •์—์„œ๋Š” ๋นˆ ์„ ํƒ๊ธฐ๊ฐ€ ๋ฆฐํŒ…์„ ํ†ต๊ณผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์•ฑ์ด ์ปดํŒŒ์ผ๋˜์ง€ ์•Š์Œ). ๊ทธ๋ž˜์„œ CSS ๋ชจ๋“ˆ/๋ฆฌ์•กํŠธ๋กœ ์ ‘๊ทผ ๋ฐฉ์‹์„ ๋ณ€๊ฒฝํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๋Š” ๋ฐ”๋กœ ์ด ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

{
     [css.loading]: isLoading
}

์ด ํŒจํ„ด์œผ๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

<div className={`${isLoading && css.loading}`}></div>

๊ท€ํ•˜์˜ ์˜ˆ์—์„œ๋Š” ์ •์˜๋˜์ง€ ์•Š์€ ์ด๋ฆ„์œผ๋กœ ๊ฐœ์ฒด ์†์„ฑ์„ ์ •์˜ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ๋…ผ๋ฆฌ๋ฅผ ์ „ํ™˜ํ•˜๋ฉด ํด๋ž˜์Šค๊ฐ€ ์ •์˜๋˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

"์Šคํƒ€์ผ์‹œํŠธ ์ž‘์„ฑ ์™„๋ฃŒ"๋ผ๊ณ  ํ•˜๋Š” ์ด ์ž‘์—…์—๋Š” ํŠน์ • ์ธ์ง€ ์ปจํ…์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ์ƒ๋‹นํ•œ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋งˆํฌ์—…๊ณผ HMR ์ž‘์—…์ด ์žˆ๋Š” ์Šค์บํด๋”ฉ ๋‹จ๊ณ„ ํ›„์— ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ์‰ฝ์Šต๋‹ˆ๋‹ค.

์ด ํŒจํ„ด์€ ์ง€๋ฐฐ์ ์ด๋ฉฐ ๋ฐ˜๊ณต์‹์ ์ธ ์‚ฌ์šฉ ์ง€์นจ์ด๋ฉฐ ์–ผ๋งˆ ์ „ React ๋ฐฐํฌํŒ์˜ ์ผ๋ถ€์˜€์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด ์ƒ˜ํ”Œ์€ ๋ถ„๋ช…ํžˆ ์ฆ๋ฅ˜๋ฉ๋‹ˆ๋‹ค. ๋‹น์‹ ์˜ ๊ธธ์€ ์ฝ์„ ์ˆ˜๋„ ์—†๊ณ  ํ™•์žฅํ•  ์ˆ˜๋„ ์—†์Šต๋‹ˆ๋‹ค.

return <div className={cx(css.post, sharedCss.frame, {
    [css.support]: post.isSupport,
    [css.foreign]: showTranslation,
    [css.private]: post.isInternal,
    [css.cached]: post.status.isLoading
    ...
})}>...</div>

CSS ๋ชจ๋“ˆ์€ ์˜ค๋Š˜๋‚  ์Šคํƒ€์ผ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์ฃผ์š” ์ ‘๊ทผ ๋ฐฉ์‹์ด๋ฉฐ ์•ž์œผ๋กœ๋„ ๊ทธ๋Ÿด ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋นˆ ์„ ํƒ๊ธฐ ์ œ๊ฑฐ - CSS ๋ชจ๋“ˆ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ๋•Œ ์ฝ”๋“œ ์˜๋ฏธ๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์ด ๋™์ž‘์€ ์ตœ์†Œํ•œ ๊ตฌ์„ฑ์„ ํ†ตํ•ด ํ”ผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ทธ ํฅ๋ฏธ ๋กญ๊ตฐ์š”. ๋‹ค์‹œ ์—ฌ๋Š” ๊ฒƒ์€ ์œ ์Šค ์ผ€์ด์Šค๋ฅผ ์œ„ํ•ด์„œ๊ฐ€ ์•„๋‹ˆ๋ผ Less๊ฐ€ CSS๋ฅผ "์ฒญ์†Œ"ํ•˜๋Š” ์ผ์„ ํ•ด์„œ๋Š” ์•ˆ ๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. compress ์˜ต์…˜์€ ๋น„์Šทํ•œ ์ด์œ ๋กœ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฆ‰, ์„ ํƒ๊ธฐ๋ฅผ ์ œ๊ฑฐ/์••์ถ•/์ ‘๋‘์‚ฌ ์ถ”๊ฐ€ ๋“ฑ์˜ ์œ ์ง€ ๊ด€๋ฆฌ ๋„๊ตฌ๊ฐ€ ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋™์ž‘์€ ๋นˆ ์„ ํƒ๊ธฐ๊ฐ€ ๋ธŒ๋ผ์šฐ์ €์™€ ๊ด€๋ จ์ด ์—†์„ ๋•Œ ์ƒ์„ฑ๋˜์—ˆ์ง€๋งŒ CSS ๋ชจ๋“ˆ์„ ๊ณ ๋ คํ•  ๋•Œ ๋ฐ์ดํ„ฐ์™€ ๊ด€๋ จ์ด ์—†๋‹ค๋Š” ๊ฒƒ์€ ์–ด๋Š ์ •๋„ ํƒ€๋‹นํ•ฉ๋‹ˆ๋‹ค.

์‚ฌ์‹ค ๋ˆ„๊ตฐ๊ฐ€ ์ด์˜๋ฅผ ์ œ๊ธฐํ•˜์ง€ ์•Š๋Š” ํ•œ ์ด๊ฒƒ์€ ์˜ต์…˜์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. IMO๋Š” removeEmptyRulesets (์„ ํƒ์ž๊ฐ€ ์•„๋‹˜)์ด๊ณ  ๊ธฐ๋ณธ๊ฐ’์€ true ์ž…๋‹ˆ๋‹ค.

ํŽธ์ง‘: ์•„๋‹ˆ๋ฉด ๊ธฐ๋ณธ๊ฐ’์ด false keepEmptyRulesets ์—ฌ์•ผ ํ•ฉ๋‹ˆ๊นŒ? ๐Ÿค” ์ •์˜๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ž˜๋ชป๋œ ๊ฒ€์‚ฌ๋ฅผ ์‰ฝ๊ฒŒ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ›„์ž์ผ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’์Šต๋‹ˆ๋‹ค.

CSS ๋ชจ๋“ˆ์„ ๊ณ ๋ คํ•  ๋•Œ

๊ทธ๋ฆฌ๊ณ  ๊ทธ๊ฒƒ์€ ๊ทธ๋“ค์—๊ฒŒ๋งŒ ๊ตญํ•œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. CSSOM์„ ํ†ตํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹ ์•ก์„ธ์Šค์™€ ๊ฐ™์€ ๊ฒƒ๋„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

keepEmptyRulesets ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
์žฅํ™ฉํ•œ ์ธก๋ฉด์—์„œ ์กฐ๊ธˆ, ์•„๋งˆ๋„. CLI์— ์ข‹์ง€ ์•Š์Œ: --keep-empty-rulesets

์žฅํ™ฉํ•œ ์ธก๋ฉด์—์„œ ์•ฝ๊ฐ„, ์•„๋งˆ๋„

๋™์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค๋งŒ ๋‹ค๋ฅธ ์ œ์•ˆ์ด ์žˆ์œผ์‹ญ๋‹ˆ๊นŒ? ๊ทธ๊ฒƒ์€ ๋งค์šฐ ๊ตฌ์ฒด์ ์ธ ํ–‰๋™์ฒ˜๋Ÿผ ๋ณด์ด๊ธฐ ๋•Œ๋ฌธ์— ๋•Œ๋กœ๋Š” ๋ช…์‹œ์ ์ธ ๊ฒƒ์ด ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. API์—์„œ๋Š” keepEmptyRulesets ์ด๊ณ  CLI์—์„œ๋Š” --keep-rulesets ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋˜๋Š” ์‹ฌ์ง€์–ด --keep-empty

๋‘˜ ๋‹ค keepEmpty ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๊นŒ?

๋‚˜๋Š” ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค :

  1. API ์˜ต์…˜์œผ๋กœ outputEmptyRulesets : true|false ;
  2. --empty-rulesets ๋ฅผ ์ „์ฒด ํ˜•์‹ CLI ํ† ๊ธ€๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ 
  3. -er ๋˜๋Š” -empty ๋ฅผ ์•ฝ์‹ CLI ํ† ๊ธ€๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

@rjgotten ์ €๋Š” ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ๋‚˜๋Š” ๊ฐ์ •์ ์œผ๋กœ ํˆฌ์žํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค lol. @garkin - ์ด์— ๋Œ€ํ•ด ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์‹ญ๋‹ˆ๊นŒ?

๋‚˜์—๊ฒŒ๋Š” ๊ดœ์ฐฎ์•„ ๋ณด์ธ๋‹ค.

์‹ค์ œ ๊ตฌํ˜„์€ ์–ธ์ œ ์˜ˆ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๊นŒ?
์ด๊ฒƒ์€ ์šฐ๋ฆฌ์—๊ฒŒ๋„ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

@orchidoris ํ™๋ณด ํ™˜์˜ํ•ฉ๋‹ˆ๋‹ค!

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ• ํ”Œ๋Ÿฌ๊ทธ์ธ...

๋ชจ๋“  ์„ ํƒ๊ธฐ์— __NOOP__: 1; ๋ฅผ ์ถ”๊ฐ€ํ•œ ๋‹ค์Œ ๋œ ์™„๋ฃŒ๋˜๋ฉด ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

class NoopPreProcessor {      
    process = (css, extra) => css.replace(/}/g, ';__NOOP__: 1;}');                                                                      
}      

class NoopPostProcessor {      
    process = (css, extra) => css.replace(/__NOOP__: 1;/g, '');                                                                               
}                                                                                                                       

const NoopPlugin = {                                                                                                    
    install: (less, pluginManager) => {                             
        pluginManager.addPreProcessor(new NoopPreProcessor());        
        pluginManager.addPostProcessor(new NoopPostProcessor());      
    },                                                                
}; 


๋กœ๋”๊ฐ€ ์ ์€ preact์˜ ๊ฒฝ์šฐ:

    helpers.getLoaders(config)                                                             
        .filter(item => item.ruleIndex===1)      
        .map(item => {                           
            item.loaders[0].options.options.stictMath = true;      
            item.loaders[0].options.options.plugins = [            
                NoopPlugin,                                        
            ];                                                     

            item.loaders[0].options.options.paths = [      
                ...item.loaders[0].options.options.paths[0],      
                path.resolve(__dirname, 'src'),                   
            ];                                                    
        });                                                       
์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰