loading up the forgejo repo on tangled to test page performance
at forgejo 4.8 kB view raw
1import {readFileSync} from 'node:fs'; 2import {env} from 'node:process'; 3import {parse} from 'postcss'; 4import plugin from 'tailwindcss/plugin.js'; 5 6const isProduction = env.NODE_ENV !== 'development'; 7 8function extractRootVars(css) { 9 const root = parse(css); 10 const vars = new Set(); 11 root.walkRules((rule) => { 12 if (rule.selector !== ':root') return; 13 rule.each((decl) => { 14 if (decl.value && decl.prop.startsWith('--')) { 15 vars.add(decl.prop.substring(2)); 16 } 17 }); 18 }); 19 return Array.from(vars); 20} 21 22const vars = extractRootVars([ 23 readFileSync(new URL('web_src/css/themes/theme-gitea-light.css', import.meta.url), 'utf8'), 24 readFileSync(new URL('web_src/css/themes/theme-gitea-dark.css', import.meta.url), 'utf8'), 25].join('\n')); 26 27export default { 28 prefix: 'tw-', 29 important: true, // the frameworks are mixed together, so tailwind needs to override other framework's styles 30 content: [ 31 isProduction && '!./templates/devtest/**/*', 32 isProduction && '!./web_src/js/standalone/devtest.js', 33 '!./templates/swagger/v1_json.tmpl', 34 '!./templates/user/auth/oidc_wellknown.tmpl', 35 './templates/**/*.tmpl', 36 './web_src/js/**/*.{js,vue}', 37 // explicitly list Go files that contain tailwind classes 38 'models/avatars/avatar.go', 39 'modules/markup/file_preview.go', 40 'modules/markup/sanitizer.go', 41 'services/auth/source/oauth2/*.go', 42 'routers/web/repo/{view,blame,issue_content_history}.go', 43 ].filter(Boolean), 44 blocklist: [ 45 // classes that don't work without CSS variables from "@tailwind base" which we don't use 46 'transform', 'shadow', 'ring', 'blur', 'grayscale', 'invert', '!invert', 'filter', '!filter', 47 'backdrop-filter', 48 // we use double-class tw-hidden defined in web_src/css/helpers.css for increased specificity 49 'hidden', 50 ], 51 theme: { 52 colors: { 53 // make `tw-bg-red` etc work with our CSS variables 54 ...Object.fromEntries(vars.filter((prop) => prop.startsWith('color-')).map((prop) => { 55 const color = prop.substring(6); 56 return [color, `var(--color-${color})`]; 57 })), 58 inherit: 'inherit', 59 current: 'currentcolor', 60 transparent: 'transparent', 61 }, 62 borderRadius: { 63 'none': '0', 64 'sm': '2px', 65 'DEFAULT': 'var(--border-radius)', // 4px 66 'md': 'var(--border-radius-medium)', // 6px 67 'lg': '8px', 68 'xl': '12px', 69 '2xl': '16px', 70 '3xl': '24px', 71 'full': 'var(--border-radius-full)', 72 }, 73 fontFamily: { 74 sans: 'var(--fonts-regular)', 75 mono: 'var(--fonts-monospace)', 76 }, 77 fontWeight: { 78 light: 'var(--font-weight-light)', 79 normal: 'var(--font-weight-normal)', 80 medium: 'var(--font-weight-medium)', 81 semibold: 'var(--font-weight-semibold)', 82 bold: 'var(--font-weight-bold)', 83 }, 84 fontSize: { // not using `rem` units because our root is currently 14px 85 'xs': '12px', 86 'sm': '14px', 87 'base': '16px', 88 'lg': '18px', 89 'xl': '20px', 90 '2xl': '24px', 91 '3xl': '30px', 92 '4xl': '36px', 93 '5xl': '48px', 94 '6xl': '60px', 95 '7xl': '72px', 96 '8xl': '96px', 97 '9xl': '128px', 98 ...Object.fromEntries(Array.from({length: 100}, (_, i) => { 99 return [`${i}`, `${i === 0 ? '0' : `${i}px`}`]; 100 })), 101 }, 102 }, 103 plugins: [ 104 plugin(({addUtilities}) => { 105 // base variables required for transform utilities 106 // added as utilities since base is not imported 107 // note: required when using tailwind's transform classes 108 addUtilities({ 109 '.transform-reset': { 110 '--tw-translate-x': 0, 111 '--tw-translate-y': 0, 112 '--tw-rotate': 0, 113 '--tw-skew-x': 0, 114 '--tw-skew-y': 0, 115 '--tw-scale-x': '1', 116 '--tw-scale-y': '1', 117 }, 118 }); 119 }), 120 plugin(({addUtilities}) => { 121 addUtilities({ 122 // tw-hidden must win all other "display: xxx !important" classes to get the chance to "hide" an element. 123 // do not use: 124 // * "[hidden]" attribute: it's too weak, can not be applied to an element with "display: flex" 125 // * ".hidden" class: it has been polluted by Fomantic UI in many cases 126 // * inline style="display: none": it's difficult to tweak 127 // * jQuery's show/hide/toggle: it can not show/hide elements with "display: xxx !important" 128 // only use: 129 // * this ".tw-hidden" class 130 // * showElem/hideElem/toggleElem functions in "utils/dom.js" 131 '.hidden.hidden': { 132 'display': 'none', 133 }, 134 // proposed class from https://github.com/tailwindlabs/tailwindcss/pull/12128 135 '.break-anywhere': { 136 'overflow-wrap': 'anywhere', 137 }, 138 }); 139 }), 140 ], 141};