Skip to content

Commit 3fa1f6f

Browse files
committed
docs: css preprocessors support
1 parent ef5ae91 commit 3fa1f6f

6 files changed

+187
-225
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:
+44-60
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,63 @@
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');
20-
}
21-
22-
const Plugin = require('broccoli-caching-writer');
23-
const fse = require('fs-extra');
24-
const path = require('path');
25-
const Funnel = require('broccoli-funnel');
7+
sass = require(`${process.env.PWD}/node_modules/node-sass`);
8+
compass = require(`${process.env.PWD}/node_modules/compass-importer`);
9+
} catch (e) {
10+
sass = null;
11+
compass = null;
12+
}
2613

27-
class CompassPlugin extends Plugin {
28-
constructor(inputNodes, options) {
29-
super(inputNodes, {});
14+
const Plugin = require('broccoli-caching-writer');
15+
const fse = require('fs-extra');
16+
const path = require('path');
17+
const Funnel = require('broccoli-funnel');
3018

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

39-
build() {
40-
let entries = this.listEntries();
41-
let rootFileNames = entries.map(e => {
42-
return path.resolve(e.basePath, e.relativePath);
43-
});
23+
options = options || {};
24+
Plugin.call(this, inputNodes, {
25+
cacheInclude: [/(.*?).scss$/, /(.*?).sass$/]
26+
});
27+
this.options = options;
28+
}
4429

45-
rootFileNames.forEach(fileName => {
46-
this.compile(fileName, this.inputPaths[0], this.outputPath);
47-
});
48-
}
30+
build() {
31+
this.listEntries().forEach(e => {
32+
let fileName = path.resolve(e.basePath, e.relativePath);
33+
this.compile(fileName, this.inputPaths[0], this.outputPath);
34+
});
35+
}
4936

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-
};
37+
compile(fileName, inputPath, outputPath) {
38+
let sassOptions = {
39+
file: path.normalize(fileName),
40+
includePaths: this.inputPaths,
41+
data: '@import "compass"; .transition { @include transition(all); }',
42+
importer: compass
43+
};
5744

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

63-
fse.outputFileSync(filePath, result.css, 'utf8');
64-
}
48+
fse.outputFileSync(filePath, result.css, 'utf8');
6549
}
50+
}
6651

67-
exports.makeBroccoliTree = (sourceDir) => {
52+
exports.makeBroccoliTree = (sourceDir) => {
53+
if (sass && compass) {
6854
let compassSrcTree = new Funnel(sourceDir, {
6955
include: ['**/*.scss', '**/*.sass'],
7056
allowEmpty: true
7157
});
7258

7359
return new CompassPlugin([compassSrcTree]);
74-
};
75-
} catch (e) {
76-
exports.makeBroccoliTree = () => {
77-
return null;
78-
};
79-
}
60+
} else {
61+
return;
62+
}
63+
};

lib/broccoli/angular-broccoli-less.js

+39-51
Original file line numberDiff line numberDiff line change
@@ -1,69 +1,57 @@
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');
14-
less = require('less');
15-
}
16-
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');
6+
less = require(`${process.env.PWD}/node_modules/less`);
7+
} catch (e) {
8+
less = null
9+
}
2210

