gulpfile.js 7.4 KB

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