UNPKG

4.13 kBJavaScriptView Raw
1'use strict';
2const path = require('path');
3const jdfUtils = require('jdf-utils');
4const $ = jdfUtils.base;
5const f = jdfUtils.file;
6const logger = require('jdf-log');
7
8//外部组件
9const Sass = require('node-sass');
10const Less = require('less');
11const postcss = require('postcss');
12const autoprefixer = require('autoprefixer');
13
14const jdf = require('./jdf');
15const VFS = require('./VFS/VirtualFileSystem');
16
17let buildCss = module.exports = {};
18
19buildCss.init = function () {
20 logger.profile('parse css');
21 return VFS.go()
22 .then(() => {
23 return VFS.travel((vfile, done) => {
24 let oPath = vfile.originPath;
25 if ($.is.sass(oPath)) {
26 done.push(buildCss.handleSass(vfile));
27 } else if ($.is.less(oPath)) {
28 done.push(buildCss.handleLess(vfile));
29 } else if ($.is.css(oPath)) {
30 done.push(buildCss.handleCss(vfile));
31 }
32 });
33 })
34 .then(() => {
35 return VFS.travel((vfile, done) => {
36 if (buildCss.isCssRelative(vfile)) {
37 done.push(buildCss.postCSSProcess(vfile));
38 }
39 });
40 })
41 .then(() => {
42 logger.profile('parse css');
43 return Promise.resolve();
44 });
45}
46
47buildCss.handleSass = function (vfile) {
48 return new Promise (function (resolve, reject) {
49 let oPath = vfile.originPath;
50 logger.verbose(`parse sass: ${oPath}`);
51 Sass.render({
52 file: oPath,
53 outputStyle: 'expanded',
54 importer: function(url, prev, done){
55 var extname = path.extname(url);
56
57 if(extname == '.sass' || extname == '.scss' || extname == '.css'){
58 return {file: url};
59 }else{
60 return {file: url += (path.extname(prev))};
61 }
62
63 }
64 }, function (err, result) {
65 if (err) {
66 logger.error(err.formatted);
67 reject(err);
68 return;
69 }
70 vfile.targetContent = result.css.toString();
71 if (!vfile.targetPath) {
72 vfile.targetPath = vfile.originPath;
73 }
74 vfile.targetPath = vfile.targetPath.replace(/scss$/, 'css');
75 resolve();
76 });
77 });
78}
79
80buildCss.handleLess = function (vfile) {
81 return new Promise(function (resolve, reject) {
82 let lessContent;
83 if (!vfile.originContent) {
84 lessContent = f.read(vfile.originPath);
85 } else {
86 lessContent = vfile.originContent;
87 }
88
89 logger.verbose(`parse less: ${vfile.originPath}`);
90 Less.render(lessContent, {filename: vfile.originPath, syncImport: true})
91 .then(function (output) {
92 vfile.originContent = lessContent;
93 vfile.targetContent = output.css;
94 if (!vfile.targetPath) {
95 vfile.targetPath = vfile.originPath;
96 }
97 vfile.targetPath = vfile.targetPath.replace(/less$/, 'css');
98 resolve();
99 }, function (err) {
100 logger.error(`parse less file ${fileFullPath}`);
101 console.log(err);
102 reject(err);
103 });
104 });
105}
106
107buildCss.handleCss = function (vfile) {
108 return vfile;
109}
110
111buildCss.postCSSProcess = function (vfile) {
112 // 更多插件可以再扩展
113 let cssAutoPrefixer = jdf.config.output.cssAutoPrefixer;
114 let browsers = jdf.config.output.browserslist || [];
115 let plugins = [autoprefixer({remove: cssAutoPrefixer, browsers: browsers})];
116 logger.verbose(`postcss - autoprefixer: parsed ${vfile.originPath}`);
117 return new Promise(function (resolve, reject) {
118 postcss(plugins)
119 .process(vfile.targetContent)
120 .then(result => {
121 vfile.targetContent = result.css;
122 resolve();
123 })
124 .catch(err => {
125 reject(err);
126 });
127 });
128}
129
130buildCss.isCssRelative = function (vfile) {
131 let oPath = vfile.originPath;
132 if (!($.is.less(oPath) || $.is.sass(oPath) || $.is.css(oPath))) {
133 return false;
134 }
135 return true;
136}
137