Gruntfile.js 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. var fs = require('fs');
  2. module.exports = function(grunt) {
  3. grunt.initConfig({
  4. less: {
  5. build: {
  6. options: {},
  7. files: {
  8. 'dist/waves.css': 'src/less/waves.less'
  9. }
  10. },
  11. minified: {
  12. options: {
  13. cleancss:true
  14. },
  15. files: {
  16. 'dist/waves.min.css': 'src/less/waves.less'
  17. }
  18. },
  19. // re-minify everything in tests/ so that they all
  20. // have the same minification for comparision
  21. test: {
  22. options: {
  23. cleancss:true,
  24. cleancssOptions: {
  25. keepSpecialComments:'0'
  26. }
  27. },
  28. files: {
  29. 'tests/less/waves.min.css': 'src/less/waves.less',
  30. 'tests/sass/waves.min.css': 'tests/sass/waves.css',
  31. 'tests/scss/waves.min.css': 'tests/scss/waves.css',
  32. 'tests/stylus/waves.min.css': 'tests/stylus/waves.css'
  33. }
  34. }
  35. },
  36. jshint: {
  37. files: [
  38. 'gruntfile.js',
  39. 'src/js/*.js',
  40. ],
  41. options: {
  42. globals: {
  43. console: true
  44. }
  45. }
  46. },
  47. uglify: {
  48. options: {
  49. mangle: true, // false when debugging
  50. compress: true, // false when debugging
  51. sourceMap: true,
  52. sourceMapName: 'dist/waves.min.js.map',
  53. preserveComments: 'some'
  54. },
  55. js: {
  56. files: {
  57. 'dist/waves.min.js': ['src/js/waves.js']
  58. }
  59. }
  60. },
  61. // Copy to dist
  62. copy: {
  63. js: {
  64. expand: true,
  65. cwd: 'src/js',
  66. src: 'waves.js',
  67. dest: 'dist/'
  68. },
  69. docs: {
  70. expand: true,
  71. cwd: 'dist',
  72. src: ['waves.min.css', 'waves.min.js'],
  73. dest: 'docs/static'
  74. }
  75. },
  76. //convert less to stylus
  77. execute: {
  78. less2stylus: {
  79. call: function(grunt, options, async) {
  80. var done = async();
  81. var exec = require('child_process').exec;
  82. exec('cd node_modules/less2stylus && ./less2stylus ../../src/less/waves.less', function (error, stdout, stderr) {
  83. grunt.log.writeln('Executing less2styus...');
  84. if (error) {
  85. grunt.log.writeln('Error! ' + error);
  86. }
  87. var fs = require('fs');
  88. fs.writeFile("src/stylus/waves.styl", stdout, function(err) {
  89. if(err) {
  90. grunt.log.writeln(err);
  91. } else {
  92. grunt.log.writeln("Stylus file was saved!");
  93. }
  94. done(); // let grunt resume
  95. });
  96. });
  97. }
  98. },
  99. less2scss: {
  100. //FUTURE: Put less2scss as it's own script
  101. call: function(grunt, options, async) {
  102. var done = async();
  103. var text = fs.readFileSync('src/less/waves.less', {encoding:'utf8'});
  104. //replace @ with $
  105. text = text.replace(/@(?!import|media|keyframes|-)/g, '$');
  106. //replace mixins
  107. text = text.replace(/\.([\w\-]*)\s*\((.*)\)\s*\{/g, '@mixin $1($2){');
  108. //replace includes
  109. text = text.replace(/\.([\w\-]*\(.*\)\s*;)/g, '@include $1');
  110. //replace string literals
  111. //eg. ~'!important' -> #{"!important"}
  112. text = text.replace(/~(?:\"|\')(.*)(?:\"|\')/g, '#{"$1"}');
  113. //NOTE: for true less->scss transpiling we'd need to replace spin to adjust-hue (not needed but anyway)
  114. fs.writeFileSync('src/scss/waves.scss', text);
  115. done();
  116. }
  117. },
  118. test: {
  119. call: function(grunt, options, async) {
  120. var done = async();
  121. var lessTest = fs.readFileSync('tests/less/waves.min.css', {encoding:'utf8'});
  122. var sassTest = fs.readFileSync('tests/sass/waves.min.css', {encoding:'utf8'});
  123. var scssTest = fs.readFileSync('tests/scss/waves.min.css', {encoding:'utf8'});
  124. var stylusTest = fs.readFileSync('tests/stylus/waves.min.css', {encoding:'utf8'});
  125. var failure = false;
  126. if (lessTest != sassTest) {
  127. grunt.log.writeln('ERROR: sass failed test.');
  128. failure = true;
  129. }
  130. if (lessTest != scssTest) {
  131. grunt.log.writeln('ERROR: scss failed test.');
  132. failure = true;
  133. }
  134. if (lessTest != stylusTest) {
  135. grunt.log.writeln('ERROR: stylus failed test.');
  136. failure = true;
  137. }
  138. if (sassTest != scssTest) {
  139. grunt.log.writeln('WARNING: sass files aren\'t equal?');
  140. failure = true;
  141. }
  142. if (!failure) grunt.log.writeln('PASS: conversions generated same CSS');
  143. done();
  144. }
  145. }
  146. },
  147. 'sass-convert': {
  148. options: {
  149. from: 'scss',
  150. to: 'sass',
  151. indent: 2
  152. },
  153. files: {
  154. cwd: 'src/scss',
  155. src: '*.scss',
  156. dest: 'src/sass'
  157. }
  158. },
  159. sass: {
  160. test: {
  161. files: [{
  162. expand: true,
  163. cwd: 'src',
  164. src: ['**/*.sass', '**/*.scss'],
  165. dest: 'tests/',
  166. ext: '.css'
  167. }]
  168. }
  169. },
  170. stylus: {
  171. test: {
  172. files: {
  173. 'tests/stylus/waves.css': 'src/stylus/waves.styl'
  174. }
  175. }
  176. },
  177. clean: {
  178. test: ['tests/*']
  179. },
  180. watch: {
  181. script: {
  182. options: {
  183. spawn: false,
  184. event: ['added', 'deleted', 'changed']
  185. },
  186. files: ['src/**/*.js', 'src/**/*.less'],
  187. tasks: ['build']
  188. },
  189. grunt: {
  190. files: ['Gruntfile.js']
  191. }
  192. }
  193. });
  194. // Load module
  195. grunt.loadNpmTasks('grunt-contrib-concat');
  196. grunt.loadNpmTasks('grunt-contrib-less');
  197. grunt.loadNpmTasks('grunt-contrib-jshint');
  198. grunt.loadNpmTasks('grunt-contrib-uglify');
  199. grunt.loadNpmTasks('grunt-contrib-copy');
  200. grunt.loadNpmTasks('grunt-contrib-watch');
  201. grunt.loadNpmTasks('grunt-contrib-sass');
  202. grunt.loadNpmTasks('grunt-contrib-stylus');
  203. grunt.loadNpmTasks('grunt-execute');
  204. grunt.loadNpmTasks('grunt-sass-convert');
  205. grunt.loadNpmTasks('grunt-contrib-clean');
  206. // Create grunt task
  207. grunt.registerTask('build', [
  208. 'less:build',
  209. 'less:minified',
  210. 'jshint',
  211. 'uglify',
  212. 'copy',
  213. 'execute:less2stylus',
  214. 'execute:less2scss',
  215. 'sass-convert',
  216. 'sass:test',
  217. 'stylus:test',
  218. 'less:test',
  219. 'execute:test',
  220. 'clean:test'
  221. ]);
  222. grunt.registerTask('default', ['build', 'watch']);
  223. };