Less.js: less.render๋Š” nodejs์˜ ๋‹ค๋ฅธ ๋””๋ ‰ํ† ๋ฆฌ์— ์žˆ๋Š” @import ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

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

๋‚˜๋Š” LESS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ…Œ๋งˆ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  nodejs๋ณด๋‹ค ์ ์€ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜์—ฌ CSS์— ๋” ์ ์€ ํŒŒ์ผ์„ ์ปดํŒŒ์ผํ•˜์ง€๋งŒ ํŠน์ • ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ ๋‚ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— Bootstrap์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์œผ๋ฉฐ Bootstrap์ด ์ ์€ ์†Œ์Šค ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‚ด ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์›ํ•˜๋Š” CSS๋งŒ ์ปดํŒŒ์ผํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์–‘ํ•œ ํ…Œ๋งˆ์—์„œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜์™€ ๋ฏน์Šค์ธ์„ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Bootstrap์„ ์ปดํŒŒ์ผํ•˜๋Š” ๋™์•ˆ ํŠน์ • ํ…Œ๋งˆ ๋ณ€์ˆ˜์™€ ๋ฏน์Šค์ธ๋„ ๊ณ ๋ คํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜/๋ฏน์Šค์ธ๊ณผ CSS ๊ทœ์น™์„ ๊ตฌ๋ณ„ํ•˜์—ฌ 2๊ฐœ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

  • application_variables.less - ํ•„์š”ํ•œ ๋ชจ๋“  ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜ ๋ฐ ๋ฏน์Šค์ธ์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
  • application.less - ํ•„์š”ํ•œ ๋ชจ๋“  ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS ๊ทœ์น™์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ

|--sample_application
    |--resources
    |   |--libraries
    |      |--bootstrap
    |           |--css
    |           |   |--application.less
    |           |--less
    |           |   |--application_variables.less    
    |--themes
        |--red
        |   |--mixins
        |   |   |--mixins.less
        |   |--variables
        |   |   |--variables.less    
        |   |--red.less    
        |--blue
        |   |--mixins
        |   |   |--mixins.less
        |   |--variables
        |   |   |--variables.less    
        |   |--blue.less    
        |--themes.less

์–ด๋–ค ํŒŒ์ผ์ด ๋ฌด์—‡์„ ํฌํ•จํ•˜๋Š”์ง€์— ๋Œ€ํ•œ ์„ค๋ช…์€ ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

1. /sample_application/themes/<-theme_name->/mixins/mixins.less
์ด ํŒŒ์ผ์—๋Š” ๋ชจ๋“  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๋ณ„ ๋ฏน์Šค์ธ๊ณผ ์žฌ์ •์˜๋œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ฏน์Šค์ธ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

.my-hover-mixin(@color) {
   &:hover {
       border: 2px solid @color;
    }
}
/*Other theme specific mixins*/

2. /sample_application/themes/<-theme_name->/variables/variables.less
์ด ํŒŒ์ผ์—๋Š” ๋ชจ๋“  ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๋ณ„ ๋ณ€์ˆ˜์™€ ์žฌ์ •์˜๋œ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

@text-color:#333333;
@border-color:#999999;
@body-bg-color:red;
/*Other theme specific variables*/

3. /sample_application/themes/<-theme_name->/<-theme_name->.less
์ด ํŒŒ์ผ์—๋Š” ํŠน์ • ํ…Œ๋งˆ์— ๋Œ€ํ•œ ๋ฏน์Šค์ธ ๋ฐ ๋ณ€์ˆ˜์˜ ํŒŒ์ผ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

<strong i="10">@import</strong> "./variables/variables.less";
<strong i="11">@import</strong> "./mixins/mixins.less";

4. /sample_application/themes/theme.less
์ด ํŒŒ์ผ์—๋Š” ๋‘ ๊ฐœ์˜ ํŒŒ์ผ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” application_variables.less์ธ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜์— ๋Œ€ํ•œ ๊ฒƒ์ด๊ณ  ๋‘ ๋ฒˆ์งธ๋Š” ํŠน์ • ํ…Œ๋งˆ์˜ ๊ธฐ๋ณธ ํŒŒ์ผ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. red.less/blue.less

<strong i="17">@import</strong> "application_variables.less";
<strong i="18">@import</strong> "red/red.less";

5. /sample_application/resources/libraries/bootstrap/css/application.less
์ด ํŒŒ์ผ์—๋Š” /themes/themes.less ๋ฐ ๋ชจ๋“  ํ•„์ˆ˜ ๋ถ€ํŠธ์ŠคํŠธ๋žฉ CSS ๊ทœ์น™์ธ ํŒŒ์ผ ๊ฐ€์ ธ์˜ค๊ธฐ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

<strong i="24">@import</strong> "theme.less";
/*Bootstrap CSS rules*/

6. /sample_application/resources/libraries/bootstrap/less/application_variables.less
์ด ํŒŒ์ผ์—๋Š” ํ•„์š”ํ•œ ๋ชจ๋“  ๋ถ€ํŠธ์ŠคํŠธ๋žฉ ๋ณ€์ˆ˜์™€ ๋ฏน์Šค์ธ์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

