Gruntfile.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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: {
  51. sequences: true,
  52. dead_code: true,
  53. conditionals: true,
  54. booleans: true,
  55. unused: true,
  56. if_return: true,
  57. join_vars: true,
  58. drop_console: true
  59. },
  60. sourceMap: true,
  61. sourceMapName: 'dist/waves.min.js.map',
  62. preserveComments: 'some'
  63. },
  64. js: {
  65. files: {
  66. 'dist/waves.min.js': ['src/js/waves.js']
  67. }
  68. }
  69. },
  70. // Copy to dist
  71. copy: {
  72. js: {
  73. expand: true,
  74. cwd: 'src/js',
  75. src: 'waves.js',
  76. dest: 'dist/'
  77. },
  78. docs: {
  79. expand: true,
  80. cwd: 'dist',
  81. src: ['waves.min.css', 'waves.min.js'],
  82. dest: 'docs/static'
  83. }
  84. },
  85. //convert less to stylus
  86. execute: {
  87. less2stylus: {
  88. call: function(grunt, options, async) {
  89. var done = async();
  90. var exec = require('child_process').exec;
  91. exec('cd node_modules/less2stylus && node ./less2stylus ../../src/less/waves.less', function (error, stdout, stderr) {
  92. grunt.log.writeln('Executing less2styus...');
  93. if (error) {
  94. grunt.log.writeln('Error! ' + error);
  95. }
  96. var fs = require('fs');
  97. fs.writeFile("src/stylus/waves.styl", stdout, function(err) {
  98. if(err) {
  99. grunt.log.writeln(err);
  100. } else {
  101. grunt.log.writeln("Stylus file was saved!");
  102. }
  103. done(); // let grunt resume
  104. });
  105. });
  106. }
  107. },
  108. less2scss: {
  109. //FUTURE: Put less2scss as it's own script
  110. call: function(grunt, options, async) {
  111. var done = async();
  112. var text = fs.readFileSync('src/less/waves.less', {encoding:'utf8'});
  113. //replace @ with $
  114. text = text.replace(/@(?!import|media|keyframes|-)/g, '$');
  115. //replace mixins
  116. text = text.replace(/\.([\w\-]*)\s*\((.*)\)\s*\{/g, '@mixin $1($2){');
  117. //replace includes
  118. text = text.replace(/\.([\w\-]*\(.*\)\s*;)/g, '@include $1');
  119. //replace string literals
  120. //eg. ~'!important' -> #{"!important"}
  121. text = text.replace(/~(?:\"|\')(.*)(?:\"|\')/g, '#{"$1"}');
  122. //NOTE: for true less->scss transpiling we'd need to replace spin to adjust-hue (not needed but anyway)
  123. fs.writeFileSync('src/scss/waves.scss', text);
  124. done();
  125. }
  126. },
  127. test: {
  128. call: function(grunt, options, async) {
  129. var done = async();
  130. var lessTest = fs.readFileSync('tests/less/waves.min.css', {encoding:'utf8'});
  131. var sassTest = fs.readFileSync('tests/sass/waves.min.css', {encoding:'utf8'});
  132. var scssTest = fs.readFileSync('tests/scss/waves.min.css', {encoding:'utf8'});
  133. var stylusTest = fs.readFileSync('tests/stylus/waves.min.css', {encoding:'utf8'});
  134. var failure = false;
  135. if (lessTest != sassTest) {
  136. grunt.log.writeln('ERROR: sass failed test.');
  137. failure = true;
  138. }
  139. if (lessTest != scssTest) {
  140. grunt.log.writeln('ERROR: scss failed test.');
  141. failure = true;
  142. }
  143. if (lessTest != stylusTest) {
  144. grunt.log.writeln('ERROR: stylus failed test.');
  145. failure = true;
  146. }
  147. if (sassTest != scssTest) {
  148. grunt.log.writeln('WARNING: sass files aren\'t equal?');
  149. failure = true;
  150. }
  151. if (!failure) grunt.log.writeln('PASS: conversions generated same CSS');
  152. done();
  153. }
  154. }
  155. },
  156. 'sass-convert': {
  157. options: {
  158. from: 'scss',
  159. to: 'sass',
  160. indent: 2
  161. },
  162. files: {
  163. cwd: 'src/scss',
  164. src: '*.scss',
  165. dest: 'src/sass'
  166. }
  167. },
  168. sass: {
  169. test: {
  170. files: [{
  171. expand: true,
  172. cwd: 'src',
  173. src: ['**/*.sass', '**/*.scss'],
  174. dest: 'tests/',
  175. ext: '.css'
  176. }]
  177. }
  178. },
  179. stylus: {
  180. test: {
  181. files: {
  182. 'tests/stylus/waves.css': 'src/stylus/waves.styl'
  183. }
  184. }
  185. },
  186. clean: {
  187. test: ['tests/*']
  188. },
  189. watch: {
  190. script: {
  191. options: {
  192. spawn: false,
  193. event: ['added', 'deleted', 'changed']
  194. },
  195. files: ['src/**/*.js', 'src/**/*.less'],
  196. tasks: ['build']
  197. },
  198. grunt: {
  199. files: ['Gruntfile.js']
  200. }
  201. }
  202. });
  203. // Load module
  204. grunt.loadNpmTasks('grunt-contrib-concat');
  205. grunt.loadNpmTasks('grunt-contrib-less');
  206. grunt.loadNpmTasks('grunt-contrib-jshint');
  207. grunt.loadNpmTasks('grunt-contrib-uglify');
  208. grunt.loadNpmTasks('grunt-contrib-copy');
  209. grunt.loadNpmTasks('grunt-contrib-watch');
  210. grunt.loadNpmTasks('grunt-contrib-sass');
  211. grunt.loadNpmTasks('grunt-contrib-stylus');
  212. grunt.loadNpmTasks('grunt-execute');
  213. grunt.loadNpmTasks('grunt-sass-convert');
  214. grunt.loadNpmTasks('grunt-contrib-clean');
  215. // Create grunt task
  216. grunt.registerTask('build', [
  217. 'less:build',
  218. 'less:minified',
  219. 'jshint',
  220. 'uglify',
  221. 'copy',
  222. 'execute:less2stylus',
  223. 'execute:less2scss',
  224. 'sass-convert',
  225. 'sass:test',
  226. 'stylus:test',
  227. 'less:test',
  228. 'execute:test',
  229. 'clean:test'
  230. ]);
  231. grunt.registerTask('default', ['build', 'watch']);
  232. };