You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.js 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. 'use strict';
  2. var PluginError = require('plugin-error');
  3. var Vinyl = require('vinyl');
  4. var path = require('path');
  5. var rework = require('rework');
  6. var reworkImport = require('rework-import');
  7. var through = require('through2');
  8. var parseImport = require('parse-import');
  9. var reworkUrl = require('rework-plugin-url');
  10. var defaults = require('lodash.defaults');
  11. module.exports = function(destFile, options) {
  12. var buffer = [];
  13. var firstFile, commonBase;
  14. var destDir = path.dirname(destFile);
  15. var urlImportRules = [];
  16. options = defaults({}, options, {
  17. inlineImports: true,
  18. rebaseUrls: true,
  19. includePaths: [],
  20. commonBase: null
  21. });
  22. return through.obj(function(file, enc, cb) {
  23. var processedCss;
  24. if (file.isStream()) {
  25. this.emit('error', new PluginError('gulp-concat-css', 'Streaming not supported'));
  26. return cb();
  27. }
  28. if(!firstFile) {
  29. firstFile = file;
  30. commonBase = options.commonBase || file.base;
  31. }
  32. function urlPlugin(file) {
  33. return reworkUrl(function(url) {
  34. if(isUrl(url) || isDataURI(url) || path.extname(url) === '.css' || path.resolve(url) === url) {
  35. return url;
  36. }
  37. var resourceAbsUrl = path.relative(commonBase, path.resolve(path.dirname(file), url));
  38. resourceAbsUrl = path.relative(destDir, resourceAbsUrl);
  39. //not all systems use forward slash as path separator
  40. //this is required by urls.
  41. if(path.sep === '\\'){
  42. //replace with forward slash
  43. resourceAbsUrl = resourceAbsUrl.replace(/\\/g, '/');
  44. }
  45. return resourceAbsUrl;
  46. });
  47. }
  48. function collectImportUrls(styles) {
  49. var outRules = [];
  50. styles.rules.forEach(function(rule) {
  51. if(rule.type !== 'import') {
  52. return outRules.push(rule);
  53. }
  54. var importData = parseImport('@import ' + rule.import + ';');
  55. var importPath = importData && importData[0].path;
  56. if(isUrl(importPath) || !options.inlineImports) {
  57. return urlImportRules.push(rule);
  58. }
  59. return outRules.push(rule);
  60. });
  61. styles.rules = outRules;
  62. }
  63. function processNestedImport(contents) {
  64. var rew = rework(contents,{source:this.source});//find the css file has syntax errors
  65. if(options.rebaseUrls) {
  66. rew = rew.use(urlPlugin(this.source));
  67. }
  68. rew = rew.use(collectImportUrls);
  69. return rew.toString();
  70. }
  71. try {
  72. processedCss = rework(String(file.contents||""),{source:file.path});//find the css file has syntax errors
  73. if(options.rebaseUrls) {
  74. processedCss = processedCss.use(urlPlugin(file.path));
  75. }
  76. processedCss = processedCss.use(collectImportUrls);
  77. if(options.inlineImports) {
  78. processedCss = processedCss.use(reworkImport({
  79. path: [
  80. '.',
  81. path.dirname(file.path)
  82. ].concat(options.includePaths),
  83. transform: processNestedImport
  84. }))
  85. .toString();
  86. }
  87. processedCss = processedCss.toString();
  88. } catch(err) {
  89. this.emit('error', new PluginError('gulp-concat-css', err));
  90. return cb();
  91. }
  92. buffer.push(processedCss);
  93. cb();
  94. }, function(cb) {
  95. if(!firstFile) {
  96. return cb();
  97. }
  98. var contents = urlImportRules.map(function(rule) {
  99. return '@import ' + rule.import + ';';
  100. }).concat(buffer).join('\n');
  101. var concatenatedFile = new Vinyl({
  102. base: firstFile.base,
  103. cwd: firstFile.cwd,
  104. path: path.join(firstFile.base, destFile),
  105. contents: new Buffer(contents)
  106. });
  107. this.push(concatenatedFile);
  108. cb();
  109. });
  110. };
  111. function isUrl(url) {
  112. return (/^([\w]+:)?\/\/./).test(url);
  113. }
  114. function isDataURI(url) {
  115. return url && url.indexOf('data:') === 0;
  116. }