/*Bootstrap variables and mixins*/

์ด์ œ compile-bootstrap.js์ธ ๋ถ€ํŠธ ์ŠคํŠธ๋žฉ์„ ๋œ ์ปดํŒŒ์ผํ•˜๋Š” ํ•˜๋‚˜์˜ ๋…ธ๋“œ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

var fs = require("fs");
var less = require('less');

(function() {
    var bsLessContent = fs.readFileSync("sample_application/resources/libraries/bootstrap/css/application.less");
    less.render(bsLessContent.toString(), {
        paths : [ "sample_application/themes/", "sample_application/resources/libraries/bootstrap/less/"],
        compress : true
    }, function(e, output) {
        fs.writeFileSync("sample_application/resources/libraries/bootstrap/css/application.css", output);
    });
})();

๊ทธ๋Ÿฌ๋‚˜์ด ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

{ [Error: 'application_variables.less' wasn't found]
   type: 'File',
   message: '\'application_variables.less\' wasn\'t found',
   filename: 'sample_application\\themes\\theme.less',
   index: 18,
   line: 2,
   callLine: NaN,
   callExtract: undefined,
   column: 0,
   extract:
    [ '<strong i="6">@import</strong> "application_variables.less";',
      '<strong i="7">@import</strong> "red/red.less";' ] }

๊ทธ๋Ÿฐ ๋‹ค์Œ ์ƒ๋Œ€ ๊ฒฝ๋กœ๋„ ์‚ฌ์šฉํ•ด ๋ณด์•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋™์ผํ•œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

{ [Error: './../resources/libraries/bootstrap/less/application_variables.less' wasn't found]
   type: 'File',
   message: '\'./../resources/libraries/bootstrap/less/application_variables.less\' wasn\'t found',
   filename: 'sample_application\\themes\\theme.less',
   index: 18,
   line: 2,
   callLine: NaN,
   callExtract: undefined,
   column: 0,
   extract:
    [ '<strong i="11">@import</strong> "./../resources/libraries/bootstrap/less/application_variables.less";',
      '<strong i="12">@import</strong> "red/red.less";' ] }

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

์†Œ์Šค๊ฐ€ ๋ฌธ์ž์—ด๋กœ ์ปดํŒŒ์ผ๋Ÿฌ์— ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์›๋ณธ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ๊ฒฝ๋กœ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ง€์ •์€ ์ƒ๋Œ€์ ์ž…๋‹ˆ๋‹ค(๋Œ€๋ถ€๋ถ„ cwd ๋งŒ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ๊ด€๋ จํ•˜์—ฌ ๊ฑฐ์˜ "์ž„์˜"์ด๋ฉฐ ๋” ์ด์ƒ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค...). ์˜ˆ:

var fs   = require('fs'),
    path = require('path'),
    less = require('less');

(function() {
    var src = "foo/bar/baz.less";
    less.render(fs.readFileSync(src).toString(), {
        filename: path.resolve(src), // <- here we go
    }, function(e, output) {
        console.log(output.css);
    });
})();

paths ์˜ต์…˜๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์— ๋‚ด๊ฐ€ ํ‹€๋ฆฌ์ง€ ์•Š์œผ๋ฉด filename ๋Œ€ํ•ด ์ ˆ๋Œ€์ ์ด๊ฑฐ๋‚˜ ์ƒ๋Œ€์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ lessc ์ž์ฒด ๊ฐ€ ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

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

์†Œ์Šค๊ฐ€ ๋ฌธ์ž์—ด๋กœ ์ปดํŒŒ์ผ๋Ÿฌ์— ์ œ๊ณต๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ๊ฐ€์ ธ์˜ค๊ธฐ๋ฅผ ์œ„ํ•œ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ์›๋ณธ ํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ๋ชจ๋“  ๊ฒฝ๋กœ๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์•Œ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์ง€์ •์€ ์ƒ๋Œ€์ ์ž…๋‹ˆ๋‹ค(๋Œ€๋ถ€๋ถ„ cwd ๋งŒ ์‚ฌ์šฉํ•˜์ง€๋งŒ ์‹ค์ œ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ๊ด€๋ จํ•˜์—ฌ ๊ฑฐ์˜ "์ž„์˜"์ด๋ฉฐ ๋” ์ด์ƒ ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค...). ์˜ˆ:

var fs   = require('fs'),
    path = require('path'),
    less = require('less');

(function() {
    var src = "foo/bar/baz.less";
    less.render(fs.readFileSync(src).toString(), {
        filename: path.resolve(src), // <- here we go
    }, function(e, output) {
        console.log(output.css);
    });
})();

paths ์˜ต์…˜๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ์— ๋‚ด๊ฐ€ ํ‹€๋ฆฌ์ง€ ์•Š์œผ๋ฉด filename ๋Œ€ํ•ด ์ ˆ๋Œ€์ ์ด๊ฑฐ๋‚˜ ์ƒ๋Œ€์ ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ lessc ์ž์ฒด ๊ฐ€ ์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ฐฐ์šฐ๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Seven-phases-max๋‹˜, ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ด ์†”๋ฃจ์…˜์€ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜๋ฏ€๋กœ ๋ฌธ์ œ๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