From 23fe07bfbd928d8b45a28727cc626e4a64b5cfbe Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Fri, 1 Jul 2022 10:07:39 +0200 Subject: [PATCH] Revert "Merge pull request #7511 from betagouv/US/fix-dynamic-imports-on-ff-60-69" This reverts commit d2fd5b83a9bfec63200519a49a10a8aa04861ca3, reversing changes made to 183dc4eb2ba5504607723abe2af4362593e867a7. --- .../controllers/chartkick_controller.ts | 5 +- .../controllers/react_controller.tsx | 58 ++++++------ app/javascript/controllers/trix_controller.ts | 9 +- app/javascript/entrypoints/application.js | 4 +- app/javascript/shared/polyfills.js | 88 +------------------ patches/@vitejs+plugin-legacy+1.8.2.patch | 13 --- vite.config.ts | 11 ++- 7 files changed, 50 insertions(+), 138 deletions(-) delete mode 100644 patches/@vitejs+plugin-legacy+1.8.2.patch diff --git a/app/javascript/controllers/chartkick_controller.ts b/app/javascript/controllers/chartkick_controller.ts index 5c89d314b..9398eedfc 100644 --- a/app/javascript/controllers/chartkick_controller.ts +++ b/app/javascript/controllers/chartkick_controller.ts @@ -1,10 +1,11 @@ import { Controller } from '@hotwired/stimulus'; import { toggle, delegate } from '@utils'; -import Chartkick from 'chartkick'; -import Highcharts from 'highcharts'; export class ChartkickController extends Controller { async connect() { + const Highcharts = await import('highcharts'); + const Chartkick = await import('chartkick'); + Chartkick.use(Highcharts); const reflow = (nextChartId?: string) => nextChartId && Chartkick.charts[nextChartId]?.getChartObject()?.reflow(); diff --git a/app/javascript/controllers/react_controller.tsx b/app/javascript/controllers/react_controller.tsx index 896f3b273..cdaff89de 100644 --- a/app/javascript/controllers/react_controller.tsx +++ b/app/javascript/controllers/react_controller.tsx @@ -1,38 +1,24 @@ import { Controller } from '@hotwired/stimulus'; -import React from 'react'; +import React, { lazy, Suspense, FunctionComponent } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import invariant from 'tiny-invariant'; type Props = Record; +type Loader = () => Promise<{ default: FunctionComponent }>; +const componentsRegistry = new Map>(); +const components = import.meta.glob('../components/*.tsx'); -const componentsRegistry = new Map(); - -import ComboAdresseSearch from '../components/ComboAdresseSearch'; -import ComboAnnuaireEducationSearch from '../components/ComboAnnuaireEducationSearch'; -import ComboCommunesSearch from '../components/ComboCommunesSearch'; -import ComboDepartementsSearch from '../components/ComboDepartementsSearch'; -import ComboMultiple from '../components/ComboMultiple'; -import ComboMultipleDropdownList from '../components/ComboMultipleDropdownList'; -import ComboPaysSearch from '../components/ComboPaysSearch'; -import ComboRegionsSearch from '../components/ComboRegionsSearch'; -import ComboSearch from '../components/ComboSearch'; -import MapEditor from '../components/MapEditor'; -import MapReader from '../components/MapReader'; - -componentsRegistry.set('ComboAdresseSearch', ComboAdresseSearch); -componentsRegistry.set( - 'ComboAnnuaireEducationSearch', - ComboAnnuaireEducationSearch -); -componentsRegistry.set('ComboCommunesSearch', ComboCommunesSearch); -componentsRegistry.set('ComboDepartementsSearch', ComboDepartementsSearch); -componentsRegistry.set('ComboMultiple', ComboMultiple); -componentsRegistry.set('ComboMultipleDropdownList', ComboMultipleDropdownList); -componentsRegistry.set('ComboPaysSearch', ComboPaysSearch); -componentsRegistry.set('ComboRegionsSearch', ComboRegionsSearch); -componentsRegistry.set('ComboSearch', ComboSearch); -componentsRegistry.set('MapEditor', MapEditor); -componentsRegistry.set('MapReader', MapReader); +for (const [path, loader] of Object.entries(components)) { + const [filename] = path.split('/').reverse(); + const componentClassName = filename.replace(/\.(ts|tsx)$/, ''); + console.debug( + `Registered lazy default export for "${componentClassName}" component` + ); + componentsRegistry.set( + componentClassName, + LoadableComponent(loader as Loader) + ); +} // Initialize React components when their markup appears into the DOM. // @@ -68,7 +54,19 @@ export class ReactController extends Controller { render(, node); } - private getComponent(componentName: string) { + private getComponent(componentName: string): FunctionComponent | null { return componentsRegistry.get(componentName) ?? null; } } + +const Spinner = () =>
; + +function LoadableComponent(loader: Loader): FunctionComponent { + const LazyComponent = lazy(loader); + const Component: FunctionComponent = (props: Props) => ( + }> + + + ); + return Component; +} diff --git a/app/javascript/controllers/trix_controller.ts b/app/javascript/controllers/trix_controller.ts index 1426f91ca..588ef1202 100644 --- a/app/javascript/controllers/trix_controller.ts +++ b/app/javascript/controllers/trix_controller.ts @@ -1,5 +1,8 @@ import { Controller } from '@hotwired/stimulus'; -import 'trix'; -import '@rails/actiontext'; -export class TrixController extends Controller {} +export class TrixController extends Controller { + connect() { + import('trix'); + import('@rails/actiontext'); + } +} diff --git a/app/javascript/entrypoints/application.js b/app/javascript/entrypoints/application.js index a5dd0bb7b..bedb5083d 100644 --- a/app/javascript/entrypoints/application.js +++ b/app/javascript/entrypoints/application.js @@ -68,5 +68,5 @@ Turbo.session.drive = false; // Expose globals window.DS = window.DS || DS; -import '../shared/track/matomo'; -import '../shared/track/sentry'; +import('../shared/track/matomo'); +import('../shared/track/sentry'); diff --git a/app/javascript/shared/polyfills.js b/app/javascript/shared/polyfills.js index 4cc295ee8..f3dce4c0f 100644 --- a/app/javascript/shared/polyfills.js +++ b/app/javascript/shared/polyfills.js @@ -1,14 +1,4 @@ -import 'core-js/stable'; -import 'regenerator-runtime/runtime'; -import 'dom4'; -import 'intersection-observer'; -import 'whatwg-fetch'; -import '@webcomponents/custom-elements'; -import '@webcomponents/template'; -import '@stimulus/polyfills'; -import 'formdata-polyfill'; -import 'event-target-polyfill'; -import 'yet-another-abortcontroller-polyfill'; +import './polyfills/dataset'; // IE 11 has no baseURI (required by turbo) if (document.baseURI == undefined) { @@ -47,79 +37,3 @@ function polyfillIsConnected(proto) { if (!('isConnected' in Node.prototype)) { polyfillIsConnected(Node.prototype); } - -/* - @preserve dataset polyfill for IE < 11. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/dataset and http://caniuse.com/#search=dataset - - @author ShirtlessKirk copyright 2015 - @license WTFPL (http://www.wtfpl.net/txt/copying) -*/ - -const dash = /-([a-z])/gi; -const dataRegEx = /^data-(.+)/; -const hasEventListener = !!document.addEventListener; -const test = document.createElement('_'); -const DOMAttrModified = 'DOMAttrModified'; - -let mutationSupport = false; - -function clearDataset(event) { - delete event.target._datasetCache; -} - -function toCamelCase(string) { - return string.replace(dash, function (_, letter) { - return letter.toUpperCase(); - }); -} - -function getDataset() { - const dataset = {}; - - for (let attribute of this.attributes) { - let match = attribute.name.match(dataRegEx); - if (match) { - dataset[toCamelCase(match[1])] = attribute.value; - } - } - - return dataset; -} - -function mutation() { - if (hasEventListener) { - test.removeEventListener(DOMAttrModified, mutation, false); - } else { - test.detachEvent(`on${DOMAttrModified}`, mutation); - } - - mutationSupport = true; -} - -if (!test.dataset) { - if (hasEventListener) { - test.addEventListener(DOMAttrModified, mutation, false); - } else { - test.attachEvent(`on${DOMAttrModified}`, mutation); - } - - // trigger event (if supported) - test.setAttribute('foo', 'bar'); - - Object.defineProperty(Element.prototype, 'dataset', { - get: mutationSupport - ? function get() { - if (!this._datasetCache) { - this._datasetCache = getDataset.call(this); - } - - return this._datasetCache; - } - : getDataset - }); - - if (mutationSupport && hasEventListener) { - // < IE9 supports neither - document.addEventListener(DOMAttrModified, clearDataset, false); - } -} diff --git a/patches/@vitejs+plugin-legacy+1.8.2.patch b/patches/@vitejs+plugin-legacy+1.8.2.patch deleted file mode 100644 index 231d5b148..000000000 --- a/patches/@vitejs+plugin-legacy+1.8.2.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/node_modules/@vitejs/plugin-legacy/index.js b/node_modules/@vitejs/plugin-legacy/index.js -index 2f1b199..1901ef6 100644 ---- a/node_modules/@vitejs/plugin-legacy/index.js -+++ b/node_modules/@vitejs/plugin-legacy/index.js -@@ -23,7 +23,7 @@ const detectDynamicImportVarName = '__vite_is_dynamic_import_support' - const detectDynamicImportCode = `try{import("_").catch(()=>1);}catch(e){}window.${detectDynamicImportVarName}=true;` - const dynamicFallbackInlineCode = `!function(){if(window.${detectDynamicImportVarName})return;console.warn("vite: loading legacy build because dynamic import is unsupported, syntax error above should be ignored");var e=document.getElementById("${legacyPolyfillId}"),n=document.createElement("script");n.src=e.src,n.onload=function(){${systemJSInlineCode}},document.body.appendChild(n)}();` - --const forceDynamicImportUsage = `export function __vite_legacy_guard(){import('data:text/javascript,')};` -+const forceDynamicImportUsage = `` - - const legacyEnvVarMarker = `__VITE_IS_LEGACY__` - diff --git a/vite.config.ts b/vite.config.ts index ee780b273..c1eefb422 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -44,7 +44,16 @@ if (shouldBuildLegacy()) { export default defineConfig({ resolve: { alias: { '@utils': '/shared/utils.ts' } }, build: { - sourcemap: true + sourcemap: true, + rollupOptions: { + output: { + manualChunks(id) { + if (id.match('maplibre') || id.match('mapbox')) { + return 'maplibre'; + } + } + } + } }, plugins });