Merge pull request #7513 from tchak/new-vite-fix
fix(vite): porte vite fallback logic from vite legacy plugin
This commit is contained in:
commit
50ef8432a8
12 changed files with 80 additions and 167 deletions
1
Gemfile
1
Gemfile
|
@ -86,7 +86,6 @@ gem 'strong_migrations' # lint database migrations
|
||||||
gem 'turbo-rails'
|
gem 'turbo-rails'
|
||||||
gem 'typhoeus'
|
gem 'typhoeus'
|
||||||
gem 'view_component'
|
gem 'view_component'
|
||||||
gem 'vite_plugin_legacy'
|
|
||||||
gem 'vite_rails'
|
gem 'vite_rails'
|
||||||
gem 'warden'
|
gem 'warden'
|
||||||
gem 'zipline'
|
gem 'zipline'
|
||||||
|
|
|
@ -749,8 +749,6 @@ GEM
|
||||||
axiom-types (~> 0.1)
|
axiom-types (~> 0.1)
|
||||||
coercible (~> 1.0)
|
coercible (~> 1.0)
|
||||||
descendants_tracker (~> 0.0, >= 0.0.3)
|
descendants_tracker (~> 0.0, >= 0.0.3)
|
||||||
vite_plugin_legacy (3.0.2)
|
|
||||||
vite_ruby (~> 3.0, >= 3.0.4)
|
|
||||||
vite_rails (3.0.9)
|
vite_rails (3.0.9)
|
||||||
railties (>= 5.1, < 8)
|
railties (>= 5.1, < 8)
|
||||||
vite_ruby (~> 3.0)
|
vite_ruby (~> 3.0)
|
||||||
|
@ -912,7 +910,6 @@ DEPENDENCIES
|
||||||
typhoeus
|
typhoeus
|
||||||
vcr
|
vcr
|
||||||
view_component
|
view_component
|
||||||
vite_plugin_legacy
|
|
||||||
vite_rails
|
vite_rails
|
||||||
warden
|
warden
|
||||||
web-console
|
web-console
|
||||||
|
|
|
@ -189,21 +189,4 @@ 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
|
||||||
|
|
31
app/helpers/vite_helper.rb
Normal file
31
app/helpers/vite_helper.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
module ViteHelper
|
||||||
|
SAFARI_10_NO_MODULE_FIX = "!function(){var e=document,t=e.createElement('script');if(!('noModule'in t)&&'onbeforeload'in t){var n=!1;e.addEventListener('beforeload',(function(e){if(e.target===t)n=!0;else if(!e.target.hasAttribute('nomodule')||!n)return;e.preventDefault()}),!0),t.type='module',t.src='.',e.head.appendChild(t),t.remove()}}();"
|
||||||
|
|
||||||
|
LEGACY_POLYFILL_ID = 'vite-legacy-polyfill'
|
||||||
|
LEGACY_ENTRY_ID = 'vite-legacy-entry'
|
||||||
|
SYSTEM_JS_INLINE_CODE = "document.querySelectorAll('script[data-legacy-entry]').forEach((e) => System.import(e.getAttribute('data-src')))"
|
||||||
|
|
||||||
|
DETECT_MODERN_BROWSER_VARNAME = '__vite_is_modern_browser'
|
||||||
|
DETECT_MODERN_BROWSER_CODE = "try{import.meta.url;import('_').catch(()=>1);}catch(e){}window.#{DETECT_MODERN_BROWSER_VARNAME}=true;"
|
||||||
|
DYNAMIC_FALLBACK_INLINE_CODE = "!function(){if(window.#{DETECT_MODERN_BROWSER_VARNAME})return;console.warn('vite: loading legacy build because dynamic import or import.meta.url is unsupported, syntax error above should be ignored');var e=document.getElementById('#{LEGACY_POLYFILL_ID}'),n=document.createElement('script');n.src=e.src,n.onload=function(){#{SYSTEM_JS_INLINE_CODE}},document.body.appendChild(n)}();"
|
||||||
|
|
||||||
|
def vite_legacy_javascript_tag(name, asset_type: :javascript)
|
||||||
|
legacy_name = name.sub(/(\..+)|$/, '-legacy\1')
|
||||||
|
src = vite_asset_path(legacy_name, type: :virtual)
|
||||||
|
javascript_include_tag(src, nomodule: true, 'data-legacy-entry': true, 'data-src': src)
|
||||||
|
end
|
||||||
|
|
||||||
|
def vite_legacy_polyfill_tag
|
||||||
|
safe_join [
|
||||||
|
javascript_tag(SAFARI_10_NO_MODULE_FIX, type: :module, nonce: true),
|
||||||
|
javascript_include_tag(vite_asset_path('legacy-polyfills', type: :virtual), nomodule: true, id: LEGACY_POLYFILL_ID)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
def vite_legacy_fallback_tag
|
||||||
|
safe_join [
|
||||||
|
javascript_tag(DETECT_MODERN_BROWSER_CODE, type: :module, nonce: true),
|
||||||
|
javascript_tag(DYNAMIC_FALLBACK_INLINE_CODE, type: :module, nonce: true)
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -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');
|
||||||
|
|
|
@ -1,14 +1,4 @@
|
||||||
import 'core-js/stable';
|
import './polyfills/dataset';
|
||||||
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) {
|
||||||
|
@ -47,79 +37,3 @@ function polyfillIsConnected(proto) {
|
||||||
if (!('isConnected' in Node.prototype)) {
|
if (!('isConnected' in Node.prototype)) {
|
||||||
polyfillIsConnected(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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -15,14 +15,16 @@
|
||||||
|
|
||||||
= vite_client_tag
|
= vite_client_tag
|
||||||
= vite_react_refresh_tag
|
= vite_react_refresh_tag
|
||||||
|
= vite_javascript_tag 'application'
|
||||||
|
- if administrateur_signed_in?
|
||||||
|
= vite_javascript_tag 'track-admin'
|
||||||
|
|
||||||
- if vite_legacy?
|
- if vite_legacy?
|
||||||
= ds_vite_legacy_javascript_tag 'application'
|
= vite_legacy_polyfill_tag
|
||||||
|
= vite_legacy_javascript_tag 'application'
|
||||||
- if administrateur_signed_in?
|
- if administrateur_signed_in?
|
||||||
= ds_vite_legacy_javascript_tag 'track-admin'
|
= vite_legacy_javascript_tag 'track-admin'
|
||||||
- else
|
= vite_legacy_fallback_tag
|
||||||
= 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"))
|
||||||
|
|
|
@ -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__`
|
|
||||||
|
|
|
@ -43,9 +43,7 @@ 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
|
|
||||||
},
|
|
||||||
plugins
|
plugins
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue