You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

webpack.config.js 9.2KB

Add tailwindcss (#29357) This will get tailwindcss working on a basic level. It provides only the utility classes, e.g. no tailwind base which we don't need because we have our own CSS reset. Without the base, we also do not have their CSS variables so a small amount of features do not work and I removed the generated classes for them. ***Note for future developers: This currently uses a `tw-` prefix, so we use it like `tw-p-3`.*** <details> <summary>Currently added CSS, all false-positives</summary> ``` .\!visible{ visibility: visible !important } .visible{ visibility: visible } .invisible{ visibility: hidden } .collapse{ visibility: collapse } .static{ position: static } .\!fixed{ position: fixed !important } .absolute{ position: absolute } .relative{ position: relative } .sticky{ position: sticky } .left-10{ left: 2.5rem } .isolate{ isolation: isolate } .float-right{ float: right } .float-left{ float: left } .mr-2{ margin-right: 0.5rem } .mr-3{ margin-right: 0.75rem } .\!block{ display: block !important } .block{ display: block } .inline-block{ display: inline-block } .inline{ display: inline } .flex{ display: flex } .inline-flex{ display: inline-flex } .\!table{ display: table !important } .inline-table{ display: inline-table } .table-caption{ display: table-caption } .table-cell{ display: table-cell } .table-column{ display: table-column } .table-column-group{ display: table-column-group } .table-footer-group{ display: table-footer-group } .table-header-group{ display: table-header-group } .table-row-group{ display: table-row-group } .table-row{ display: table-row } .flow-root{ display: flow-root } .inline-grid{ display: inline-grid } .contents{ display: contents } .list-item{ display: list-item } .\!hidden{ display: none !important } .hidden{ display: none } .flex-shrink{ flex-shrink: 1 } .shrink{ flex-shrink: 1 } .flex-grow{ flex-grow: 1 } .grow{ flex-grow: 1 } .border-collapse{ border-collapse: collapse } .select-all{ user-select: all } .resize{ resize: both } .flex-wrap{ flex-wrap: wrap } .overflow-visible{ overflow: visible } .rounded{ border-radius: 0.25rem } .border{ border-width: 1px } .text-justify{ text-align: justify } .uppercase{ text-transform: uppercase } .lowercase{ text-transform: lowercase } .capitalize{ text-transform: capitalize } .italic{ font-style: italic } .text-red{ color: var(--color-red) } .text-shadow{ color: var(--color-shadow) } .underline{ text-decoration-line: underline } .overline{ text-decoration-line: overline } .line-through{ text-decoration-line: line-through } .outline{ outline-style: solid } .ease-in{ transition-timing-function: cubic-bezier(0.4, 0, 1, 1) } .ease-in-out{ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) } .ease-out{ transition-timing-function: cubic-bezier(0, 0, 0.2, 1) } ``` </details> --------- Co-authored-by: Giteabot <teabot@gitea.io>
3 miesięcy temu
Add Octicon SVG spritemap (#10107) * Add octicon SVG sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Static prefix Signed-off-by: jolheiser <john.olheiser@gmail.com> * SVG for all repo icons Signed-off-by: jolheiser <john.olheiser@gmail.com> * make vendor Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap out octicons Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move octicons to top of less imports Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix JS Signed-off-by: jolheiser <john.olheiser@gmail.com> * Definitely not a search/replace Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed regex Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move to more generic calls and webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * make svg -> make webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg-sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed a test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg from makefile Signed-off-by: jolheiser <john.olheiser@gmail.com> * Suggestions Signed-off-by: jolheiser <john.olheiser@gmail.com> * Attempt to fix test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert timetracking test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap .octicon for .svg in less Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add aria-hidden Signed-off-by: jolheiser <john.olheiser@gmail.com> * Replace mega-octicon Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix webpack globbing on Windows Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert Co-Authored-By: silverwind <me@silverwind.io> * Fix octions from upstream Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix Vue and missed JS function Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add JS helper and PWA Signed-off-by: jolheiser <john.olheiser@gmail.com> * Preload SVG Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: techknowlogick <matti@mdranta.net>
4 lat temu
Introduce customized HTML elements, fix incorrect AppUrl usages in templates (#22861) This PR follows: * #21986 * #22831 This PR also introduce customized HTML elements, which would also help problems like: * #17760 * #21429 * #21440 With customized HTML elements, there won't be any load-search-replace operations, and it can avoid page flicking (which @silverwind cares a lot). Browser support: https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements # FAQ ## Why the component has the prefix? As usual, I would strongly suggest to add prefixes for our own/private names. The dedicated prefix will avoid conflicts in the future, and it makes it easier to introduce various 3rd components, like GitHub's `relative-time` component. If there is no prefix, it's impossible to introduce another public component with the same name in the future. ## Why the `custcomp.js` is loaded before HTML body? The `index.js` is after HTML body. Customized components must be registered before the content loading. Otherwise there would be still some flicking. `custcomp.js` should have its own dependencies and should be very light, so it won't affect the page loading time too much. ## Why use `data-url` attribute but not use the `textContent`? According to the standard, the `connectedCallback` occurs on the tag-opening moment. The element's children are not ready yet. ## Why not use `{{.GuessCurrentOrigin $.ctx ...}}` to let backend decide the absolute URL? It's difficult for backend to guess the correct protocol(scheme) correctly with zero configuration. Generating the absolute URL from frontend can guarantee that the URL is 100% correct -- since the user is visiting it. # Screenshot <details> ![image](https://user-images.githubusercontent.com/2114189/218256757-a267c8ba-3108-4755-9ae5-329f1b08f615.png) </details>
1 rok temu
Introduce customized HTML elements, fix incorrect AppUrl usages in templates (#22861) This PR follows: * #21986 * #22831 This PR also introduce customized HTML elements, which would also help problems like: * #17760 * #21429 * #21440 With customized HTML elements, there won't be any load-search-replace operations, and it can avoid page flicking (which @silverwind cares a lot). Browser support: https://developer.mozilla.org/en-US/docs/Web/API/Window/customElements # FAQ ## Why the component has the prefix? As usual, I would strongly suggest to add prefixes for our own/private names. The dedicated prefix will avoid conflicts in the future, and it makes it easier to introduce various 3rd components, like GitHub's `relative-time` component. If there is no prefix, it's impossible to introduce another public component with the same name in the future. ## Why the `custcomp.js` is loaded before HTML body? The `index.js` is after HTML body. Customized components must be registered before the content loading. Otherwise there would be still some flicking. `custcomp.js` should have its own dependencies and should be very light, so it won't affect the page loading time too much. ## Why use `data-url` attribute but not use the `textContent`? According to the standard, the `connectedCallback` occurs on the tag-opening moment. The element's children are not ready yet. ## Why not use `{{.GuessCurrentOrigin $.ctx ...}}` to let backend decide the absolute URL? It's difficult for backend to guess the correct protocol(scheme) correctly with zero configuration. Generating the absolute URL from frontend can guarantee that the URL is 100% correct -- since the user is visiting it. # Screenshot <details> ![image](https://user-images.githubusercontent.com/2114189/218256757-a267c8ba-3108-4755-9ae5-329f1b08f615.png) </details>
1 rok temu
Add tailwindcss (#29357) This will get tailwindcss working on a basic level. It provides only the utility classes, e.g. no tailwind base which we don't need because we have our own CSS reset. Without the base, we also do not have their CSS variables so a small amount of features do not work and I removed the generated classes for them. ***Note for future developers: This currently uses a `tw-` prefix, so we use it like `tw-p-3`.*** <details> <summary>Currently added CSS, all false-positives</summary> ``` .\!visible{ visibility: visible !important } .visible{ visibility: visible } .invisible{ visibility: hidden } .collapse{ visibility: collapse } .static{ position: static } .\!fixed{ position: fixed !important } .absolute{ position: absolute } .relative{ position: relative } .sticky{ position: sticky } .left-10{ left: 2.5rem } .isolate{ isolation: isolate } .float-right{ float: right } .float-left{ float: left } .mr-2{ margin-right: 0.5rem } .mr-3{ margin-right: 0.75rem } .\!block{ display: block !important } .block{ display: block } .inline-block{ display: inline-block } .inline{ display: inline } .flex{ display: flex } .inline-flex{ display: inline-flex } .\!table{ display: table !important } .inline-table{ display: inline-table } .table-caption{ display: table-caption } .table-cell{ display: table-cell } .table-column{ display: table-column } .table-column-group{ display: table-column-group } .table-footer-group{ display: table-footer-group } .table-header-group{ display: table-header-group } .table-row-group{ display: table-row-group } .table-row{ display: table-row } .flow-root{ display: flow-root } .inline-grid{ display: inline-grid } .contents{ display: contents } .list-item{ display: list-item } .\!hidden{ display: none !important } .hidden{ display: none } .flex-shrink{ flex-shrink: 1 } .shrink{ flex-shrink: 1 } .flex-grow{ flex-grow: 1 } .grow{ flex-grow: 1 } .border-collapse{ border-collapse: collapse } .select-all{ user-select: all } .resize{ resize: both } .flex-wrap{ flex-wrap: wrap } .overflow-visible{ overflow: visible } .rounded{ border-radius: 0.25rem } .border{ border-width: 1px } .text-justify{ text-align: justify } .uppercase{ text-transform: uppercase } .lowercase{ text-transform: lowercase } .capitalize{ text-transform: capitalize } .italic{ font-style: italic } .text-red{ color: var(--color-red) } .text-shadow{ color: var(--color-shadow) } .underline{ text-decoration-line: underline } .overline{ text-decoration-line: overline } .line-through{ text-decoration-line: line-through } .outline{ outline-style: solid } .ease-in{ transition-timing-function: cubic-bezier(0.4, 0, 1, 1) } .ease-in-out{ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) } .ease-out{ transition-timing-function: cubic-bezier(0, 0, 0.2, 1) } ``` </details> --------- Co-authored-by: Giteabot <teabot@gitea.io>
3 miesięcy temu
Add tailwindcss (#29357) This will get tailwindcss working on a basic level. It provides only the utility classes, e.g. no tailwind base which we don't need because we have our own CSS reset. Without the base, we also do not have their CSS variables so a small amount of features do not work and I removed the generated classes for them. ***Note for future developers: This currently uses a `tw-` prefix, so we use it like `tw-p-3`.*** <details> <summary>Currently added CSS, all false-positives</summary> ``` .\!visible{ visibility: visible !important } .visible{ visibility: visible } .invisible{ visibility: hidden } .collapse{ visibility: collapse } .static{ position: static } .\!fixed{ position: fixed !important } .absolute{ position: absolute } .relative{ position: relative } .sticky{ position: sticky } .left-10{ left: 2.5rem } .isolate{ isolation: isolate } .float-right{ float: right } .float-left{ float: left } .mr-2{ margin-right: 0.5rem } .mr-3{ margin-right: 0.75rem } .\!block{ display: block !important } .block{ display: block } .inline-block{ display: inline-block } .inline{ display: inline } .flex{ display: flex } .inline-flex{ display: inline-flex } .\!table{ display: table !important } .inline-table{ display: inline-table } .table-caption{ display: table-caption } .table-cell{ display: table-cell } .table-column{ display: table-column } .table-column-group{ display: table-column-group } .table-footer-group{ display: table-footer-group } .table-header-group{ display: table-header-group } .table-row-group{ display: table-row-group } .table-row{ display: table-row } .flow-root{ display: flow-root } .inline-grid{ display: inline-grid } .contents{ display: contents } .list-item{ display: list-item } .\!hidden{ display: none !important } .hidden{ display: none } .flex-shrink{ flex-shrink: 1 } .shrink{ flex-shrink: 1 } .flex-grow{ flex-grow: 1 } .grow{ flex-grow: 1 } .border-collapse{ border-collapse: collapse } .select-all{ user-select: all } .resize{ resize: both } .flex-wrap{ flex-wrap: wrap } .overflow-visible{ overflow: visible } .rounded{ border-radius: 0.25rem } .border{ border-width: 1px } .text-justify{ text-align: justify } .uppercase{ text-transform: uppercase } .lowercase{ text-transform: lowercase } .capitalize{ text-transform: capitalize } .italic{ font-style: italic } .text-red{ color: var(--color-red) } .text-shadow{ color: var(--color-shadow) } .underline{ text-decoration-line: underline } .overline{ text-decoration-line: overline } .line-through{ text-decoration-line: line-through } .outline{ outline-style: solid } .ease-in{ transition-timing-function: cubic-bezier(0.4, 0, 1, 1) } .ease-in-out{ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1) } .ease-out{ transition-timing-function: cubic-bezier(0, 0, 0.2, 1) } ``` </details> --------- Co-authored-by: Giteabot <teabot@gitea.io>
3 miesięcy temu
Add Octicon SVG spritemap (#10107) * Add octicon SVG sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Static prefix Signed-off-by: jolheiser <john.olheiser@gmail.com> * SVG for all repo icons Signed-off-by: jolheiser <john.olheiser@gmail.com> * make vendor Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap out octicons Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move octicons to top of less imports Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix JS Signed-off-by: jolheiser <john.olheiser@gmail.com> * Definitely not a search/replace Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed regex Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move to more generic calls and webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * make svg -> make webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg-sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed a test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg from makefile Signed-off-by: jolheiser <john.olheiser@gmail.com> * Suggestions Signed-off-by: jolheiser <john.olheiser@gmail.com> * Attempt to fix test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert timetracking test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap .octicon for .svg in less Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add aria-hidden Signed-off-by: jolheiser <john.olheiser@gmail.com> * Replace mega-octicon Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix webpack globbing on Windows Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert Co-Authored-By: silverwind <me@silverwind.io> * Fix octions from upstream Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix Vue and missed JS function Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add JS helper and PWA Signed-off-by: jolheiser <john.olheiser@gmail.com> * Preload SVG Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: techknowlogick <matti@mdranta.net>
4 lat temu
Add Octicon SVG spritemap (#10107) * Add octicon SVG sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Static prefix Signed-off-by: jolheiser <john.olheiser@gmail.com> * SVG for all repo icons Signed-off-by: jolheiser <john.olheiser@gmail.com> * make vendor Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap out octicons Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move octicons to top of less imports Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix JS Signed-off-by: jolheiser <john.olheiser@gmail.com> * Definitely not a search/replace Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed regex Signed-off-by: jolheiser <john.olheiser@gmail.com> * Move to more generic calls and webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * make svg -> make webpack Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg-sprite Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Missed a test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Remove svg from makefile Signed-off-by: jolheiser <john.olheiser@gmail.com> * Suggestions Signed-off-by: jolheiser <john.olheiser@gmail.com> * Attempt to fix test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Update tests Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert timetracking test Signed-off-by: jolheiser <john.olheiser@gmail.com> * Swap .octicon for .svg in less Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add aria-hidden Signed-off-by: jolheiser <john.olheiser@gmail.com> * Replace mega-octicon Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix webpack globbing on Windows Signed-off-by: jolheiser <john.olheiser@gmail.com> * Revert Co-Authored-By: silverwind <me@silverwind.io> * Fix octions from upstream Signed-off-by: jolheiser <john.olheiser@gmail.com> * Fix Vue and missed JS function Signed-off-by: jolheiser <john.olheiser@gmail.com> * Add JS helper and PWA Signed-off-by: jolheiser <john.olheiser@gmail.com> * Preload SVG Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-authored-by: techknowlogick <matti@mdranta.net>
4 lat temu
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import fastGlob from 'fast-glob';
  2. import wrapAnsi from 'wrap-ansi';
  3. import AddAssetPlugin from 'add-asset-webpack-plugin';
  4. import LicenseCheckerWebpackPlugin from 'license-checker-webpack-plugin';
  5. import MiniCssExtractPlugin from 'mini-css-extract-plugin';
  6. import MonacoWebpackPlugin from 'monaco-editor-webpack-plugin';
  7. import {VueLoaderPlugin} from 'vue-loader';
  8. import EsBuildLoader from 'esbuild-loader';
  9. import {parse, dirname} from 'node:path';
  10. import webpack from 'webpack';
  11. import {fileURLToPath} from 'node:url';
  12. import {readFileSync} from 'node:fs';
  13. import {env} from 'node:process';
  14. import tailwindcss from 'tailwindcss';
  15. import tailwindConfig from './tailwind.config.js';
  16. import tailwindcssNesting from 'tailwindcss/nesting/index.js';
  17. import postcssNesting from 'postcss-nesting';
  18. const {EsbuildPlugin} = EsBuildLoader;
  19. const {SourceMapDevToolPlugin, DefinePlugin} = webpack;
  20. const formatLicenseText = (licenseText) => wrapAnsi(licenseText || '', 80).trim();
  21. const glob = (pattern) => fastGlob.sync(pattern, {
  22. cwd: dirname(fileURLToPath(new URL(import.meta.url))),
  23. absolute: true,
  24. });
  25. const themes = {};
  26. for (const path of glob('web_src/css/themes/*.css')) {
  27. themes[parse(path).name] = [path];
  28. }
  29. const isProduction = env.NODE_ENV !== 'development';
  30. // ENABLE_SOURCEMAP accepts the following values:
  31. // true - all enabled, the default in development
  32. // reduced - minimal sourcemaps, the default in production
  33. // false - all disabled
  34. let sourceMaps;
  35. if ('ENABLE_SOURCEMAP' in env) {
  36. sourceMaps = ['true', 'false'].includes(env.ENABLE_SOURCEMAP) ? env.ENABLE_SOURCEMAP : 'reduced';
  37. } else {
  38. sourceMaps = isProduction ? 'reduced' : 'true';
  39. }
  40. // define which web components we use for Vue to not interpret them as Vue components
  41. const webComponents = new Set([
  42. // our own, in web_src/js/webcomponents
  43. 'overflow-menu',
  44. 'origin-url',
  45. 'absolute-date',
  46. // from dependencies
  47. 'markdown-toolbar',
  48. 'relative-time',
  49. 'text-expander',
  50. ]);
  51. const filterCssImport = (url, ...args) => {
  52. const cssFile = args[1] || args[0]; // resourcePath is 2nd argument for url and 3rd for import
  53. const importedFile = url.replace(/[?#].+/, '').toLowerCase();
  54. if (cssFile.includes('fomantic')) {
  55. if (/brand-icons/.test(importedFile)) return false;
  56. if (/(eot|ttf|otf|woff|svg)$/i.test(importedFile)) return false;
  57. }
  58. if (cssFile.includes('katex') && /(ttf|woff)$/i.test(importedFile)) {
  59. return false;
  60. }
  61. return true;
  62. };
  63. /** @type {import("webpack").Configuration} */
  64. export default {
  65. mode: isProduction ? 'production' : 'development',
  66. entry: {
  67. index: [
  68. fileURLToPath(new URL('web_src/js/jquery.js', import.meta.url)),
  69. fileURLToPath(new URL('web_src/fomantic/build/semantic.js', import.meta.url)),
  70. fileURLToPath(new URL('web_src/js/index.js', import.meta.url)),
  71. fileURLToPath(new URL('node_modules/easymde/dist/easymde.min.css', import.meta.url)),
  72. fileURLToPath(new URL('web_src/fomantic/build/semantic.css', import.meta.url)),
  73. fileURLToPath(new URL('web_src/css/index.css', import.meta.url)),
  74. ],
  75. webcomponents: [
  76. fileURLToPath(new URL('web_src/js/webcomponents/index.js', import.meta.url)),
  77. ],
  78. swagger: [
  79. fileURLToPath(new URL('web_src/js/standalone/swagger.js', import.meta.url)),
  80. fileURLToPath(new URL('web_src/css/standalone/swagger.css', import.meta.url)),
  81. ],
  82. 'eventsource.sharedworker': [
  83. fileURLToPath(new URL('web_src/js/features/eventsource.sharedworker.js', import.meta.url)),
  84. ],
  85. ...(!isProduction && {
  86. devtest: [
  87. fileURLToPath(new URL('web_src/js/standalone/devtest.js', import.meta.url)),
  88. fileURLToPath(new URL('web_src/css/standalone/devtest.css', import.meta.url)),
  89. ],
  90. }),
  91. ...themes,
  92. },
  93. devtool: false,
  94. output: {
  95. path: fileURLToPath(new URL('public/assets', import.meta.url)),
  96. filename: () => 'js/[name].js',
  97. chunkFilename: ({chunk}) => {
  98. const language = (/monaco.*languages?_.+?_(.+?)_/.exec(chunk.id) || [])[1];
  99. return `js/${language ? `monaco-language-${language.toLowerCase()}` : `[name]`}.[contenthash:8].js`;
  100. },
  101. },
  102. optimization: {
  103. minimize: isProduction,
  104. minimizer: [
  105. new EsbuildPlugin({
  106. target: 'es2020',
  107. minify: true,
  108. css: true,
  109. legalComments: 'none',
  110. }),
  111. ],
  112. splitChunks: {
  113. chunks: 'async',
  114. name: (_, chunks) => chunks.map((item) => item.name).join('-'),
  115. },
  116. moduleIds: 'named',
  117. chunkIds: 'named',
  118. },
  119. module: {
  120. rules: [
  121. {
  122. test: /\.vue$/i,
  123. exclude: /node_modules/,
  124. loader: 'vue-loader',
  125. options: {
  126. compilerOptions: {
  127. isCustomElement: (tag) => webComponents.has(tag),
  128. },
  129. },
  130. },
  131. {
  132. test: /\.js$/i,
  133. exclude: /node_modules/,
  134. use: [
  135. {
  136. loader: 'esbuild-loader',
  137. options: {
  138. loader: 'js',
  139. target: 'es2020',
  140. },
  141. },
  142. ],
  143. },
  144. {
  145. test: /\.css$/i,
  146. use: [
  147. {
  148. loader: MiniCssExtractPlugin.loader,
  149. },
  150. {
  151. loader: 'css-loader',
  152. options: {
  153. sourceMap: sourceMaps === 'true',
  154. url: {filter: filterCssImport},
  155. import: {filter: filterCssImport},
  156. importLoaders: 1,
  157. },
  158. },
  159. {
  160. loader: 'postcss-loader',
  161. options: {
  162. postcssOptions: {
  163. map: false, // https://github.com/postcss/postcss/issues/1914
  164. plugins: [
  165. tailwindcssNesting(postcssNesting({edition: '2024-02'})),
  166. tailwindcss(tailwindConfig),
  167. ],
  168. },
  169. },
  170. }
  171. ],
  172. },
  173. {
  174. test: /\.svg$/i,
  175. include: fileURLToPath(new URL('public/assets/img/svg', import.meta.url)),
  176. type: 'asset/source',
  177. },
  178. {
  179. test: /\.(ttf|woff2?)$/i,
  180. type: 'asset/resource',
  181. generator: {
  182. filename: 'fonts/[name].[contenthash:8][ext]',
  183. }
  184. },
  185. {
  186. test: /\.png$/i,
  187. type: 'asset/resource',
  188. generator: {
  189. filename: 'img/webpack/[name].[contenthash:8][ext]',
  190. }
  191. },
  192. ],
  193. },
  194. plugins: [
  195. new webpack.ProvidePlugin({ // for htmx extensions
  196. htmx: 'htmx.org',
  197. }),
  198. new DefinePlugin({
  199. __VUE_OPTIONS_API__: true, // at the moment, many Vue components still use the Vue Options API
  200. __VUE_PROD_DEVTOOLS__: false, // do not enable devtools support in production
  201. __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false, // https://github.com/vuejs/vue-cli/pull/7443
  202. }),
  203. new VueLoaderPlugin(),
  204. new MiniCssExtractPlugin({
  205. filename: 'css/[name].css',
  206. chunkFilename: 'css/[name].[contenthash:8].css',
  207. }),
  208. sourceMaps !== 'false' && new SourceMapDevToolPlugin({
  209. filename: '[file].[contenthash:8].map',
  210. ...(sourceMaps === 'reduced' && {include: /^js\/index\.js$/}),
  211. }),
  212. new MonacoWebpackPlugin({
  213. filename: 'js/monaco-[name].[contenthash:8].worker.js',
  214. }),
  215. isProduction ? new LicenseCheckerWebpackPlugin({
  216. outputFilename: 'licenses.txt',
  217. outputWriter: ({dependencies}) => {
  218. const line = '-'.repeat(80);
  219. const goJson = readFileSync('assets/go-licenses.json', 'utf8');
  220. const goModules = JSON.parse(goJson).map(({name, licenseText}) => {
  221. return {name, body: formatLicenseText(licenseText)};
  222. });
  223. const jsModules = dependencies.map(({name, version, licenseName, licenseText}) => {
  224. return {name, version, licenseName, body: formatLicenseText(licenseText)};
  225. });
  226. const modules = [...goModules, ...jsModules].sort((a, b) => a.name.localeCompare(b.name));
  227. return modules.map(({name, version, licenseName, body}) => {
  228. const title = licenseName ? `${name}@${version} - ${licenseName}` : name;
  229. return `${line}\n${title}\n${line}\n${body}`;
  230. }).join('\n');
  231. },
  232. override: {
  233. 'khroma@*': {licenseName: 'MIT'}, // https://github.com/fabiospampinato/khroma/pull/33
  234. 'idiomorph@0.3.0': {licenseName: 'BSD-2-Clause'}, // https://github.com/bigskysoftware/idiomorph/pull/37
  235. },
  236. emitError: true,
  237. allow: '(Apache-2.0 OR 0BSD OR BSD-2-Clause OR BSD-3-Clause OR MIT OR ISC OR CPAL-1.0 OR Unlicense OR EPL-1.0 OR EPL-2.0)',
  238. }) : new AddAssetPlugin('licenses.txt', `Licenses are disabled during development`),
  239. ],
  240. performance: {
  241. hints: false,
  242. maxEntrypointSize: Infinity,
  243. maxAssetSize: Infinity,
  244. },
  245. resolve: {
  246. symlinks: false,
  247. },
  248. watchOptions: {
  249. ignored: [
  250. 'node_modules/**',
  251. ],
  252. },
  253. stats: {
  254. assetsSort: 'name',
  255. assetsSpace: Infinity,
  256. cached: false,
  257. cachedModules: false,
  258. children: false,
  259. chunkModules: false,
  260. chunkOrigins: false,
  261. chunksSort: 'name',
  262. colors: true,
  263. entrypoints: false,
  264. excludeAssets: [
  265. /^js\/monaco-language-.+\.js$/,
  266. !isProduction && /^licenses.txt$/,
  267. ].filter(Boolean),
  268. groupAssetsByChunk: false,
  269. groupAssetsByEmitStatus: false,
  270. groupAssetsByInfo: false,
  271. groupModulesByAttributes: false,
  272. modules: false,
  273. reasons: false,
  274. runtimeModules: false,
  275. },
  276. };