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.

326 lines
8.2 KiB

  1. module.exports = function(grunt) {
  2. var
  3. site = grunt.file.readJSON('build.config'),
  4. // shortcut
  5. paths = site.paths,
  6. defaultTasks = [
  7. // run grunt watch
  8. 'watch'
  9. ],
  10. watchTasks = [
  11. // compiles less
  12. 'less:build',
  13. // copy js
  14. 'copy:file',
  15. // auto prefix modified file
  16. 'autoprefixer:prefixFile',
  17. // creates minified js of modified file if it is js
  18. 'newer:uglify:minifyOutput',
  19. // creates minified css of modified file if it is css
  20. 'newer:cssmin:minifyOutput',
  21. // create concatenated css release if modified file is css
  22. 'newer:concat:createCSSPackage',
  23. // create concatenated js release if modified file is js
  24. 'newer:concat:createJSPackage'
  25. ],
  26. resetTasks = [
  27. // clean build directory
  28. 'clean:output'
  29. ],
  30. buildTasks = [
  31. // clean build directory
  32. 'clean:output',
  33. // compiles less definitions
  34. 'less:buildAll',
  35. // copy assets
  36. 'copy:uncompressedAssets',
  37. 'copy:minifiedAssets',
  38. 'copy:packagedAssets',
  39. // copy javascript definitions
  40. 'copy:javascript',
  41. // auto prefix all modified files
  42. 'autoprefixer:prefixOutput',
  43. // creates minified js of each output file
  44. 'uglify:minifyOutput',
  45. // creates minified css of each output file
  46. 'cssmin:minifyOutput',
  47. // create concatenated css release
  48. 'concat:createCSSPackage',
  49. // create concatenated js release
  50. 'concat:createJSPackage'
  51. ],
  52. setWatchFiles = function(action, filePath) {
  53. var
  54. outputPath = filePath.replace(paths.source.definitions, paths.output.uncompressed + 'definitions/'),
  55. regExp = new RegExp(paths.source.themes + '.*\/([^\/]*\/[^\/]*)\.(?:overrides|variables)$')
  56. ;
  57. // convert backslashes to slashes for Windows compatibility
  58. if(process.platform === 'win32') {
  59. filePath = filePath.replace(/\\/g, '/');
  60. }
  61. // find relevant .less file for each modified .overrides or .variables file
  62. if(filePath.search(regExp) !== -1) {
  63. filePath = filePath.replace(regExp, paths.source.definitions + '$1.less');
  64. }
  65. // build less and prefix
  66. if(filePath.search('.less') !== -1) {
  67. outputPath = outputPath.replace('less', 'css');
  68. grunt.config('less.build.src', filePath);
  69. grunt.config('less.build.dest', outputPath);
  70. grunt.config('autoprefixer.prefixFile.src', outputPath);
  71. }
  72. // copy just the one js file
  73. else if(filePath.search('.js') !== -1) {
  74. grunt.config('copy.file.src', filePath);
  75. grunt.config('copy.file.dest', outputPath);
  76. }
  77. // do nothing
  78. else {
  79. grunt.config('less.build.src', 'non/existant/path');
  80. grunt.config('less.build.dest', 'non/existant/path');
  81. grunt.config('autoprefixer.prefixFile.src', 'non/existant/path');
  82. }
  83. },
  84. // this allows filenames with multiple extensions to be preserved
  85. preserveFileExtensions = function(folder, filename) {
  86. return folder + filename.substring(0, filename.lastIndexOf('.') ) + '.css';
  87. },
  88. preserveMinFileExtensions = function(folder, filename) {
  89. return folder + filename.substring(0, filename.lastIndexOf('.') ) + '.min.css';
  90. },
  91. config
  92. ;
  93. config = {
  94. site : site,
  95. paths : site.paths,
  96. /*******************************
  97. Watch
  98. *******************************/
  99. // watches for changes in a source folder
  100. watch: {
  101. options: {
  102. spawn: false
  103. },
  104. src: {
  105. files: [
  106. paths.source.definitions + '**/*.less',
  107. paths.source.themes + '**/*.variables',
  108. paths.source.themes + '**/*.overrides',
  109. paths.source.definitions + '**/*.js'
  110. ],
  111. tasks : watchTasks
  112. }
  113. },
  114. /*******************************
  115. Test
  116. *******************************/
  117. // Clear terminal output
  118. clear: {
  119. terminal: {}
  120. },
  121. // Configured at run time
  122. copy: {
  123. file: {},
  124. uncompressedAssets: {
  125. expand: true,
  126. cwd: paths.source.themes,
  127. src : [
  128. [
  129. '**/assets/**/*'
  130. ]
  131. ],
  132. dest : paths.output.uncompressed + '/themes'
  133. },
  134. minifiedAssets: {
  135. expand: true,
  136. cwd: paths.source.themes,
  137. src : [
  138. [
  139. '**/assets/**/*'
  140. ]
  141. ],
  142. dest : paths.output.minified + '/themes'
  143. },
  144. packagedAssets: {
  145. expand: true,
  146. cwd: paths.source.themes,
  147. src : [
  148. [
  149. '**/assets/**/*'
  150. ]
  151. ],
  152. dest : paths.output.packaged + '/themes'
  153. },
  154. javascript: {
  155. expand : true,
  156. cwd : paths.source.definitions,
  157. src : ['**/*.js'],
  158. dest : paths.output.uncompressed + '/definitions/'
  159. }
  160. },
  161. less: {
  162. options: {
  163. paths : ['src'],
  164. compress : false,
  165. optimization : 2
  166. },
  167. build: {
  168. rename : preserveFileExtensions
  169. },
  170. buildAll: {
  171. expand : true,
  172. cwd : paths.source.definitions,
  173. src : ['**/*.less'],
  174. dest : paths.output.uncompressed + '/definitions/',
  175. rename : preserveFileExtensions
  176. }
  177. },
  178. // Clean a folder
  179. clean: {
  180. options: {
  181. force: true
  182. },
  183. output : [
  184. paths.output.uncompressed,
  185. paths.output.minified,
  186. paths.output.packaged
  187. ]
  188. },
  189. // Prefix
  190. autoprefixer: {
  191. options: {
  192. browsers: site.support
  193. },
  194. prefixOutput: {
  195. expand : true,
  196. cwd : paths.output.uncompressed,
  197. dest : paths.output.uncompressed,
  198. src : [
  199. '**/*.css'
  200. ]
  201. },
  202. prefixFile: {
  203. src : paths.output.uncompressed + '**/*.css'
  204. }
  205. },
  206. // Minify
  207. cssmin: {
  208. options : {
  209. keepSpecialComments: 0,
  210. report: 'min',
  211. banner : '' +
  212. '/*\n' +
  213. '* # Semantic UI ' +
  214. '* http://github.com/semantic-org/semantic-ui\n' +
  215. '*\n' +
  216. '* Copyright <%= grunt.template.today("yyyy") %> \n' +
  217. '* Built: <%= grunt.template.today("mm/dd/yyyy") %>\n' +
  218. '*/\n'
  219. },
  220. minifyOutput: {
  221. expand : true,
  222. cwd : paths.output.uncompressed,
  223. src : [
  224. '**/*.css'
  225. ],
  226. dest : paths.output.minified,
  227. rename : preserveMinFileExtensions
  228. }
  229. },
  230. // Minify JS
  231. uglify: {
  232. minifyOutput: {
  233. expand : true,
  234. cwd : paths.output.uncompressed,
  235. src : [
  236. '**/*.js'
  237. ],
  238. dest : paths.output.minified,
  239. ext : '.min.js',
  240. banner : '' +
  241. '/*' +
  242. '* # Semantic UI\n' +
  243. '* http://github.com/semantic-org/semantic-ui\n' +
  244. '*\n' +
  245. '* Copyright <%= grunt.template.today("yyyy") %> Contributors\n' +
  246. '*\n' +
  247. '* Build Date: <%= grunt.template.today("mm/dd/yyyy") %>\n' +
  248. '*/\n'
  249. }
  250. },
  251. concat: {
  252. options: {
  253. },
  254. createCSSPackage: {
  255. src: [ paths.output.minified + '**/*.css'],
  256. dest: paths.output.packaged + 'definitions/css/semantic.css'
  257. },
  258. createJSPackage: {
  259. src: [ paths.output.minified + '**/*.js'],
  260. dest: paths.output.packaged + 'definitions/js/semantic.js'
  261. }
  262. }
  263. };
  264. // filesys & terminal
  265. grunt.loadNpmTasks('grunt-contrib-clean');
  266. grunt.loadNpmTasks('grunt-contrib-watch');
  267. grunt.loadNpmTasks('grunt-contrib-copy');
  268. grunt.loadNpmTasks('grunt-clear');
  269. grunt.loadNpmTasks('grunt-contrib-concat');
  270. grunt.loadNpmTasks('grunt-newer');
  271. // css
  272. grunt.loadNpmTasks('grunt-contrib-cssmin');
  273. grunt.loadNpmTasks('grunt-contrib-less');
  274. grunt.loadNpmTasks('grunt-autoprefixer');
  275. // javascript
  276. grunt.loadNpmTasks('grunt-contrib-uglify');
  277. grunt.initConfig(config);
  278. grunt.registerTask('default', defaultTasks);
  279. grunt.registerTask('build', buildTasks);
  280. grunt.registerTask('reset', resetTasks);
  281. // compiles only changed less files <https://npmjs.org/package/grunt-contrib-watch>
  282. grunt.event.on('watch', setWatchFiles);
  283. };