gulpfile.js 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. /* eslint-env node */
  2. const autoprefix = require('autoprefixer')
  3. const browserSync = require('browser-sync').create()
  4. const del = require('del')
  5. const { src, dest, lastRun, watch, series } = require('gulp')
  6. const cleanCss = require('gulp-clean-css')
  7. const eslint = require('gulp-eslint7')
  8. const fileinclude = require('gulp-file-include')
  9. const gulpIf = require('gulp-if')
  10. const npmDist = require('gulp-npm-dist')
  11. const postcss = require('gulp-postcss')
  12. const rename = require('gulp-rename')
  13. const sass = require('gulp-sass')(require('sass'))
  14. const gulpStylelint = require('gulp-stylelint')
  15. const rollup = require('rollup')
  16. const rollupTypescript = require('@rollup/plugin-typescript')
  17. const rtlcss = require('rtlcss')
  18. const pkg = require('./package')
  19. const year = new Date().getFullYear()
  20. const banner = `/*!
  21. * AdminLTE v${pkg.version} (${pkg.homepage})
  22. * Copyright 2014-${year} ${pkg.author}
  23. * Licensed under MIT (https://github.com/ColorlibHQ/AdminLTE/blob/master/LICENSE)
  24. */`
  25. // Define paths
  26. const paths = {
  27. dist: {
  28. base: './dist/',
  29. css: './dist/css',
  30. html: './dist/pages',
  31. assets: './dist/assets',
  32. vendor: './dist/vendor'
  33. },
  34. src: {
  35. base: './src/',
  36. html: './src/pages/**/*.html',
  37. assets: './src/assets/**/*.*',
  38. partials: './src/partials/**/*.html',
  39. scss: './src/scss',
  40. ts: './src/ts',
  41. nodeModules: './node_modules/'
  42. },
  43. temp: {
  44. base: './.temp/',
  45. css: './.temp/css',
  46. js: './.temp/js',
  47. html: './.temp/pages',
  48. assets: './.temp/assets',
  49. vendor: './.temp/vendor'
  50. }
  51. }
  52. const sassOptions = {
  53. outputStyle: 'expanded',
  54. includePaths: ['./node_modules/']
  55. }
  56. const postcssOptions = [
  57. autoprefix({ cascade: false })
  58. ]
  59. const postcssRtlOptions = [
  60. autoprefix({ cascade: false }),
  61. rtlcss({})
  62. ]
  63. // From here Dev mode will Start
  64. // Compile SCSS
  65. const scss = () => src(paths.src.scss + '/adminlte.scss', { sourcemaps: true })
  66. .pipe(sass(sassOptions).on('error', sass.logError))
  67. .pipe(postcss(postcssOptions))
  68. .pipe(dest(paths.temp.css, { sourcemaps: '.' }))
  69. .pipe(browserSync.stream())
  70. // Compile SCSS Dark
  71. const scssDark = () => src(paths.src.scss + '/dark/adminlte-dark-addon.scss', { sourcemaps: true })
  72. .pipe(sass(sassOptions).on('error', sass.logError))
  73. .pipe(postcss(postcssOptions))
  74. .pipe(dest(paths.temp.css + '/dark', { sourcemaps: '.' }))
  75. .pipe(browserSync.stream())
  76. // Lint SCSS
  77. const lintScss = () => src([paths.src.scss + '/**/*.scss'], { since: lastRun(lintScss) })
  78. .pipe(gulpStylelint({
  79. failAfterError: false,
  80. reporters: [
  81. { formatter: 'string', console: true }
  82. ]
  83. }))
  84. const tsCompile = () =>
  85. rollup.rollup({
  86. input: paths.src.ts + '/adminlte.ts',
  87. output: {
  88. banner
  89. },
  90. plugins: [
  91. rollupTypescript()
  92. ]
  93. }).then(bundle => bundle.write({
  94. file: paths.temp.js + '/adminlte.js',
  95. format: 'umd',
  96. name: 'adminlte',
  97. sourcemap: true
  98. }))
  99. // Lint TS
  100. function isFixed(file) {
  101. // Has ESLint fixed the file contents?
  102. return file.eslint !== null && file.eslint.fixed
  103. }
  104. const lintTs = () => src([paths.src.ts + '/**/*.ts'], { since: lastRun(lintTs) })
  105. .pipe(eslint({ fix: true }))
  106. .pipe(eslint.format())
  107. .pipe(gulpIf(isFixed, dest(paths.src.ts)))
  108. .pipe(eslint.failAfterError())
  109. const index = () => src([paths.src.base + '*.html'])
  110. .pipe(fileinclude({
  111. prefix: '@@',
  112. basepath: './src/partials/',
  113. context: {
  114. environment: 'development'
  115. }
  116. }))
  117. .pipe(dest(paths.temp.base))
  118. .pipe(browserSync.stream())
  119. const html = () => src([paths.src.html])
  120. .pipe(fileinclude({
  121. prefix: '@@',
  122. basepath: './src/partials/',
  123. context: {
  124. environment: 'development'
  125. }
  126. }))
  127. .pipe(dest(paths.temp.html))
  128. .pipe(browserSync.stream())
  129. const assets = () => src([paths.src.assets])
  130. .pipe(dest(paths.temp.assets))
  131. .pipe(browserSync.stream())
  132. const vendor = () => src(npmDist({ copyUnminified: true }), { base: paths.src.nodeModules })
  133. .pipe(dest(paths.temp.vendor))
  134. const serve = () => {
  135. browserSync.init({
  136. server: paths.temp.base
  137. })
  138. watch([paths.src.scss], series(lintScss))
  139. watch([paths.src.scss + '/**/*.scss', '!' + paths.src.scss + '/bootstrap-dark/**/*.scss', '!' + paths.src.scss + '/dark/**/*.scss'], series(scss))
  140. watch([paths.src.scss + '/bootstrap-dark/', paths.src.scss + '/dark/'], series(scssDark))
  141. watch([paths.src.ts], series(lintTs, tsCompile))
  142. watch([paths.src.html, paths.src.base + '*.html', paths.src.partials], series(html, index))
  143. watch([paths.src.assets], series(assets))
  144. }
  145. // From here Dist will Start
  146. // Minify CSS
  147. const minifyDistCss = () => src([
  148. paths.dist.css + '/**/*.css'
  149. ], {
  150. base: paths.dist.css,
  151. sourcemaps: true
  152. })
  153. .pipe(cleanCss({ format: { breakWith: 'lf' } }))
  154. .pipe(rename({ suffix: '.min' }))
  155. .pipe(dest(paths.dist.css, { sourcemaps: '.' }))
  156. // Minify JS
  157. // Need to add terser
  158. const minifyDistJs = () =>
  159. rollup.rollup({
  160. input: paths.src.ts + '/adminlte.ts',
  161. output: {
  162. banner
  163. },
  164. plugins: [
  165. rollupTypescript()
  166. ]
  167. }).then(bundle => bundle.write({
  168. file: paths.temp.js + '/adminlte.js',
  169. format: 'umd',
  170. name: 'adminlte',
  171. sourcemap: true
  172. }))
  173. // Copy assets
  174. const copyDistAssets = () => src(paths.src.assets)
  175. .pipe(dest(paths.dist.assets))
  176. // Clean
  177. const cleanDist = () => del([paths.dist.base])
  178. // Compile and copy all scss/css
  179. const copyDistCssAll = () => src([paths.src.scss + '/**/*.scss'], {
  180. base: paths.src.scss,
  181. sourcemaps: true
  182. })
  183. .pipe(sass(sassOptions).on('error', sass.logError))
  184. .pipe(postcss(postcssOptions))
  185. .pipe(dest(paths.dist.css, { sourcemaps: '.' }))
  186. const copyDistCssRtl = () => src(paths.dist.css + '/*.css', { sourcemaps: true })
  187. .pipe(postcss(postcssRtlOptions))
  188. .pipe(rename({ suffix: '.rtl' }))
  189. .pipe(dest(paths.dist.css + '/rtl', { sourcemaps: '.' }))
  190. // Compile and copy ts/js
  191. const copyDistJs = () =>
  192. rollup.rollup({
  193. input: paths.src.ts + '/adminlte.ts',
  194. output: {
  195. banner
  196. },
  197. plugins: [
  198. rollupTypescript()
  199. ]
  200. }).then(bundle => bundle.write({
  201. file: paths.temp.js + '/adminlte.js',
  202. format: 'umd',
  203. name: 'adminlte',
  204. sourcemap: true
  205. }))
  206. // Copy Html
  207. const copyDistHtml = () => src([paths.src.html])
  208. .pipe(fileinclude({
  209. prefix: '@@',
  210. basepath: './src/partials/',
  211. context: {
  212. environment: 'production'
  213. }
  214. }))
  215. .pipe(dest(paths.dist.html))
  216. // Copy index
  217. const copyDistHtmlIndex = () => src([paths.src.base + '*.html'])
  218. .pipe(fileinclude({
  219. prefix: '@@',
  220. basepath: './src/partials/',
  221. context: {
  222. environment: 'production'
  223. }
  224. }))
  225. .pipe(dest(paths.dist.base))
  226. // Copy node_modules to vendor
  227. const copyDistVendor = () => src(npmDist({ copyUnminified: true }), { base: paths.src.nodeModules })
  228. .pipe(dest(paths.dist.vendor))
  229. // To Dist Before release
  230. exports.build = series(lintScss, lintTs, cleanDist, copyDistCssAll, copyDistCssRtl, minifyDistCss, copyDistJs, minifyDistJs, copyDistHtml, copyDistHtmlIndex, copyDistAssets, copyDistVendor)
  231. // Default - Only for light mode AdminLTE
  232. exports.default = series(scss, scssDark, tsCompile, html, index, assets, vendor, serve)