Skip to content

Commit 66545d6

Browse files
committed
docs: css preprocessors support
1 parent ef5ae91 commit 66545d6

7 files changed

+205
-241
lines changed

README.md

+13
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ The generated project has dependencies that require **Node 4 or greater**.
3333
* [Deploying the App via GitHub Pages](#deploying-the-app-via-github-pages)
3434
* [Support for offline applications](#support-for-offline-applications)
3535
* [Commands autocompletion](#commands-autocompletion)
36+
* [CSS preprocessor integration](#css-preprocessor-integration)
3637
* [Known Issues](#known-issues)
3738

3839
## Installation
@@ -249,6 +250,18 @@ ng completion >> ~/.bash_profile
249250
source ~/.bash_profile
250251
```
251252

253+
254+
### CSS Preprocessor integration
255+
256+
We support all major CSS preprocessors:
257+
- sass (node-sass)
258+
- less (less)
259+
- compass (compass-importer + node-sass)
260+
- stylus (stylus)
261+
262+
To use one just install for example `npm install node-sass` and rename `.css` files in your project to `.scss` or `.sass`. They will be compiled automatically.
263+
264+
252265
## Known issues
253266

254267
This project is currently a prototype so there are many known issues. Just to mention a few:
+46-59
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,66 @@
11
/* jshint node: true, esversion: 6 */
22
'use strict';
33

4+
let sass;
5+
let compass;
46
try {
5-
let sass;
6-
let compass;
7-
8-
if (process.platform === 'win32') {
9-
require.resolve(`${process.env.PWD}/node_modules/node-sass`);
10-
require.resolve(`${process.env.PWD}/node_modules/compass-importer`);
11-
sass = require(`${process.env.PWD}/node_modules/node-sass`);
12-
compass = require(`${process.env.PWD}/node_modules/compass-importer`);
13-
} else {
14-
process.env.NODE_PATH += `:${process.env.PWD}/node_modules`;
15-
require('module').Module._initPaths();
16-
require.resolve('node-sass');
17-
require.resolve('compass-importer');
18-
sass = require('node-sass');
19-
compass = require('compass-importer');
7+
try {
8+
sass = require('sass');
9+
compass = require('compass');
10+
} catch (e) {
11+
sass = require(`${process.env.PROJECT_ROOT}/node_modules/node-sass`);
12+
compass = require(`${process.env.PROJECT_ROOT}/node_modules/compass-importer`);
2013
}
14+
} catch (e) {
15+
sass = null;
16+
compass = null;
17+
}
2118

22-
const Plugin = require('broccoli-caching-writer');
23-
const fse = require('fs-extra');
24-
const path = require('path');
25-
const Funnel = require('broccoli-funnel');
26-
27-
class CompassPlugin extends Plugin {
28-
constructor(inputNodes, options) {
29-
super(inputNodes, {});
19+
const Plugin = require('broccoli-caching-writer');
20+
const fse = require('fs-extra');
21+
const path = require('path');
22+
const Funnel = require('broccoli-funnel');
3023

31-
options = options || {};
32-
Plugin.call(this, inputNodes, {
33-
cacheInclude: [/(.*?).scss$/, /(.*?).sass$/]
34-
});
35-
this.options = options;
36-
this.fileRegistry = [];
37-
}
24+
class CompassPlugin extends Plugin {
25+
constructor(inputNodes, options) {
26+
super(inputNodes, {});
3827

39-
build() {
40-
let entries = this.listEntries();
41-
let rootFileNames = entries.map(e => {
42-
return path.resolve(e.basePath, e.relativePath);
43-
});
28+
options = options || {};
29+
Plugin.call(this, inputNodes, {
30+
cacheInclude: [/(.*?).scss$/, /(.*?).sass$/]
31+
});
32+
this.options = options;
33+
}
4434

45-
rootFileNames.forEach(fileName => {
46-
this.compile(fileName, this.inputPaths[0], this.outputPath);
47-
});
48-
}
35+
build() {
36+
this.listEntries().forEach(e => {
37+
let fileName = path.resolve(e.basePath, e.relativePath);
38+
this.compile(fileName, this.inputPaths[0], this.outputPath);
39+
});
40+
}
4941

50-
compile(fileName, inputPath, outputPath) {
51-
let sassOptions = {
52-
file: path.join(fileName),
53-
includePaths: this.inputPaths,
54-
data: '@import "compass"; .transition { @include transition(all); }',
55-
importer: compass
56-
};
42+
compile(fileName, inputPath, outputPath) {
43+
let sassOptions = {
44+
file: path.normalize(fileName),
45+
includePaths: this.inputPaths,
46+
data: '@import "compass"; .transition { @include transition(all); }',
47+
importer: compass
48+
};
5749

58-
let result = sass.renderSync(sassOptions);
59-
let filePath = fileName.replace(inputPath, outputPath)
60-
.replace(/\.scss$/, '.css')
61-
.replace(/\.sass$/, '.css');
50+
let result = sass.renderSync(sassOptions);
51+
let filePath = fileName.replace(inputPath, outputPath).replace(/\.s[ac]ss$/, '.css');
6252

63-
fse.outputFileSync(filePath, result.css, 'utf8');
64-
}
53+
fse.outputFileSync(filePath, result.css, 'utf8');
6554
}
55+
}
6656

67-
exports.makeBroccoliTree = (sourceDir) => {
57+
exports.makeBroccoliTree = (sourceDir) => {
58+
if (sass && compass) {
6859
let compassSrcTree = new Funnel(sourceDir, {
6960
include: ['**/*.scss', '**/*.sass'],
7061
allowEmpty: true
7162
});
7263

7364
return new CompassPlugin([compassSrcTree]);
74-
};
75-
} catch (e) {
76-
exports.makeBroccoliTree = () => {
77-
return null;
78-
};
79-
}
65+
}
66+
};

lib/broccoli/angular-broccoli-less.js

+39-49
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,59 @@
11
/* jshint node: true, esversion: 6 */
22
'use strict';
33

4+
let less;
45
try {
5-
let less;
6-
7-
if (process.platform === 'win32') {
8-
require.resolve(`${process.env.PWD}/node_modules/less`);
9-
less = require(`${process.env.PWD}/node_modules/less`);
10-
} else {
11-
process.env.NODE_PATH += `:${process.env.PWD}/node_modules`;
12-
require('module').Module._initPaths();
13-
require.resolve('less');
6+
try {
147
less = require('less');
8+
} catch (e) {
9+
less = require(`${process.env.PROJECT_ROOT}/node_modules/less`);
1510
}
11+
} catch (e) {
12+
less = null
13+
}
1614

17-
const Plugin = require('broccoli-caching-writer');
18-
const fs = require('fs');
19-
const fse = require('fs-extra');
20-
const path = require('path');
21-
const Funnel = require('broccoli-funnel');
15+
const Plugin = require('broccoli-caching-writer');
16+
const fs = require('fs');
17+
const fse = require('fs-extra');
18+
const path = require('path');
19+
const Funnel = require('broccoli-funnel');
2220

23-
class LESSPlugin extends Plugin {
24-
constructor(inputNodes, options) {
25-
super(inputNodes, {});
21+
class LESSPlugin extends Plugin {
22+
constructor(inputNodes, options) {
23+
super(inputNodes, {});
2624

27-
options = options || {};
28-
Plugin.call(this, inputNodes, {
29-
cacheInclude: [/(.*?).less$/]
30-
});
31-
this.options = options;
32-
this.fileRegistry = [];
33-
}
34-
35-
build() {
36-
let entries = this.listEntries();
37-
let rootFileNames = entries.map(e => {
38-
return path.resolve(e.basePath, e.relativePath);
39-
});
25+
options = options || {};
26+
Plugin.call(this, inputNodes, {
27+
cacheInclude: [/(.*?).less$/]
28+
});
29+
this.options = options;
30+
}
4031

41-
return Promise.all(rootFileNames.map(fileName => {
42-
return this.compile(fileName, this.inputPaths[0], this.outputPath);
43-
}));
44-
}
32+
build() {
33+
return Promise.all(this.listEntries().map(e => {
34+
let fileName = path.resolve(e.basePath, e.relativePath);
35+
return this.compile(fileName, this.inputPaths[0], this.outputPath);
36+
}));
37+
}
4538

46-
compile(fileName, inputPath, outputPath) {
47-
let content = fs.readFileSync(fileName, 'utf8');
39+
compile(fileName, inputPath, outputPath) {
40+
let content = fs.readFileSync(fileName, 'utf8');
4841

49-
return less.render(content)
50-
.then(output => {
51-
let filePath = fileName.replace(inputPath, outputPath).replace(/\.less$/, '.css');
52-
fse.outputFileSync(filePath, output.css, 'utf8');
53-
});
54-
}
42+
return less.render(content)
43+
.then(output => {
44+
let filePath = fileName.replace(inputPath, outputPath).replace(/\.less$/, '.css');
45+
fse.outputFileSync(filePath, output.css, 'utf8');
46+
});
5547
}
48+
}
5649

57-
exports.makeBroccoliTree = (sourceDir) => {
50+
exports.makeBroccoliTree = (sourceDir) => {
51+
if (less) {
5852
let lessSrcTree = new Funnel(sourceDir, {
5953
include: ['**/*.less'],
6054
allowEmpty: true
6155
});
6256

6357
return new LESSPlugin([lessSrcTree]);
64-
};
65-
} catch (e) {
66-
exports.makeBroccoliTree = () => {
67-
return null;
68-
};
69-
}
58+
}
59+
};

lib/broccoli/angular-broccoli-sass.js

+39-51
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,60 @@
11
/* jshint node: true, esversion: 6 */
22
'use strict';
33

4+
let sass;
45
try {
5-
let sass;
6-
7-
if (process.platform === 'win32') {
8-
require.resolve(`${process.env.PWD}/node_modules/node-sass`);
9-
sass = require(`${process.env.PWD}/node_modules/node-sass`);
10-
} else {
11-
process.env.NODE_PATH += `:${process.env.PWD}/node_modules`;
12-
require('module').Module._initPaths();
13-
require.resolve('node-sass');
6+
try {
147
sass = require('node-sass');
8+
} catch (e) {
9+
sass = require(`${process.env.PROJECT_ROOT}/node_modules/node-sass`);
1510
}
11+
} catch (e) {
12+
sass = null;
13+
}
1614

17-
const Plugin = require('broccoli-caching-writer');
18-
const fse = require('fs-extra');
19-
const path = require('path');
20-
const Funnel = require('broccoli-funnel');
21-
22-
class SASSPlugin extends Plugin {
23-
constructor(inputNodes, options) {
24-
super(inputNodes, {});
15+
const Plugin = require('broccoli-caching-writer');
16+
const fse = require('fs-extra');
17+
const path = require('path');
18+
const Funnel = require('broccoli-funnel');
2519

26-
options = options || {};
27-
Plugin.call(this, inputNodes, {
28-
cacheInclude: [/(.*?).scss$/, /(.*?).sass$/]
29-
});
30-
this.options = options;
31-
this.fileRegistry = [];
32-
}
20+
class SASSPlugin extends Plugin {
21+
constructor(inputNodes, options) {
22+
super(inputNodes, {});
3323

34-
build() {
35-
let entries = this.listEntries();
36-
let rootFileNames = entries.map(e => {
37-
return path.resolve(e.basePath, e.relativePath);
38-
});
24+
options = options || {};
25+
Plugin.call(this, inputNodes, {
26+
cacheInclude: [/(.*?).scss$/, /(.*?).sass$/]
27+
});
28+
this.options = options;
29+
}
3930

40-
rootFileNames.forEach(fileName => {
41-
this.compile(fileName, this.inputPaths[0], this.outputPath);
42-
});
43-
}
31+
build() {
32+
this.listEntries().forEach(e => {
33+
let fileName = path.resolve(e.basePath, e.relativePath);
34+
this.compile(fileName, this.inputPaths[0], this.outputPath);
35+
});
36+
}
4437

45-
compile(fileName, inputPath, outputPath) {
46-
let sassOptions = {
47-
file: path.join(fileName),
48-
includePaths: this.inputPaths
49-
};
38+
compile(fileName, inputPath, outputPath) {
39+
let sassOptions = {
40+
file: path.join(fileName),
41+
includePaths: this.inputPaths
42+
};
5043

51-
let result = sass.renderSync(sassOptions);
52-
let filePath = fileName.replace(inputPath, outputPath)
53-
.replace(/\.scss$/, '.css')
54-
.replace(/\.sass$/, '.css');
44+
let result = sass.renderSync(sassOptions);
45+
let filePath = fileName.replace(inputPath, outputPath).replace(/\.s[ac]ss$/, '.css');
5546

56-
fse.outputFileSync(filePath, result.css, 'utf8');
57-
}
47+
fse.outputFileSync(filePath, result.css, 'utf8');
5848
}
49+
}
5950

60-
exports.makeBroccoliTree = (sourceDir) => {
51+
exports.makeBroccoliTree = (sourceDir) => {
52+
if (sass) {
6153
let sassSrcTree = new Funnel(sourceDir, {
6254
include: ['**/*.sass', '**/*.scss'],
6355
allowEmpty: true
6456
});
6557

6658
return new SASSPlugin([sassSrcTree]);
67-
};
68-
} catch (e) {
69-
exports.makeBroccoliTree = () => {
70-
return null;
71-
};
72-
}
59+
}
60+
};

0 commit comments

Comments
 (0)