writeFile.ts 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import fs from 'fs-extra';
  2. import path from 'path';
  3. import os from 'os';
  4. import generateScssMap from './generateSCSSMap';
  5. import { cloneDeep, omit } from 'lodash';
  6. const lodash = { cloneDeep, omit };
  7. const writeComponentScss = (scssMap: { [p: string]: { [p: string]: string } }, tempDir: string) => {
  8. for (const componentName of Object.keys(scssMap)) {
  9. const componentDirPath = path.join(tempDir, 'components', componentName);
  10. fs.emptyDirSync(componentDirPath);
  11. for (const scssFileName of Object.keys(scssMap[componentName])) {
  12. fs.writeFileSync(path.join(componentDirPath, scssFileName), scssMap[componentName][scssFileName], { encoding: 'utf-8' });
  13. }
  14. }
  15. return;
  16. };
  17. const writeThemeScss = (scssMap: (ReturnType<typeof generateScssMap>)['theme'], tempDir: string) => {
  18. const themeDirPath = path.join(tempDir, 'theme');
  19. fs.emptyDirSync(themeDirPath);
  20. for (const scssFileName of Object.keys(scssMap)) {
  21. fs.writeFileSync(path.join(themeDirPath, scssFileName), scssMap[scssFileName as keyof typeof scssMap] as string, { encoding: 'utf8' });
  22. }
  23. return;
  24. };
  25. const preProcessScssMap = (scssMapOrigin: ReturnType<typeof generateScssMap>) => {
  26. const scssMap = lodash.cloneDeep(scssMapOrigin);
  27. //----- generate entry -----
  28. let compilerEntryContent = '';
  29. compilerEntryContent += `@import "./theme/index.scss";\n`;
  30. compilerEntryContent += `@import "./theme/global.scss";\n`;
  31. if (scssMap.theme?.["animation.scss"]) {
  32. compilerEntryContent += `@import "./theme/animation.scss";\n`;
  33. }
  34. for (const componentName of Object.keys(scssMap['components'])) {
  35. let scssFileName = `${componentName}.scss`;
  36. //edge case portal keyframes, cause their folderName and scssFilename not match.
  37. if (componentName === '_portal') {
  38. scssFileName = 'portal.scss';
  39. } else if (componentName === 'keyframes') {
  40. scssFileName = 'rotate.scss';
  41. }
  42. compilerEntryContent += `@import "./components/${componentName}/${scssFileName}";\n`;
  43. }
  44. //edge case for iconButton and textarea
  45. compilerEntryContent += `@import "./components/button/iconButton.scss";\n`;
  46. compilerEntryContent += `@import "./components/input/textarea.scss";\n`;
  47. //----- generate entry end -----
  48. //----- inject component token file local.scss to component's variables.scss -----
  49. const themeLocalRaw = scssMap.theme['local.scss'];
  50. if (themeLocalRaw) {
  51. for (const componentName of Object.keys(scssMap['components'])) {
  52. if (scssMap['components'][componentName]['variables.scss']) {
  53. scssMap['components'][componentName]['variables.scss'] += `\n\n\n\n//inject custom theme variables\n${themeLocalRaw}`;
  54. }
  55. }
  56. }
  57. //----- inject end -----
  58. return {
  59. ...{
  60. components: scssMap['components'],
  61. theme: lodash.omit(scssMap['theme'], 'local.scss')
  62. },
  63. index: compilerEntryContent
  64. };
  65. };
  66. const writeFile = (scssMap: ReturnType<typeof generateScssMap>, tempDir: string = path.join(os.tmpdir(), `semi_scss_compile_${Date.now()}`)) => {
  67. fs.emptyDirSync(tempDir);
  68. const finalScssMapWaitForCompiling = preProcessScssMap(scssMap);
  69. writeComponentScss(finalScssMapWaitForCompiling['components'], tempDir);
  70. writeThemeScss(finalScssMapWaitForCompiling['theme'], tempDir);
  71. //write compile entry
  72. fs.writeFileSync(path.join(tempDir, 'index.scss'), finalScssMapWaitForCompiling['index'], { encoding: 'utf8' });
  73. return tempDir;
  74. };
  75. export default writeFile;