uglifyStatics.mjs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import fs from 'fs';
  2. import { minify_sync } from 'terser';
  3. import * as path from 'path';
  4. class Minifier {
  5. static MinifyList = [
  6. 'CDClientLib',
  7. 'modules',
  8. 'page',
  9. 'App.js'
  10. ];
  11. static combine() {
  12. const getAllJSFiles = (dirPath, fileList = []) => {
  13. const files = fs.readdirSync(dirPath);
  14. files.forEach(file => {
  15. const filePath = path.join(dirPath, file);
  16. if (fs.statSync(filePath).isDirectory()) {
  17. getAllJSFiles(filePath, fileList);
  18. } else if (filePath.endsWith('.js')) {
  19. fileList.push(filePath);
  20. }
  21. });
  22. return fileList;
  23. };
  24. const mergeFilesWithComments = (fileList) => {
  25. let mergedContent = '';
  26. for (let i = 0; i < fileList.length; i++) {
  27. mergedContent += `\n\n/*! >>> ${fileList[i]} */\n\n`;
  28. const filePath = fileList[i];
  29. const fileContent = fs.readFileSync(filePath, 'utf8');
  30. mergedContent += fileContent;
  31. }
  32. return mergedContent;
  33. }
  34. const allJSFiles = this.MinifyList.reduce((accumulator, currentPath) => {
  35. currentPath = path.join('./dist/static/', currentPath);
  36. if (fs.statSync(currentPath).isDirectory()) {
  37. return accumulator.concat(getAllJSFiles(currentPath));
  38. } else if (currentPath.endsWith('.js')) {
  39. return accumulator.concat(currentPath);
  40. }
  41. return accumulator;
  42. }, []);
  43. const mergedContent = mergeFilesWithComments(allJSFiles);
  44. fs.writeFileSync('./dist/static/merged_statics.js', mergedContent);
  45. }
  46. static uglify() {
  47. const mangleProperties = {
  48. properties: {
  49. reserved: [
  50. '$', // jQuery
  51. // >>> CodeMirror
  52. 'CodeMirror',
  53. 'cmLineCount',
  54. 'cmEachLine',
  55. 'cmRefresh',
  56. 'cmSetValue',
  57. 'scrollIntoView',
  58. 'markText',
  59. 'getSearchCursor',
  60. 'cmFirstLine',
  61. 'setSelection',
  62. 'cmGetValue',
  63. 'replaceRange',
  64. 'setCursor',
  65. 'cmGetLine',
  66. 'cmFocus',
  67. 'lineNo',
  68. 'onClassLinkClick',
  69. 'onPropertyClick',
  70. // <<< CodeMirror
  71. // >>> Server data
  72. 'Class',
  73. 'isAdmin',
  74. 'ClassList',
  75. 'ClassSource',
  76. 'RepoNames',
  77. 'Z8Locales',
  78. 'Comments',
  79. 'LastUpdateTime',
  80. 'comment',
  81. 'timestamp',
  82. 'nearestParent',
  83. 'type',
  84. 'value',
  85. 'key',
  86. 'inherited',
  87. 'overridden',
  88. 'dynamic'
  89. // <<< Server data
  90. ],
  91. keep_quoted: true
  92. },
  93. toplevel: true
  94. }
  95. const uglified = minify_sync(fs.readFileSync('./dist/static/merged_statics.js', "utf8").toString(), { mangle: mangleProperties });
  96. const uglifiedCode = uglified.code.replace(/\/\*\!\s>>>\s(.+)\s\*\/([^\s])/g, '/*! >>> $1 */\n$2');
  97. const uglifiedCodeStrings = uglifiedCode.split('\n');
  98. let fPath = '';
  99. let fContents = {};
  100. for(const str of uglifiedCodeStrings) {
  101. const fnMatch = str.match(/\/\*\!\s>>>\s(.+)\s\*\//);
  102. if(fnMatch) {
  103. fPath = `./${fnMatch[1]}`;
  104. fContents[fPath] = '';
  105. } else {
  106. fContents[fPath] += str + '\n';
  107. }
  108. }
  109. for(const file of Object.keys(fContents)) {
  110. fs.writeFileSync(file, fContents[file]);
  111. }
  112. }
  113. static clean() {
  114. fs.rmSync('./dist/static/merged_statics.js');
  115. }
  116. static run() {
  117. Minifier.combine();
  118. Minifier.uglify();
  119. Minifier.clean();
  120. }
  121. }
  122. Minifier.run();