parcel-postbuild.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. const util = require('util'),
  2. fs = require('fs'),
  3. path = require('path'),
  4. replace = require('replace-in-file'),
  5. escapeRegExp = require('lodash.escaperegexp'),
  6. copyFilePromise = util.promisify(fs.copyFile);
  7. // the directory in which you're outputting your build
  8. let baseDir = 'public'
  9. // the name for the directory where your static files will be moved to
  10. let staticDir = 'static'
  11. // the directory where your source files are placed
  12. let sourceDir = 'src'
  13. const pathMake = (p) => {
  14. if (!fs.existsSync(path.join(__dirname, baseDir, p))){
  15. fs.mkdirSync(path.join(__dirname, baseDir, p));
  16. }}
  17. pathMake(staticDir) // if the staticDir directory isn't there, create it
  18. // pathMake(assetsDir)// same for the assetsDir directory
  19. pathMake('font') // same for the fontsDir directory
  20. pathMake('js')
  21. pathMake('styles')
  22. const hashRemove = (hash) => {
  23. return hash.replace(/\.[a-z0-9]{8}\./gm, '.')
  24. }
  25. const linkReplace = (file, list, dir) => {
  26. list.forEach(name => {
  27. let startPath = `${dir}/`
  28. if(dir == null) { startPath = '' }
  29. let options = {
  30. files: path.join(baseDir, file),
  31. from: new RegExp(escapeRegExp(name), 'g'),
  32. to: startPath + hashRemove(name)
  33. }
  34. try {
  35. let changedFiles = replace.sync(options);
  36. // console.log('Modified files:', changedFiles.join(', '));
  37. }
  38. catch (error) {
  39. console.error('Error occurred:', error);
  40. }})}
  41. const parcelFakeUnignore = (file, list, dir) => {
  42. let options = {
  43. files: path.join(baseDir, file),
  44. from: new RegExp(/<!-- parcel-ignore \[ (.*) \] -->/, 'gm'),
  45. to: '$1'
  46. }
  47. try {
  48. let changedFiles = replace.sync(options);
  49. // console.log('Modified files:', changedFiles.join(', '));
  50. }
  51. catch (error) {
  52. console.error('Error occurred:', error);
  53. }}
  54. const filesMove = (list, dest) => {
  55. list.forEach(
  56. name => {
  57. fs.rename(path.join(__dirname, baseDir, name), path.join(__dirname, baseDir, dest, hashRemove(name)), function (err) {
  58. if (err) throw err
  59. console.log(`Successfully moved ${hashRemove(name)}`)
  60. })})}
  61. const copyFiles = (srcDir, destDir, files) => {
  62. return Promise.all(files.map(f => {
  63. return copyFilePromise(path.join(srcDir, f), path.join(destDir, f));
  64. }));
  65. }
  66. // Loop through the baseDir directory
  67. fs.readdir(`./${baseDir}`, (err, files) => {
  68. // store all files in custom arrays by type
  69. let html = [],
  70. js = [],
  71. css = [],
  72. jsMaps = [],
  73. cssMaps = [],
  74. fonts = [],
  75. webman = [],
  76. staticAssets = []
  77. const sortFiles = () => {
  78. files.forEach(file => {
  79. // first HTML files
  80. if(file.match(/.+\.(html)$/)) {
  81. console.log('html match', file)
  82. html.push(file)
  83. } else if(file.match(/.+\.(js)$/)) { // then JavaScripts
  84. console.log('JavaScript match', file)
  85. js.push(file)
  86. } else if(file.match(/.+\.(woff|woff2|eot|ttf|otf)$/)) { // then fonts
  87. console.log('Font match', file)
  88. fonts.push(file)
  89. } else if (file.match(/.+\.(svg)$/)) { // Cheching for font SVG
  90. console.log('SVG match', file)
  91. if (fs.readFileSync(path.join(baseDir, file), 'utf8').match(/\<font\s/gm) != null) {
  92. fonts.push(file)
  93. } else {
  94. staticAssets.push(file)
  95. }
  96. } else if(file.match(/.+\.(css)$/)) { // then CSS
  97. console.log('css match', file)
  98. css.push(file)
  99. } else if(file.match(/.+\.(js.map)$/)) { // then sourcemaps
  100. console.log('JS sourcemaps match', file)
  101. jsMaps.push(file)
  102. } else if(file.match(/.+\.(css.map)$/)) { // then sourcemaps
  103. console.log('CSS sourcemaps match', file)
  104. cssMaps.push(file)
  105. } else if(file.match(/.+\.(webmanifest)$/)) { // then webmanifest
  106. console.log('CSS sourcemaps match', file)
  107. webman.push(file)
  108. } else if(file.match(/.+\..+$/)){ // all other files, exclude current directory and directory one level up
  109. if (!file.match(/.+\.(json|webmanifest)$/)) {
  110. console.log('Static match', file)
  111. staticAssets.push(file)
  112. }
  113. }
  114. });
  115. }
  116. const replaceLinks = () => {
  117. // check what went where
  118. console.log('html', html, '\ncss', css, '\ncss sourcemaps', cssMaps, '\njs', js, '\njs sourcemaps', jsMaps, '\nfonts', fonts, '\nstaticAssets', staticAssets)
  119. // create an array for all compiled assets
  120. // let assets = css.concat(js).concat(map)
  121. // replace all other resources in html
  122. html.forEach(
  123. file => {
  124. staticAssets.forEach(name => {
  125. let options = {
  126. files: path.join(baseDir, file),
  127. from: new RegExp(escapeRegExp(name), 'g'),
  128. to: staticDir + '/' + hashRemove(name)
  129. }
  130. try {
  131. let changedFiles = replace.sync(options);
  132. // console.log('Modified files:', changedFiles.join(', '));
  133. }
  134. catch (error) {
  135. console.error('Error occurred:', error);
  136. }
  137. })
  138. // assets.forEach(name => {
  139. // let options = {
  140. // files: path.join(baseDir, file),
  141. // from: new RegExp(escapeRegExp(name), 'g'),
  142. // to: assetsDir + '/' + hashRemove(name)
  143. // }
  144. // try {
  145. // let changedFiles = replace.sync(options);
  146. // console.log('Modified files:', changedFiles.join(', '));
  147. // }
  148. // catch (error) {
  149. // console.error('Error occurred:', error);
  150. // }
  151. // })
  152. linkReplace(file, fonts, 'font')
  153. // linkReplace(file, js, 'js')
  154. parcelFakeUnignore(file)
  155. linkReplace(file, css, 'styles')
  156. }
  157. )
  158. webman.forEach(
  159. file => {
  160. staticAssets.forEach(name => {
  161. let options = {
  162. files: path.join(baseDir, file),
  163. from: new RegExp(escapeRegExp(name), 'g'),
  164. to: staticDir + '/' + hashRemove(name)
  165. }
  166. try {
  167. let changedFiles = replace.sync(options);
  168. }
  169. catch (error) {
  170. console.error('Error occurred:', error);
  171. }
  172. })
  173. linkReplace(file, staticAssets, staticDir)
  174. }
  175. )
  176. // replace map links in js
  177. js.forEach(
  178. file => {
  179. jsMaps.forEach(name => {
  180. let options = {
  181. files: path.join(baseDir, file),
  182. from: name,
  183. to: hashRemove(name)
  184. }
  185. try {
  186. let changedFiles = replace.sync(options);
  187. // console.log('Modified files:', changedFiles.join(', '));
  188. }
  189. catch (error) {
  190. console.error('Error occurred:', error);
  191. }
  192. })
  193. }
  194. )
  195. // replace links in css
  196. css.forEach(
  197. file => {
  198. staticAssets.forEach(name => {
  199. let options = {
  200. files: path.join(baseDir, file),
  201. from: new RegExp(escapeRegExp(name), 'g'),
  202. to: '../' + staticDir + '/' + hashRemove(name)
  203. }
  204. try {
  205. let changedFiles = replace.sync(options);
  206. // console.log('Modified files:', changedFiles.join(', '));
  207. }
  208. catch (error) {
  209. console.error('Error occurred:', error);
  210. }
  211. })
  212. linkReplace(file, fonts, '../font')
  213. linkReplace(file, cssMaps, null)
  214. }
  215. )
  216. }
  217. const moveBuildFiles = () => {
  218. // filesMove(assets, assetsDir) // move js and css and maps
  219. filesMove(fonts, 'font') // move fonts
  220. filesMove(js, 'js')
  221. filesMove(jsMaps, 'js')
  222. filesMove(css, 'styles')
  223. filesMove(cssMaps, 'styles')
  224. filesMove(staticAssets, staticDir) // move staticAssets
  225. }
  226. sortFiles();
  227. replaceLinks();
  228. moveBuildFiles();
  229. });
  230. // fs.copyFile(`${sourceDir}\\data.json`, `${baseDir}\\data.json`, (err) => {
  231. // if (err) throw err;
  232. // console.log('data.json was copied');
  233. // });
  234. // fs.copyFile(`${sourceDir}\\js\\main.js`, `${baseDir}\\js\\main.js`, (err) => {
  235. // if (err) throw err;
  236. // console.log('data.json was copied');
  237. // });
  238. // usage
  239. copyFiles(sourceDir, baseDir, ['data.json', 'js/main.js']).then(() => {
  240. console.log("JSON and JS are copied.");
  241. }).catch(err => {
  242. console.log(err);
  243. });