Merge pull request #7510 from tchak/fix-dynamic-import

fix(vite): temporary use legacy build in all browsers
This commit is contained in:
Paul Chavard 2022-06-30 10:53:15 +02:00 committed by GitHub
commit 8a729ae5ee
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 55 deletions

View file

@ -189,4 +189,21 @@ module ApplicationHelper
Rails.env.production? || ENV['VITE_LEGACY'] == 'enabled' Rails.env.production? || ENV['VITE_LEGACY'] == 'enabled'
end end
end end
def ds_vite_legacy_javascript_tag(name, asset_type: :javascript)
legacy_name = name.sub(/(\..+)|$/, '-legacy\1')
import_tag = tag(:script) do
# rubocop:disable Rails/OutputSafety
"System.import('#{vite_asset_path(legacy_name, type: asset_type)}')".html_safe
# rubocop:enable Rails/OutputSafety
end
safe_join [ds_vite_legacy_polyfill_tag, import_tag]
end
# Internal: Renders the vite-legacy-polyfill to enable code splitting in
# browsers that do not support modules.
def ds_vite_legacy_polyfill_tag
tag(:script, nil, src: vite_asset_path('legacy-polyfills', type: :virtual))
end
end end

View file

@ -1,10 +1,11 @@
import { Controller } from '@hotwired/stimulus'; import { Controller } from '@hotwired/stimulus';
import { toggle, delegate } from '@utils'; import { toggle, delegate } from '@utils';
import Chartkick from 'chartkick';
import Highcharts from 'highcharts';
export class ChartkickController extends Controller { export class ChartkickController extends Controller {
async connect() { async connect() {
const Highcharts = await import('highcharts');
const Chartkick = await import('chartkick');
Chartkick.use(Highcharts); Chartkick.use(Highcharts);
const reflow = (nextChartId?: string) => const reflow = (nextChartId?: string) =>
nextChartId && Chartkick.charts[nextChartId]?.getChartObject()?.reflow(); nextChartId && Chartkick.charts[nextChartId]?.getChartObject()?.reflow();

View file

@ -1,38 +1,24 @@
import { Controller } from '@hotwired/stimulus'; import { Controller } from '@hotwired/stimulus';
import React from 'react'; import React, { lazy, Suspense, FunctionComponent } from 'react';
import { render, unmountComponentAtNode } from 'react-dom'; import { render, unmountComponentAtNode } from 'react-dom';
import invariant from 'tiny-invariant'; import invariant from 'tiny-invariant';
type Props = Record<string, unknown>; type Props = Record<string, unknown>;
type Loader = () => Promise<{ default: FunctionComponent<Props> }>;
const componentsRegistry = new Map<string, FunctionComponent<Props>>();
const components = import.meta.glob('../components/*.tsx');
const componentsRegistry = new Map(); for (const [path, loader] of Object.entries(components)) {
const [filename] = path.split('/').reverse();
import ComboAdresseSearch from '../components/ComboAdresseSearch'; const componentClassName = filename.replace(/\.(ts|tsx)$/, '');
import ComboAnnuaireEducationSearch from '../components/ComboAnnuaireEducationSearch'; console.debug(
import ComboCommunesSearch from '../components/ComboCommunesSearch'; `Registered lazy default export for "${componentClassName}" component`
import ComboDepartementsSearch from '../components/ComboDepartementsSearch'; );
import ComboMultiple from '../components/ComboMultiple'; componentsRegistry.set(
import ComboMultipleDropdownList from '../components/ComboMultipleDropdownList'; componentClassName,
import ComboPaysSearch from '../components/ComboPaysSearch'; LoadableComponent(loader as Loader)
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);
// Initialize React components when their markup appears into the DOM. // Initialize React components when their markup appears into the DOM.
// //
@ -68,7 +54,19 @@ export class ReactController extends Controller {
render(<Component {...props} />, node); render(<Component {...props} />, node);
} }
private getComponent(componentName: string) { private getComponent(componentName: string): FunctionComponent<Props> | null {
return componentsRegistry.get(componentName) ?? null; return componentsRegistry.get(componentName) ?? null;
} }
} }
const Spinner = () => <div className="spinner left" />;
function LoadableComponent(loader: Loader): FunctionComponent<Props> {
const LazyComponent = lazy(loader);
const Component: FunctionComponent<Props> = (props: Props) => (
<Suspense fallback={<Spinner />}>
<LazyComponent {...props} />
</Suspense>
);
return Component;
}

View file

@ -1,5 +1,8 @@
import { Controller } from '@hotwired/stimulus'; 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');
}
}

View file

@ -68,5 +68,5 @@ Turbo.session.drive = false;
// Expose globals // Expose globals
window.DS = window.DS || DS; window.DS = window.DS || DS;
import '../shared/track/matomo'; import('../shared/track/matomo');
import '../shared/track/sentry'; import('../shared/track/sentry');

View file

@ -1,15 +1,4 @@
import './polyfills/dataset'; import './polyfills/dataset';
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';
// IE 11 has no baseURI (required by turbo) // IE 11 has no baseURI (required by turbo)
if (document.baseURI == undefined) { if (document.baseURI == undefined) {

View file

@ -15,9 +15,14 @@
= vite_client_tag = vite_client_tag
= vite_react_refresh_tag = vite_react_refresh_tag
= vite_javascript_tag 'application' - if vite_legacy?
- if administrateur_signed_in? = ds_vite_legacy_javascript_tag 'application'
= vite_javascript_tag 'track-admin' - if administrateur_signed_in?
= ds_vite_legacy_javascript_tag 'track-admin'
- else
= vite_javascript_tag 'application'
- if administrateur_signed_in?
= vite_javascript_tag 'track-admin'
= preload_link_tag(asset_url("Muli-Regular.woff2")) = preload_link_tag(asset_url("Muli-Regular.woff2"))
= preload_link_tag(asset_url("Muli-Bold.woff2")) = preload_link_tag(asset_url("Muli-Bold.woff2"))
@ -43,9 +48,6 @@
- if content_for?(:footer) - if content_for?(:footer)
= content_for(:footer) = content_for(:footer)
- if vite_legacy?
= vite_legacy_javascript_tag 'application'
= yield :charts_js = yield :charts_js
// Container for custom turbo-stream actions // Container for custom turbo-stream actions

View file

@ -44,7 +44,16 @@ if (shouldBuildLegacy()) {
export default defineConfig({ export default defineConfig({
resolve: { alias: { '@utils': '/shared/utils.ts' } }, resolve: { alias: { '@utils': '/shared/utils.ts' } },
build: { build: {
sourcemap: true sourcemap: true,
rollupOptions: {
output: {
manualChunks(id) {
if (id.match('maplibre') || id.match('mapbox')) {
return 'maplibre';
}
}
}
}
}, },
plugins plugins
}); });