23-
class LESSPlugin extends Plugin {
24-
constructor(inputNodes, options) {
25-
super(inputNodes, {});
11+
const Plugin = require('broccoli-caching-writer');
12+
const fs = require('fs');
13+
const fse = require('fs-extra');
14+
const path = require('path');
15+
const Funnel = require('broccoli-funnel');
2616

27-
options = options || {};
28-
Plugin.call(this, inputNodes, {
29-
cacheInclude: [/(.*?).less$/]
30-
});
31-
this.options = options;
32-
this.fileRegistry = [];
33-
}
17+
class LESSPlugin extends Plugin {
18+
constructor(inputNodes, options) {
19+
super(inputNodes, {});
3420

35-
build() {
36-
let entries = this.listEntries();
37-
let rootFileNames = entries.map(e => {
38-
return path.resolve(e.basePath, e.relativePath);
39-
});
21+
options = options || {};
22+
Plugin.call(this, inputNodes, {
23+
cacheInclude: [/(.*?).less$/]
24+
});
25+
this.options = options;
26+
}
4027

41-
return Promise.all(rootFileNames.map(fileName => {
42-
return this.compile(fileName, this.inputPaths[0], this.outputPath);
43-
}));
44-
}
28+
build() {
29+
return Promise.all(this.listEntries().map(e => {
30+
let fileName = path.resolve(e.basePath, e.relativePath);
31+
return this.compile(fileName, this.inputPaths[0], this.outputPath);
32+
}));
33+
}
4534

46-
compile(fileName, inputPath, outputPath) {
47-
let content = fs.readFileSync(fileName, 'utf8');
35+
compile(fileName, inputPath, outputPath) {
36+
let content = fs.readFileSync(fileName, 'utf8');
4837

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-
}
38+
return less.render(content)
39+
.then(output => {
40+
let filePath = fileName.replace(inputPath, outputPath).replace(/\.less$/, '.css');
41+
fse.outputFileSync(filePath, output.css, 'utf8');
42+
});
5543
}
44+
}
5645

57-
exports.makeBroccoliTree = (sourceDir) => {
46+
exports.makeBroccoliTree = (sourceDir) => {
47+
if (less) {
5848
let lessSrcTree = new Funnel(sourceDir, {
5949
include: ['**/*.less'],
6050
allowEmpty: true
6151
});
6252

6353
return new LESSPlugin([lessSrcTree]);
64-
};
65-
} catch (e) {
66-
exports.makeBroccoliTree = () => {
67-
return null;
68-
};
69-
}
54+
} else {
55+
return;
56+
}
57+
};

lib/broccoli/angular-broccoli-sass.js

+39-53
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,58 @@
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');
14-
sass = require('node-sass');
15-
}
16-
17-
const Plugin = require('broccoli-caching-writer');
18-
const fse = require('fs-extra');
19-
const path = require('path');
20-
const Funnel = require('broccoli-funnel');
6+
sass = require(`${process.env.PWD}/node_modules/node-sass`);
7+
} catch (e) {
8+
sass = null;
9+
}
2110

22-
class SASSPlugin extends Plugin {
23-
constructor(inputNodes, options) {
24-
super(inputNodes, {});
11+
const Plugin = require('broccoli-caching-writer');
12+
const fse = require('fs-extra');
13+
const path = require('path');
14+
const Funnel = require('broccoli-funnel');
2515

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

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

40-
rootFileNames.forEach(fileName => {
41-
this.compile(fileName, this.inputPaths[0], this.outputPath);
42-
});
43-
}
27+
build() {
28+
this.listEntries().forEach(e => {
29+
let fileName = path.resolve(e.basePath, e.relativePath);
30+
this.compile(fileName, this.inputPaths[0], this.outputPath);
31+
});
32+
}
4433

45-
compile(fileName, inputPath, outputPath) {
46-
let sassOptions = {
47-
file: path.join(fileName),
48-
includePaths: this.inputPaths
49-
};
34+
compile(fileName, inputPath, outputPath) {
35+
let sassOptions = {
36+
file: path.join(fileName),
37+
includePaths: this.inputPaths
38+
};
5039

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

56-
fse.outputFileSync(filePath, result.css, 'utf8');
57-
}
43+
fse.outputFileSync(filePath, result.css, 'utf8');
5844
}
45+
}
5946

60-
exports.makeBroccoliTree = (sourceDir) => {
47+
exports.makeBroccoliTree = (sourceDir) => {
48+
if (sass) {
6149
let sassSrcTree = new Funnel(sourceDir, {
6250
include: ['**/*.sass', '**/*.scss'],
6351
allowEmpty: true
6452
});
6553

6654
return new SASSPlugin([sassSrcTree]);
67-
};
68-
} catch (e) {
69-
exports.makeBroccoliTree = () => {
70-
return null;
71-
};
72-
}
55+
} else {
56+
return;
57+
}
58+
};

0 commit comments

Comments
 (0)