gulpfile.js 7.7 KB

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