UNPKG

4.31 kBJavaScriptView Raw
1'use strict';
2
3var fs = require('fs');
4var path = require('path');
5var rollupPluginutils = require('rollup-pluginutils');
6
7function css (options) {
8 if ( options === void 0 ) options = {};
9
10 var filter = rollupPluginutils.createFilter(options.include || ['/**/*.css', '/**/*.scss', '/**/*.sass'], options.exclude);
11 var dest = options.output;
12
13 var styles = {};
14 var includePaths = options.includePaths || [];
15 includePaths.push(process.cwd());
16
17 var compileToCSS = function (scss) {
18 // Compile SASS to CSS
19 if (scss.length) {
20 includePaths = includePaths.filter(function (v, i, a) { return a.indexOf(v) === i; });
21 try {
22 var css = require('node-sass').renderSync(Object.assign({
23 data: scss,
24 includePaths: includePaths
25 }, options)).css.toString();
26 // Possibly process CSS (e.g. by PostCSS)
27 if (typeof options.processor === 'function') {
28 return options.processor(css, styles)
29 }
30 return css
31 } catch (e) {
32 if (options.failOnError) {
33 throw e
34 }
35 console.log();
36 console.log(red('Error:\n\t' + e.message));
37 if (e.message.includes('Invalid CSS')) {
38 console.log(green('Solution:\n\t' + 'fix your Sass code'));
39 console.log('Line: ' + e.line);
40 console.log('Column: ' + e.column);
41 }
42 if (e.message.includes('node-sass') && e.message.includes('find module')) {
43 console.log(green('Solution:\n\t' + 'npm install --save node-sass'));
44 }
45 if (e.message.includes('node-sass') && e.message.includes('bindigs')) {
46 console.log(green('Solution:\n\t' + 'npm rebuild node-sass --force'));
47 }
48 console.log();
49 }
50 }
51 };
52
53 return {
54 name: 'css',
55 transform: function transform (code, id) {
56 if (!filter(id)) {
57 return
58 }
59
60 // When output is disabled, the stylesheet is exported as a string
61 if (options.output === false) {
62 var css = compileToCSS(code);
63 return {
64 code: 'export default ' + JSON.stringify(css),
65 map: { mappings: '' }
66 }
67 }
68
69 // Map of every stylesheet
70 styles[id] = code;
71 includePaths.push(path.dirname(id));
72
73 return ''
74 },
75 generateBundle: function generateBundle (opts) {
76 // No stylesheet needed
77 if (options.output === false) {
78 return
79 }
80
81 // Combine all stylesheets
82 var scss = '';
83 for (var id in styles) {
84 scss += styles[id] || '';
85 }
86
87 var css = compileToCSS(scss);
88
89 // Resolve if porcessor returned a Promise
90 Promise.resolve(css).then(function (css) {
91 // Emit styles through callback
92 if (typeof options.output === 'function') {
93 options.output(css, styles);
94 return
95 }
96
97 if (typeof dest !== 'string') {
98 // Don't create unwanted empty stylesheets
99 if (!css.length) {
100 return
101 }
102
103 // Guess destination filename
104 dest = opts.dest || opts.file || 'bundle.js';
105 if (dest.endsWith('.js')) {
106 dest = dest.slice(0, -3);
107 }
108 dest = dest + '.css';
109 }
110
111 // Ensure that dest parent folders exist (create the missing ones)
112 ensureParentDirsSync(path.dirname(dest));
113
114 // Emit styles to file
115 fs.writeFile(dest, css, function (err) {
116 if (opts.verbose !== false) {
117 if (err) {
118 console.error(red(err));
119 } else if (css) {
120 console.log(green(dest), getSize(css.length));
121 }
122 }
123 });
124 });
125 }
126 }
127}
128
129function red (text) {
130 return '\x1b[1m\x1b[31m' + text + '\x1b[0m'
131}
132
133function green (text) {
134 return '\x1b[1m\x1b[32m' + text + '\x1b[0m'
135}
136
137function getSize (bytes) {
138 return bytes < 10000
139 ? bytes.toFixed(0) + ' B'
140 : bytes < 1024000
141 ? (bytes / 1024).toPrecision(3) + ' kB'
142 : (bytes / 1024 / 1024).toPrecision(4) + ' MB'
143}
144
145function ensureParentDirsSync (dir) {
146 if (fs.existsSync(dir)) {
147 return
148 }
149
150 try {
151 fs.mkdirSync(dir);
152 } catch (err) {
153 if (err.code === 'ENOENT') {
154 ensureParentDirsSync(path.dirname(dir));
155 ensureParentDirsSync(dir);
156 }
157 }
158}
159
160module.exports = css;