Open CNFeffery opened 1 year ago
solved.
class CustomDash(dash.Dash):
def interpolate_index(self, **kwargs):
scripts = kwargs.pop('scripts')
# 提取scripts部分符合条件的外部js资源
external_scripts = re.findall(
'(<script src="http.*?"></script>)',
scripts
)
# 将原有的script标签内容替换为带备用地址错误切换的版本
for external_script in external_scripts:
scripts = scripts.replace(
external_script,
'''<script src="{}" onerror='this.remove(); let fallbackScript = document.createElement("script"); fallbackScript.src = "{}"; document.querySelector("head").prepend(fallbackScript);'></script>'''.format(
re.findall('"(.*?)"', external_script)[0],
re.findall('"(.*?)"', external_script)[0]
.replace('https://unpkg.com/', 'https://npm.elemecdn.com/')
)
)
scripts = '''<script>
window.onerror = async function(message, source, lineno, colno, error) {
if (message.includes('is not defined') !== -1) {
await waitForModules();
}
}
async function waitForModules() {
const requiredModules = [
'DashRenderer',
'dash_html_components',
'dash_core_components',
'feffery_antd_components',
'feffery_utils_components',
'feffery_markdown_components'
];
while (!areModulesDefined(requiredModules)) {
await delay(100); // 延迟100毫秒
}
// 变量已定义,触发事件
var renderer = new DashRenderer();
}
function areModulesDefined(modules) {
return modules.every(module => window[module]);
}
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
</script>
''' + scripts
return super(CustomDash, self).interpolate_index(scripts=scripts, **kwargs)
Thanks @CNFeffery - I'm glad to see you found a solution. I haven't seen CDN fallbacks implemented before, is this common? If it is, we would gladly accept a feature to build this in natively, something like app = Dash(cdn_fallbacks={"unpkg.com": "npm.elemecdn.com"})
@alexcjohnson Yes, it is common for origin CDN loads to fail due to unexpected network issues, in my solution I defined the requiredModules
manually, it will be much more convenient if there are some parameters like cdn_fallbacks
you mentioned😀.
OK great. I'll reopen this issue so it's more visible - I don't know if anyone here at Plotly will work on it in the near future, but if you or anyone else wants to make a PR to add cdn_fallbacks
they'll have your code as a fantastic starting point!
My current solution is as below:
but it meets the
Uncaught ReferenceError: DashRenderer is not defined
error:is there a stable way to solve this issue🤔?