@openedx/frontend-base 1.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/LICENSE +661 -0
  2. package/README.md +112 -0
  3. package/config/babel/babel.config.js +28 -0
  4. package/config/config-helpers/createConfig.js +13 -0
  5. package/config/config-helpers/createLintConfig.js +16 -0
  6. package/config/config-helpers/getBaseConfig.js +12 -0
  7. package/config/defaultConfigPaths.js +35 -0
  8. package/config/eslint/base.eslint.config.js +113 -0
  9. package/config/index.js +12 -0
  10. package/config/jest/jest.config.js +30 -0
  11. package/config/tsconfig.json +32 -0
  12. package/config/types.js +25 -0
  13. package/config/webpack/common-config/all/getCodeRules.js +52 -0
  14. package/config/webpack/common-config/all/getFileLoaderRules.js +26 -0
  15. package/config/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  16. package/config/webpack/common-config/all/getImageMinimizer.js +25 -0
  17. package/config/webpack/common-config/all/getStylesheetRule.js +112 -0
  18. package/config/webpack/common-config/dev/getDevServer.js +38 -0
  19. package/config/webpack/common-config/index.js +18 -0
  20. package/config/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  21. package/config/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  22. package/config/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  23. package/config/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  24. package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  25. package/config/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  26. package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  27. package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  28. package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  29. package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  30. package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  31. package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  32. package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  33. package/config/webpack/types.js +2 -0
  34. package/config/webpack/utils/getLocalAliases.js +65 -0
  35. package/config/webpack/utils/getPublicPath.js +6 -0
  36. package/config/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  37. package/config/webpack/utils/paragonUtils.js +138 -0
  38. package/config/webpack/webpack.config.build.js +80 -0
  39. package/config/webpack/webpack.config.dev.js +76 -0
  40. package/config/webpack/webpack.config.dev.shell.js +110 -0
  41. package/eslint.config.js +18 -0
  42. package/frontend-base.d.ts +8 -0
  43. package/index.ts +7 -0
  44. package/jest.config.js +7 -0
  45. package/openedx-frontend-base.tgz +0 -0
  46. package/package.json +149 -0
  47. package/runtime/analytics/MockAnalyticsService.js +71 -0
  48. package/runtime/analytics/SegmentAnalyticsService.js +243 -0
  49. package/runtime/analytics/index.ts +12 -0
  50. package/runtime/analytics/interface.js +145 -0
  51. package/runtime/auth/AxiosCsrfTokenService.js +60 -0
  52. package/runtime/auth/AxiosJwtAuthService.js +363 -0
  53. package/runtime/auth/AxiosJwtTokenService.js +134 -0
  54. package/runtime/auth/LocalForageCache.js +76 -0
  55. package/runtime/auth/MockAuthService.js +278 -0
  56. package/runtime/auth/index.ts +19 -0
  57. package/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js +36 -0
  58. package/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js +37 -0
  59. package/runtime/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +20 -0
  60. package/runtime/auth/interceptors/createRetryInterceptor.js +74 -0
  61. package/runtime/auth/interface.js +309 -0
  62. package/runtime/auth/utils.js +105 -0
  63. package/runtime/babel.config.js +3 -0
  64. package/runtime/config/index.ts +295 -0
  65. package/runtime/constants.ts +68 -0
  66. package/runtime/i18n/index.js +118 -0
  67. package/runtime/i18n/injectIntlWithShim.jsx +48 -0
  68. package/runtime/i18n/lib.ts +272 -0
  69. package/runtime/index.ts +134 -0
  70. package/runtime/initialize.js +352 -0
  71. package/runtime/jest.config.js +32 -0
  72. package/runtime/logging/MockLoggingService.js +31 -0
  73. package/runtime/logging/NewRelicLoggingService.js +184 -0
  74. package/runtime/logging/index.ts +9 -0
  75. package/runtime/logging/interface.js +109 -0
  76. package/runtime/logging/types.ts +4 -0
  77. package/runtime/react/AuthenticatedPageRoute.jsx +43 -0
  78. package/runtime/react/CombinedAppProvider.tsx +46 -0
  79. package/runtime/react/CurrentAppContext.tsx +25 -0
  80. package/runtime/react/CurrentAppProvider.tsx +46 -0
  81. package/runtime/react/Divider.tsx +5 -0
  82. package/runtime/react/ErrorBoundary.jsx +47 -0
  83. package/runtime/react/ErrorPage.jsx +72 -0
  84. package/runtime/react/LoginRedirect.jsx +16 -0
  85. package/runtime/react/PageWrap.jsx +24 -0
  86. package/runtime/react/SiteContext.tsx +32 -0
  87. package/runtime/react/SiteProvider.tsx +78 -0
  88. package/runtime/react/hooks.ts +106 -0
  89. package/runtime/react/index.ts +19 -0
  90. package/runtime/routing/index.ts +1 -0
  91. package/runtime/routing/utils.ts +34 -0
  92. package/runtime/scripts/GoogleAnalyticsLoader.ts +59 -0
  93. package/runtime/scripts/index.ts +1 -0
  94. package/runtime/setupTest.js +49 -0
  95. package/runtime/slots/Slot.tsx +32 -0
  96. package/runtime/slots/SlotContext.tsx +8 -0
  97. package/runtime/slots/hooks.ts +35 -0
  98. package/runtime/slots/index.ts +7 -0
  99. package/runtime/slots/layout/DefaultSlotLayout.tsx +9 -0
  100. package/runtime/slots/layout/hooks.ts +65 -0
  101. package/runtime/slots/layout/index.ts +5 -0
  102. package/runtime/slots/layout/types.ts +45 -0
  103. package/runtime/slots/layout/utils.ts +14 -0
  104. package/runtime/slots/types.ts +23 -0
  105. package/runtime/slots/utils.ts +59 -0
  106. package/runtime/slots/widget/WidgetContext.tsx +9 -0
  107. package/runtime/slots/widget/WidgetProvider.tsx +30 -0
  108. package/runtime/slots/widget/hooks.ts +105 -0
  109. package/runtime/slots/widget/iframe/IFrameContentWrapper.messages.tsx +16 -0
  110. package/runtime/slots/widget/iframe/IFrameContentWrapper.tsx +84 -0
  111. package/runtime/slots/widget/iframe/IFrameWidget.tsx +59 -0
  112. package/runtime/slots/widget/iframe/constants.ts +19 -0
  113. package/runtime/slots/widget/iframe/hooks.ts +179 -0
  114. package/runtime/slots/widget/iframe/index.ts +6 -0
  115. package/runtime/slots/widget/iframe/types.ts +7 -0
  116. package/runtime/slots/widget/index.ts +6 -0
  117. package/runtime/slots/widget/types.ts +134 -0
  118. package/runtime/slots/widget/utils.tsx +201 -0
  119. package/runtime/subscriptions.ts +60 -0
  120. package/runtime/testing/index.ts +9 -0
  121. package/runtime/testing/initializeMockApp.ts +81 -0
  122. package/runtime/testing/mockMessages.ts +23 -0
  123. package/runtime/utils.js +178 -0
  124. package/shell/DefaultLayout.tsx +18 -0
  125. package/shell/DefaultMain.tsx +7 -0
  126. package/shell/Logo.tsx +28 -0
  127. package/shell/Shell.messages.ts +61 -0
  128. package/shell/Shell.tsx +18 -0
  129. package/shell/app.scss +149 -0
  130. package/shell/app.ts +24 -0
  131. package/shell/babel.config.js +3 -0
  132. package/shell/dev/devFooter/app.tsx +43 -0
  133. package/shell/dev/devFooter/index.ts +1 -0
  134. package/shell/dev/devHeader/BarContext.tsx +13 -0
  135. package/shell/dev/devHeader/BarLink.tsx +16 -0
  136. package/shell/dev/devHeader/BarProvider.tsx +25 -0
  137. package/shell/dev/devHeader/CoursesLink.tsx +16 -0
  138. package/shell/dev/devHeader/FooContext.tsx +13 -0
  139. package/shell/dev/devHeader/FooLink.tsx +16 -0
  140. package/shell/dev/devHeader/FooProvider.tsx +25 -0
  141. package/shell/dev/devHeader/app.tsx +53 -0
  142. package/shell/dev/devHeader/index.ts +1 -0
  143. package/shell/dev/devHeader/providers.tsx +11 -0
  144. package/shell/dev/devHome/HomePage.tsx +28 -0
  145. package/shell/dev/devHome/app.ts +18 -0
  146. package/shell/dev/devHome/i18n/index.ts +27 -0
  147. package/shell/dev/devHome/index.ts +1 -0
  148. package/shell/dev/devHome/messages.ts +11 -0
  149. package/shell/dev/devUser/app.tsx +24 -0
  150. package/shell/dev/devUser/index.ts +1 -0
  151. package/shell/dev/index.ts +5 -0
  152. package/shell/dev/slotShowcase/HorizontalSlotLayout.tsx +11 -0
  153. package/shell/dev/slotShowcase/LayoutWithOptions.tsx +17 -0
  154. package/shell/dev/slotShowcase/SlotShowcasePage.tsx +66 -0
  155. package/shell/dev/slotShowcase/WidgetWithOptions.tsx +11 -0
  156. package/shell/dev/slotShowcase/app.tsx +373 -0
  157. package/shell/dev/slotShowcase/index.ts +1 -0
  158. package/shell/footer/CenterLinks.tsx +11 -0
  159. package/shell/footer/CopyrightNotice.tsx +36 -0
  160. package/shell/footer/Footer.tsx +34 -0
  161. package/shell/footer/LabeledLinkColumn.tsx +19 -0
  162. package/shell/footer/LanguageMenu.tsx +35 -0
  163. package/shell/footer/LanguageMenuItem.tsx +23 -0
  164. package/shell/footer/LeftLinks.tsx +11 -0
  165. package/shell/footer/LegalNotices.tsx +17 -0
  166. package/shell/footer/PoweredBy.tsx +17 -0
  167. package/shell/footer/RevealLinks.tsx +43 -0
  168. package/shell/footer/RightLinks.tsx +11 -0
  169. package/shell/footer/app.tsx +73 -0
  170. package/shell/footer/data/api.ts +48 -0
  171. package/shell/footer/index.ts +2 -0
  172. package/shell/header/AuthenticatedMenu.tsx +32 -0
  173. package/shell/header/Header.tsx +17 -0
  174. package/shell/header/anonymous-menu/AnonymousMenu.tsx +14 -0
  175. package/shell/header/anonymous-menu/LoginButton.tsx +14 -0
  176. package/shell/header/anonymous-menu/RegisterButton.tsx +15 -0
  177. package/shell/header/app.tsx +142 -0
  178. package/shell/header/desktop/DesktopLayout.tsx +22 -0
  179. package/shell/header/desktop/PrimaryNavLinks.tsx +10 -0
  180. package/shell/header/desktop/SecondaryNavLinks.tsx +10 -0
  181. package/shell/header/index.ts +2 -0
  182. package/shell/header/mobile/MobileLayout.tsx +47 -0
  183. package/shell/header/mobile/MobileNavLinks.tsx +10 -0
  184. package/shell/i18n/index.ts +25 -0
  185. package/shell/index.ts +7 -0
  186. package/shell/jest.config.js +30 -0
  187. package/shell/menus/LinkMenuItem.tsx +64 -0
  188. package/shell/menus/NavDropdownMenuSlot.tsx +29 -0
  189. package/shell/menus/ProfileLinkMenuItem.tsx +33 -0
  190. package/shell/menus/data/utils.ts +19 -0
  191. package/shell/public/index.html +10 -0
  192. package/shell/router/createRouter.ts +17 -0
  193. package/shell/router/getAppRoutes.ts +21 -0
  194. package/shell/setupTest.js +48 -0
  195. package/shell/site.config.dev.tsx +49 -0
  196. package/shell/site.tsx +41 -0
  197. package/test-site/app.d.ts +15 -0
  198. package/test-site/dist/176.436443549ebb858db483.js +2 -0
  199. package/test-site/dist/176.436443549ebb858db483.js.map +1 -0
  200. package/test-site/dist/362.536eff787d2380fe246c.js +2 -0
  201. package/test-site/dist/362.536eff787d2380fe246c.js.map +1 -0
  202. package/test-site/dist/653.486966b108d224551296.js +2 -0
  203. package/test-site/dist/653.486966b108d224551296.js.map +1 -0
  204. package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
  205. package/test-site/dist/806.323cf6496ad0a7fe73a7.js +3 -0
  206. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +106 -0
  207. package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +1 -0
  208. package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +4 -0
  209. package/test-site/dist/app.612058b36c74787759ac.css +61 -0
  210. package/test-site/dist/app.612058b36c74787759ac.css.map +1 -0
  211. package/test-site/dist/app.612058b36c74787759ac.js +2 -0
  212. package/test-site/dist/app.612058b36c74787759ac.js.map +1 -0
  213. package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +1 -0
  214. package/test-site/dist/index.html +1 -0
  215. package/test-site/dist/report.html +39 -0
  216. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +2 -0
  217. package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +1 -0
  218. package/test-site/eslint.config.js +12 -0
  219. package/test-site/package-lock.json +19226 -0
  220. package/test-site/package.json +29 -0
  221. package/test-site/public/index.html +10 -0
  222. package/test-site/site.config.build.tsx +27 -0
  223. package/test-site/site.config.dev.tsx +27 -0
  224. package/test-site/src/authenticated-page/AuthenticatedPage.tsx +18 -0
  225. package/test-site/src/authenticated-page/i18n/index.ts +27 -0
  226. package/test-site/src/authenticated-page/index.tsx +28 -0
  227. package/test-site/src/example-page/ExamplePage.tsx +79 -0
  228. package/test-site/src/example-page/Image.tsx +11 -0
  229. package/test-site/src/example-page/ParagonPreview.jsx +66 -0
  230. package/test-site/src/example-page/apple.jpg +0 -0
  231. package/test-site/src/example-page/apple.svg +1 -0
  232. package/test-site/src/example-page/index.ts +16 -0
  233. package/test-site/src/i18n/README.md +3 -0
  234. package/test-site/src/i18n/messages/frontend-app-sample/ar.json +4 -0
  235. package/test-site/src/i18n/messages/frontend-app-sample/eo.json +1 -0
  236. package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +4 -0
  237. package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +1 -0
  238. package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +3 -0
  239. package/test-site/src/iframe-widget/IframeWidget.tsx +14 -0
  240. package/test-site/src/iframe-widget/index.ts +16 -0
  241. package/test-site/src/index.tsx +3 -0
  242. package/test-site/src/messages.js +11 -0
  243. package/test-site/src/site.scss +11 -0
  244. package/test-site/tsconfig.json +14 -0
  245. package/tools/babel/babel.config.js +27 -0
  246. package/tools/babel.config.js +3 -0
  247. package/tools/cli/README.md +29 -0
  248. package/tools/cli/commands/pack.ts +9 -0
  249. package/tools/cli/commands/release.ts +27 -0
  250. package/tools/cli/commands/serve.ts +43 -0
  251. package/tools/cli/intl-imports.ts +274 -0
  252. package/tools/cli/openedx.ts +101 -0
  253. package/tools/cli/transifex-utils.ts +75 -0
  254. package/tools/cli/utils/ensureConfigFilenameOption.ts +40 -0
  255. package/tools/cli/utils/formatter.ts +10 -0
  256. package/tools/cli/utils/getResolvedConfigPath.ts +23 -0
  257. package/tools/cli/utils/prettyPrintTitle.ts +15 -0
  258. package/tools/cli/utils/printUsage.ts +53 -0
  259. package/tools/config-helpers/createConfig.ts +8 -0
  260. package/tools/config-helpers/createLintConfig.ts +14 -0
  261. package/tools/config-helpers/getBaseConfig.ts +11 -0
  262. package/tools/defaultConfigPaths.ts +30 -0
  263. package/tools/dist/babel/babel.config.js +28 -0
  264. package/tools/dist/cli/commands/pack.js +14 -0
  265. package/tools/dist/cli/commands/release.js +28 -0
  266. package/tools/dist/cli/commands/serve.js +44 -0
  267. package/tools/dist/cli/intl-imports.js +233 -0
  268. package/tools/dist/cli/openedx.js +100 -0
  269. package/tools/dist/cli/transifex-utils.js +68 -0
  270. package/tools/dist/cli/utils/ensureConfigFilenameOption.js +42 -0
  271. package/tools/dist/cli/utils/formatter.js +10 -0
  272. package/tools/dist/cli/utils/getResolvedConfigPath.js +28 -0
  273. package/tools/dist/cli/utils/prettyPrintTitle.js +17 -0
  274. package/tools/dist/cli/utils/printUsage.js +48 -0
  275. package/tools/dist/config-helpers/createConfig.js +13 -0
  276. package/tools/dist/config-helpers/createLintConfig.js +16 -0
  277. package/tools/dist/config-helpers/getBaseConfig.js +12 -0
  278. package/tools/dist/defaultConfigPaths.js +35 -0
  279. package/tools/dist/eslint/base.eslint.config.js +113 -0
  280. package/tools/dist/eslint.config.js +11 -0
  281. package/tools/dist/index.js +12 -0
  282. package/tools/dist/jest/jest.config.js +30 -0
  283. package/tools/dist/jest.config.js +20 -0
  284. package/tools/dist/types.js +25 -0
  285. package/tools/dist/typescript/tsconfig.json +32 -0
  286. package/tools/dist/webpack/common-config/all/getCodeRules.js +52 -0
  287. package/tools/dist/webpack/common-config/all/getFileLoaderRules.js +26 -0
  288. package/tools/dist/webpack/common-config/all/getIgnoreWarnings.js +14 -0
  289. package/tools/dist/webpack/common-config/all/getImageMinimizer.js +25 -0
  290. package/tools/dist/webpack/common-config/all/getStylesheetRule.js +112 -0
  291. package/tools/dist/webpack/common-config/dev/getDevServer.js +38 -0
  292. package/tools/dist/webpack/common-config/index.js +18 -0
  293. package/tools/dist/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
  294. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
  295. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
  296. package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
  297. package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
  298. package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
  299. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
  300. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
  301. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
  302. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
  303. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
  304. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
  305. package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
  306. package/tools/dist/webpack/types.js +2 -0
  307. package/tools/dist/webpack/utils/getLocalAliases.js +65 -0
  308. package/tools/dist/webpack/utils/getPublicPath.js +6 -0
  309. package/tools/dist/webpack/utils/getResolvedSiteConfigPath.js +32 -0
  310. package/tools/dist/webpack/utils/paragonUtils.js +138 -0
  311. package/tools/dist/webpack/webpack.config.build.js +80 -0
  312. package/tools/dist/webpack/webpack.config.dev.js +76 -0
  313. package/tools/dist/webpack/webpack.config.dev.shell.js +110 -0
  314. package/tools/eslint/base.eslint.config.js +124 -0
  315. package/tools/eslint/modules.d.ts +5 -0
  316. package/tools/eslint.config.js +15 -0
  317. package/tools/index.ts +3 -0
  318. package/tools/jest/jest.config.js +30 -0
  319. package/tools/jest.config.js +19 -0
  320. package/tools/tsconfig.json +24 -0
  321. package/tools/types.ts +21 -0
  322. package/tools/typescript/tsconfig.json +32 -0
  323. package/tools/webpack/common-config/README.md +15 -0
  324. package/tools/webpack/common-config/all/getCodeRules.ts +51 -0
  325. package/tools/webpack/common-config/all/getFileLoaderRules.ts +23 -0
  326. package/tools/webpack/common-config/all/getIgnoreWarnings.ts +13 -0
  327. package/tools/webpack/common-config/all/getImageMinimizer.ts +26 -0
  328. package/tools/webpack/common-config/all/getStylesheetRule.ts +111 -0
  329. package/tools/webpack/common-config/dev/getDevServer.ts +35 -0
  330. package/tools/webpack/common-config/index.ts +6 -0
  331. package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +11 -0
  332. package/tools/webpack/modules.d.ts +6 -0
  333. package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +102 -0
  334. package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +21 -0
  335. package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +7 -0
  336. package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +3 -0
  337. package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +1 -0
  338. package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +134 -0
  339. package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +3 -0
  340. package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +71 -0
  341. package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +72 -0
  342. package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +6 -0
  343. package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +131 -0
  344. package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +144 -0
  345. package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +106 -0
  346. package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +54 -0
  347. package/tools/webpack/types.ts +69 -0
  348. package/tools/webpack/utils/getLocalAliases.ts +65 -0
  349. package/tools/webpack/utils/getPublicPath.ts +3 -0
  350. package/tools/webpack/utils/getResolvedSiteConfigPath.ts +28 -0
  351. package/tools/webpack/utils/paragonUtils.ts +152 -0
  352. package/tools/webpack/webpack.config.build.ts +93 -0
  353. package/tools/webpack/webpack.config.dev.shell.ts +122 -0
  354. package/tools/webpack/webpack.config.dev.ts +90 -0
  355. package/tsconfig.json +23 -0
  356. package/types.ts +99 -0
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const react_refresh_webpack_plugin_1 = __importDefault(require("@pmmmwh/react-refresh-webpack-plugin"));
7
+ const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checker-webpack-plugin"));
8
+ const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
9
+ const path_1 = __importDefault(require("path"));
10
+ const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
11
+ const common_config_1 = require("./common-config");
12
+ const ParagonWebpackPlugin_1 = __importDefault(require("./plugins/paragon-webpack-plugin/ParagonWebpackPlugin"));
13
+ const getLocalAliases_1 = __importDefault(require("./utils/getLocalAliases"));
14
+ const getPublicPath_1 = __importDefault(require("./utils/getPublicPath"));
15
+ const getResolvedSiteConfigPath_1 = __importDefault(require("./utils/getResolvedSiteConfigPath"));
16
+ const paragonUtils_1 = require("./utils/paragonUtils");
17
+ const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
18
+ const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
19
+ const aliases = (0, getLocalAliases_1.default)();
20
+ const resolvedSiteConfigPath = (0, getResolvedSiteConfigPath_1.default)('site.config.dev.tsx');
21
+ const config = {
22
+ entry: {
23
+ app: path_1.default.resolve(process.cwd(), 'node_modules/@openedx/frontend-base/shell/site'),
24
+ ...(0, paragonUtils_1.getParagonEntryPoints)(paragonThemeCss),
25
+ ...(0, paragonUtils_1.getParagonEntryPoints)(brandThemeCss),
26
+ },
27
+ output: {
28
+ path: path_1.default.resolve(process.cwd(), './dist'),
29
+ publicPath: (0, getPublicPath_1.default)(),
30
+ },
31
+ resolve: {
32
+ alias: {
33
+ ...aliases,
34
+ 'site.config': resolvedSiteConfigPath,
35
+ },
36
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
37
+ },
38
+ mode: 'development',
39
+ devtool: 'eval-source-map',
40
+ module: {
41
+ rules: [
42
+ ...(0, common_config_1.getCodeRules)('dev', resolvedSiteConfigPath),
43
+ (0, common_config_1.getStylesheetRule)('dev'),
44
+ ...(0, common_config_1.getFileLoaderRules)(),
45
+ ],
46
+ },
47
+ optimization: {
48
+ splitChunks: {
49
+ chunks: 'all',
50
+ cacheGroups: {
51
+ ...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
52
+ ...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
53
+ },
54
+ },
55
+ minimizer: (0, common_config_1.getImageMinimizer)(),
56
+ },
57
+ // Specify additional processing or side-effects done on the Webpack output bundles as a whole.
58
+ plugins: [
59
+ // RemoveEmptyScriptsPlugin get rid of empty scripts generated by webpack when using mini-css-extract-plugin
60
+ // This helps to clean up the final bundle application
61
+ // See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
62
+ new webpack_remove_empty_scripts_1.default(),
63
+ new ParagonWebpackPlugin_1.default(),
64
+ // Writes the extracted CSS from each entry to a file in the output directory.
65
+ new mini_css_extract_plugin_1.default({
66
+ filename: '[name].css',
67
+ }),
68
+ (0, common_config_1.getHtmlWebpackPlugin)(),
69
+ new react_refresh_webpack_plugin_1.default(),
70
+ new fork_ts_checker_webpack_plugin_1.default(),
71
+ ],
72
+ // This configures webpack-dev-server which serves bundles from memory and provides live
73
+ // reloading.
74
+ devServer: (0, common_config_1.getDevServer)(),
75
+ };
76
+ exports.default = config;
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const ts_transformer_1 = require("@formatjs/ts-transformer");
7
+ const react_refresh_webpack_plugin_1 = __importDefault(require("@pmmmwh/react-refresh-webpack-plugin"));
8
+ const fork_ts_checker_webpack_plugin_1 = __importDefault(require("fork-ts-checker-webpack-plugin"));
9
+ const mini_css_extract_plugin_1 = __importDefault(require("mini-css-extract-plugin"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const react_refresh_typescript_1 = __importDefault(require("react-refresh-typescript"));
12
+ const webpack_remove_empty_scripts_1 = __importDefault(require("webpack-remove-empty-scripts"));
13
+ const common_config_1 = require("./common-config");
14
+ const ParagonWebpackPlugin_1 = __importDefault(require("./plugins/paragon-webpack-plugin/ParagonWebpackPlugin"));
15
+ const html_webpack_plugin_1 = __importDefault(require("html-webpack-plugin"));
16
+ const getLocalAliases_1 = __importDefault(require("./utils/getLocalAliases"));
17
+ const getPublicPath_1 = __importDefault(require("./utils/getPublicPath"));
18
+ const getResolvedSiteConfigPath_1 = __importDefault(require("./utils/getResolvedSiteConfigPath"));
19
+ const paragonUtils_1 = require("./utils/paragonUtils");
20
+ const paragonThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd());
21
+ const brandThemeCss = (0, paragonUtils_1.getParagonThemeCss)(process.cwd(), { isBrandOverride: true });
22
+ const aliases = (0, getLocalAliases_1.default)();
23
+ const resolvedSiteConfigPath = (0, getResolvedSiteConfigPath_1.default)('shell/site.config.dev.tsx');
24
+ const config = {
25
+ entry: {
26
+ app: path_1.default.resolve(process.cwd(), 'shell/site'),
27
+ ...(0, paragonUtils_1.getParagonEntryPoints)(paragonThemeCss),
28
+ ...(0, paragonUtils_1.getParagonEntryPoints)(brandThemeCss),
29
+ },
30
+ output: {
31
+ path: path_1.default.resolve(process.cwd(), './dist'),
32
+ publicPath: (0, getPublicPath_1.default)(),
33
+ },
34
+ resolve: {
35
+ alias: {
36
+ ...aliases,
37
+ 'site.config': resolvedSiteConfigPath,
38
+ },
39
+ extensions: ['.js', '.jsx', '.ts', '.tsx'],
40
+ },
41
+ mode: 'development',
42
+ devtool: 'eval-source-map',
43
+ module: {
44
+ rules: [
45
+ {
46
+ test: /\.(js|jsx|ts|tsx)$/,
47
+ include: [
48
+ /shell/,
49
+ /runtime/,
50
+ path_1.default.resolve(process.cwd(), 'types'),
51
+ resolvedSiteConfigPath,
52
+ ],
53
+ use: {
54
+ loader: require.resolve('ts-loader'),
55
+ options: {
56
+ transpileOnly: true,
57
+ compilerOptions: {
58
+ noEmit: false,
59
+ },
60
+ getCustomTransformers() {
61
+ return {
62
+ before: [
63
+ (0, ts_transformer_1.transform)({
64
+ overrideIdFn: '[sha512:contenthash:base64:6]',
65
+ }),
66
+ (0, react_refresh_typescript_1.default)()
67
+ ],
68
+ };
69
+ },
70
+ },
71
+ },
72
+ },
73
+ (0, common_config_1.getStylesheetRule)('dev'),
74
+ ...(0, common_config_1.getFileLoaderRules)(),
75
+ ],
76
+ },
77
+ optimization: {
78
+ splitChunks: {
79
+ chunks: 'all',
80
+ cacheGroups: {
81
+ ...(0, paragonUtils_1.getParagonCacheGroups)(paragonThemeCss),
82
+ ...(0, paragonUtils_1.getParagonCacheGroups)(brandThemeCss),
83
+ },
84
+ },
85
+ minimizer: (0, common_config_1.getImageMinimizer)(),
86
+ },
87
+ // Specify additional processing or side-effects done on the Webpack output bundles as a whole.
88
+ plugins: [
89
+ // RemoveEmptyScriptsPlugin get rid of empty scripts generated by webpack when using mini-css-extract-plugin
90
+ // This helps to clean up the final bundle application
91
+ // See: https://www.npmjs.com/package/webpack-remove-empty-scripts#usage-with-mini-css-extract-plugin
92
+ new webpack_remove_empty_scripts_1.default(),
93
+ new ParagonWebpackPlugin_1.default(),
94
+ // Writes the extracted CSS from each entry to a file in the output directory.
95
+ new mini_css_extract_plugin_1.default({
96
+ filename: '[name].css',
97
+ }),
98
+ new html_webpack_plugin_1.default({
99
+ inject: true, // Appends script tags linking to the webpack bundles at the end of the body
100
+ template: path_1.default.resolve(process.cwd(), 'shell/public/index.html'),
101
+ chunks: ['app'],
102
+ }),
103
+ new react_refresh_webpack_plugin_1.default(),
104
+ new fork_ts_checker_webpack_plugin_1.default(),
105
+ ],
106
+ // This configures webpack-dev-server which serves bundles from memory and provides live
107
+ // reloading.
108
+ devServer: (0, common_config_1.getDevServer)(),
109
+ };
110
+ exports.default = config;
@@ -0,0 +1,124 @@
1
+ // @ts-check
2
+
3
+ const { fixupPluginRules } = require('@eslint/compat');
4
+ const eslint = require('@eslint/js');
5
+ const formatjs = require('eslint-plugin-formatjs');
6
+ const jest = require('eslint-plugin-jest');
7
+ const jsxA11y = require('eslint-plugin-jsx-a11y');
8
+ const react = require('eslint-plugin-react');
9
+ const reactHooks = require('eslint-plugin-react-hooks');
10
+ const globals = require('globals');
11
+ const tseslint = require('typescript-eslint');
12
+ const stylistic = require('@stylistic/eslint-plugin');
13
+
14
+ module.exports = tseslint.config(
15
+ eslint.configs.recommended,
16
+ ...tseslint.configs.stylisticTypeChecked,
17
+ ...tseslint.configs.recommended,
18
+ stylistic.configs['recommended-flat'],
19
+ {
20
+ ignores: [
21
+ 'coverage/*',
22
+ 'dist/*',
23
+ 'node_modules/*',
24
+ '**/__mocks__/*',
25
+ '**/__snapshots__/*',
26
+ ],
27
+ },
28
+ {
29
+ languageOptions: {
30
+ parserOptions: {
31
+ projectService: true,
32
+ }
33
+ }
34
+ },
35
+ {
36
+ languageOptions: {
37
+ ...(react.configs.flat !== undefined ? react.configs.flat.recommended.languageOptions : {}),
38
+ globals: {
39
+ ...globals.browser,
40
+ ...globals.node,
41
+ ...globals.jest,
42
+ PARAGON_THEME: 'readonly',
43
+ newrelic: 'readonly',
44
+ },
45
+ },
46
+ plugins: {
47
+ jest,
48
+ // Type assertion is workaround for incorrect TypeScript
49
+ // types in eslint-plugin-react
50
+ //
51
+ // TODO: Remove when types are fixed in eslint-plugin-react
52
+ // - https://github.com/jsx-eslint/eslint-plugin-react/issues/3838
53
+ react: /** @type {import('eslint').ESLint.Plugin} */ (react),
54
+ 'react-hooks': fixupPluginRules(reactHooks),
55
+ formatjs,
56
+ 'jsx-a11y': jsxA11y,
57
+ },
58
+ settings: {
59
+ react: {
60
+ version: 'detect',
61
+ }
62
+ }
63
+ },
64
+ {
65
+ rules: {
66
+ // For some reasons the 'flat' key in react.configs is optional, so Typescript complains if
67
+ // we don't guard using it. But... it exists in the export, so something's odd with their types.
68
+ ...(react.configs.flat !== undefined ? react.configs.flat.recommended.rules : {}),
69
+ ...(react.configs.flat !== undefined ? react.configs.flat['jsx-runtime'].rules : {}),
70
+ ...reactHooks.configs.recommended.rules,
71
+ '@typescript-eslint/no-explicit-any': 'off',
72
+ '@typescript-eslint/non-nullable-type-assertion-style': 'off',
73
+ 'react/no-array-index-key': 'error',
74
+ 'formatjs/enforce-description': ['error', 'literal'],
75
+ 'jsx-a11y/label-has-associated-control': ['error', {
76
+ labelComponents: [],
77
+ labelAttributes: [],
78
+ controlComponents: [],
79
+ assert: 'htmlFor',
80
+ depth: 25,
81
+ }],
82
+ // https://github.com/evcohen/eslint-plugin-jsx-a11y/issues/340#issuecomment-338424908
83
+ 'jsx-a11y/anchor-is-valid': ['error', {
84
+ components: ['Link'],
85
+ specialLink: ['to'],
86
+ }],
87
+ '@typescript-eslint/no-unused-vars': ['error', {
88
+ caughtErrors: 'none',
89
+ }],
90
+ '@typescript-eslint/no-empty-function': 'off',
91
+ '@stylistic/semi': ['error', 'always', { omitLastInOneLineBlock: true, omitLastInOneLineClassBody: true }],
92
+ '@stylistic/quotes': ['error', 'single', {
93
+ avoidEscape: true,
94
+ allowTemplateLiterals: true,
95
+ }],
96
+ '@stylistic/comma-dangle': 'off',
97
+ '@stylistic/quote-props': ['error', 'as-needed'],
98
+ '@stylistic/arrow-parens': 'off',
99
+ '@stylistic/jsx-one-expression-per-line': 'off',
100
+ '@stylistic/multiline-ternary': 'off',
101
+ '@stylistic/brace-style': ['error', '1tbs'],
102
+ '@stylistic/member-delimiter-style': ['error', {
103
+ multiline: {
104
+ delimiter: 'comma',
105
+ requireLast: true,
106
+ },
107
+ singleline: {
108
+ delimiter: 'comma',
109
+ requireLast: false,
110
+ }
111
+ }],
112
+ },
113
+ },
114
+ {
115
+ files: [
116
+ 'babel.config.js',
117
+ 'jest.config.js',
118
+ 'eslint.config.js'
119
+ ],
120
+ rules: {
121
+ '@typescript-eslint/no-require-imports': 'off'
122
+ }
123
+ }
124
+ );
@@ -0,0 +1,5 @@
1
+ // This file needs to exist to declare modules for dependencies that don't publish their types.
2
+
3
+ declare module 'eslint-plugin-jest';
4
+ declare module 'eslint-plugin-jsx-a11y';
5
+ declare module 'eslint-plugin-react-hooks';
@@ -0,0 +1,15 @@
1
+ // @ts-check
2
+
3
+ const tseslint = require('typescript-eslint');
4
+ const eslintConfig = require('./eslint/base.eslint.config.js');
5
+
6
+ module.exports = tseslint.config(
7
+ {
8
+ extends: eslintConfig,
9
+ },
10
+ {
11
+ rules: {
12
+ '@typescript-eslint/no-require-imports': 'off'
13
+ }
14
+ },
15
+ );
package/tools/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { default as createConfig } from './config-helpers/createConfig';
2
+ export { default as createLintConfig } from './config-helpers/createLintConfig';
3
+ export { default as getBaseConfig } from './config-helpers/getBaseConfig';
@@ -0,0 +1,30 @@
1
+ const path = require('path');
2
+
3
+ module.exports = {
4
+ testEnvironment: 'jsdom',
5
+ testEnvironmentOptions: {
6
+ url: 'http://localhost/',
7
+ },
8
+ rootDir: process.cwd(),
9
+ moduleNameMapper: {
10
+ '\\.(css|scss)$': require.resolve('identity-obj-proxy'),
11
+ 'site.config': path.resolve(process.cwd(), './site.config.test.tsx'),
12
+ },
13
+ collectCoverageFrom: [
14
+ 'src/**/*.{js,jsx,ts,tsx}',
15
+ ],
16
+ coveragePathIgnorePatterns: [
17
+ '/node_modules/',
18
+ ],
19
+ transformIgnorePatterns: [
20
+ '/node_modules/(?!(@openedx|@edx)/)',
21
+ ],
22
+ modulePathIgnorePatterns: [
23
+ '/dist/',
24
+ ],
25
+ testPathIgnorePatterns: [
26
+ '/site.config.test.tsx',
27
+ '/node_modules/',
28
+ '/dist/',
29
+ ],
30
+ };
@@ -0,0 +1,19 @@
1
+ module.exports = {
2
+ testEnvironment: 'node',
3
+ testEnvironmentOptions: {
4
+ url: 'http://localhost/',
5
+ },
6
+ collectCoverageFrom: [
7
+ 'cli/**/*.{js,jsx,ts,tsx}',
8
+ ],
9
+ transformIgnorePatterns: [
10
+ '/node_modules/(?!(@openedx|@edx)/)',
11
+ ],
12
+ modulePathIgnorePatterns: [
13
+ '/dist/',
14
+ ],
15
+ testPathIgnorePatterns: [
16
+ '/node_modules/',
17
+ '/dist/',
18
+ ],
19
+ };
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": "@tsconfig/node20/tsconfig.json",
3
+ "compilerOptions": {
4
+ "rootDir": ".",
5
+ "outDir": "dist",
6
+ "noEmit": false,
7
+ "allowJs": true,
8
+ "resolveJsonModule": true,
9
+ },
10
+ "include": [
11
+ "babel/**/*",
12
+ "cli/**/*",
13
+ "config-helpers/**/*",
14
+ "jest/jest.config.js",
15
+ "typescript/tsconfig.json",
16
+ "webpack/**/*",
17
+ "types.ts",
18
+ "index.ts",
19
+ "defaultConfigPaths.ts",
20
+ "eslint/**/*",
21
+ "eslint.config.js",
22
+ "jest.config.js",
23
+ ],
24
+ }
package/tools/types.ts ADDED
@@ -0,0 +1,21 @@
1
+ export enum ConfigTypes {
2
+ BABEL = 'babel',
3
+ WEBPACK_BUILD = 'webpack-build',
4
+ WEBPACK_DEV = 'webpack-dev',
5
+ WEBPACK_DEV_SHELL = 'webpack-dev-shell',
6
+ LINT = 'lint',
7
+ TEST = 'test',
8
+ }
9
+
10
+ export enum CommandTypes {
11
+ RELEASE = 'release',
12
+ PACK = 'pack',
13
+ LINT = 'lint',
14
+ TEST = 'test',
15
+ BUILD = 'build',
16
+ DEV_SHELL = 'dev:shell',
17
+ DEV = 'dev',
18
+ FORMAT_JS = 'formatjs',
19
+ SERVE = 'serve',
20
+ HELP = 'help',
21
+ }
@@ -0,0 +1,32 @@
1
+ {
2
+ "compilerOptions": {
3
+ "allowJs": true,
4
+ "allowSyntheticDefaultImports": true,
5
+ "declaration": true,
6
+ "esModuleInterop": true,
7
+ "forceConsistentCasingInFileNames": true,
8
+ "jsx": "react-jsx",
9
+ "lib": [
10
+ "DOM",
11
+ "DOM.Iterable",
12
+ "ESNext",
13
+ "esnext.intl",
14
+ "es2017.intl",
15
+ "es2018.intl"
16
+ ],
17
+ "isolatedModules": true,
18
+ "module": "ESNext",
19
+ "moduleResolution": "node",
20
+ "noEmit": true,
21
+ "noFallthroughCasesInSwitch": true,
22
+ "noImplicitAny": false,
23
+ "noImplicitThis": true,
24
+ "noUnusedParameters": true,
25
+ "resolveJsonModule": true,
26
+ "skipLibCheck": true,
27
+ "sourceMap": true,
28
+ "strict": true,
29
+ "strictFunctionTypes": false,
30
+ "target": "ES6"
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ # Using this 'common-config' folder
2
+
3
+ **Don't try too hard to re-use code.**
4
+
5
+ If extracting webpack config to this folder makes the config harder to reason, then it's not worth it.
6
+
7
+ The things that have been extracted so far are either:
8
+
9
+ 1) So similar (or exactly the same) across configs that they're easy to understand. `getHtmlWebpackPlugin`, `getImageMinimizer`, `ignoreWarnings`, and `getFileLoaderRules` fit in this category.
10
+ 2) Need to be kept in sync and tended to drift, despite being a bit different. The `getStylesheetRule` and `getCodeRules` functions fit in this category. They are arguably easier to reason all in one place so we can understand the differences between
11
+ them.
12
+
13
+ What they all share in common is that they're fairly long and make the configs harder to read. Extracting them has made the configs about a page of text and all the important high-level stuff that makes them different is still present.
14
+
15
+ More or less. Use your judgment.
@@ -0,0 +1,51 @@
1
+ import { transform } from '@formatjs/ts-transformer';
2
+ import ReactRefreshTypeScript from 'react-refresh-typescript';
3
+
4
+ import { RuleSetRule } from 'webpack';
5
+
6
+ export default function getCodeRules(mode: 'dev' | 'production', resolvedSiteConfigPath: string) {
7
+ const rules: RuleSetRule[] = [
8
+ {
9
+ test: /\.(js|jsx|ts|tsx)$/,
10
+ include: [
11
+ /src/,
12
+ /node_modules\/@openedx\/frontend-base/,
13
+ resolvedSiteConfigPath,
14
+ ],
15
+ use: {
16
+ loader: require.resolve('ts-loader'),
17
+ options: {
18
+ transpileOnly: true,
19
+ compilerOptions: {
20
+ noEmit: false,
21
+ },
22
+ getCustomTransformers() {
23
+ const before = [
24
+ transform({
25
+ overrideIdFn: '[sha512:contenthash:base64:6]',
26
+ }),
27
+ ];
28
+ if (mode === 'dev') {
29
+ before.push(ReactRefreshTypeScript());
30
+ }
31
+ return {
32
+ before,
33
+ };
34
+ },
35
+ },
36
+ },
37
+ },
38
+ ];
39
+
40
+ if (mode === 'production') {
41
+ rules.push({
42
+ test: /\.(js|jsx|ts|tsx)$/,
43
+ use: [
44
+ require.resolve('source-map-loader'),
45
+ ],
46
+ enforce: 'pre',
47
+ });
48
+ }
49
+
50
+ return rules;
51
+ }
@@ -0,0 +1,23 @@
1
+ export default function getFileLoaderRules() {
2
+ return [
3
+ // Webpack, by default, uses the url-loader for images and fonts that are required/included by
4
+ // files it processes, which just base64 encodes them and inlines them in the javascript
5
+ // bundles. This makes the javascript bundles ginormous and defeats caching so we will use the
6
+ // file-loader instead to copy the files directly to the output directory.
7
+ {
8
+ test: /\.(woff2?|ttf|svg|eot)(\?v=\d+\.\d+\.\d+)?$/,
9
+ loader: require.resolve('file-loader'),
10
+ },
11
+ {
12
+ test: /favicon.ico$/,
13
+ loader: require.resolve('file-loader'),
14
+ options: {
15
+ name: '[name].[ext]', // <-- retain original file name
16
+ },
17
+ },
18
+ {
19
+ test: /\.(jpe?g|png|gif)(\?v=\d+\.\d+\.\d+)?$/,
20
+ loader: require.resolve('file-loader'),
21
+ },
22
+ ];
23
+ }
@@ -0,0 +1,13 @@
1
+ import { WebpackError } from 'webpack';
2
+
3
+ export default function getIgnoreWarnings() {
4
+ return [
5
+ // Ignore warnings raised by source-map-loader.
6
+ // some third party packages may ship miss-configured sourcemaps, that interrupts the build
7
+ // See: https://github.com/facebook/create-react-app/discussions/11278#discussioncomment-1780169
8
+ (warning: WebpackError) => !!(
9
+ // @ts-expect-error 'resource' is something TypeScript can't find for whatever reason.
10
+ warning.module?.resource.includes('node_modules')
11
+ && warning.details?.includes('source-map-loader')),
12
+ ];
13
+ }
@@ -0,0 +1,26 @@
1
+ import ImageMinimizerPlugin, { Compiler } from 'image-minimizer-webpack-plugin';
2
+ import { WebpackPluginInstance } from 'webpack';
3
+
4
+ // This is pulled from the definition of optimization.minimizer in the webpack Configuration type.
5
+ type ImageMinimizerReturnType = (false | '' | 0 | '...' | ((this: Compiler, compiler: Compiler) => void) | WebpackPluginInstance | null | undefined)[] | undefined;
6
+
7
+ export default function getImageMinimizer(): ImageMinimizerReturnType {
8
+ return [
9
+ '...',
10
+ new ImageMinimizerPlugin({
11
+ minimizer: {
12
+ implementation: ImageMinimizerPlugin.sharpMinify,
13
+ options: {
14
+ encodeOptions: {
15
+ ...['png', 'jpeg', 'jpg'].reduce((accumulator, value) => (
16
+ { ...accumulator, [value]: { progressive: true, quality: 65 } }
17
+ ), {}),
18
+ gif: {
19
+ effort: 5,
20
+ },
21
+ },
22
+ },
23
+ },
24
+ }),
25
+ ];
26
+ }