diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8d9cf35d2..d93d730917 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,12 @@
All notable changes to `dash` will be documented in this file.
This project adheres to [Semantic Versioning](https://semver.org/).
+## [UNRELEASED]
+
+## Fixed
+
+- [#2783](https://github.com/plotly/dash/pull/2783) Remove dynamic loading.
+
## [2.16.0] - 2024-03-01
## Fixed
diff --git a/dash/_validate.py b/dash/_validate.py
index 29caf0ace2..dcd075b8cd 100644
--- a/dash/_validate.py
+++ b/dash/_validate.py
@@ -1,3 +1,4 @@
+import sys
from collections.abc import MutableSequence
import re
from textwrap import dedent
@@ -356,6 +357,13 @@ def check_obsolete(kwargs):
See https://dash.plotly.com for details.
"""
)
+ if key in ["dynamic_loading", "preloaded_libraries"]:
+ # Only warns as this was only available for a short time.
+ print(
+ f"{key} has been removed and no longer a valid keyword argument in Dash.",
+ file=sys.stderr,
+ )
+ continue
# any other kwarg mimic the built-in exception
raise TypeError(f"Dash() got an unexpected keyword argument '{key}'")
diff --git a/dash/dash-renderer/src/APIController.react.js b/dash/dash-renderer/src/APIController.react.js
index 9e90dc6268..ed443bad5c 100644
--- a/dash/dash-renderer/src/APIController.react.js
+++ b/dash/dash-renderer/src/APIController.react.js
@@ -1,12 +1,6 @@
import {batch, connect} from 'react-redux';
import {includes, isEmpty} from 'ramda';
-import React, {
- useEffect,
- useRef,
- useState,
- createContext,
- useCallback
-} from 'react';
+import React, {useEffect, useRef, useState, createContext} from 'react';
import PropTypes from 'prop-types';
import TreeContainer from './TreeContainer';
import GlobalErrorContainer from './components/error/GlobalErrorContainer.react';
@@ -27,7 +21,6 @@ import {getAppState} from './reducers/constants';
import {STATUS} from './constants/constants';
import {getLoadingState, getLoadingHash} from './utils/TreeContainer';
import wait from './utils/wait';
-import LibraryManager from './libraries/LibraryManager';
export const DashContext = createContext({});
@@ -53,10 +46,6 @@ const UnconnectedContainer = props => {
if (!events.current) {
events.current = new EventEmitter();
}
-
- const [libraryReady, setLibraryReady] = useState(false);
- const onLibraryReady = useCallback(() => setLibraryReady(true), []);
-
const renderedTree = useRef(false);
const propsRef = useRef({});
@@ -71,9 +60,7 @@ const UnconnectedContainer = props => {
})
});
- useEffect(
- storeEffect.bind(null, props, events, setErrorLoading, libraryReady)
- );
+ useEffect(storeEffect.bind(null, props, events, setErrorLoading));
useEffect(() => {
if (renderedTree.current) {
@@ -130,23 +117,14 @@ const UnconnectedContainer = props => {
content =
Loading...
;
}
- return (
-
- {config && config.ui === true ? (
- {content}
- ) : (
- content
- )}
-
+ return config && config.ui === true ? (
+ {content}
+ ) : (
+ content
);
};
-function storeEffect(props, events, setErrorLoading, libraryReady) {
+function storeEffect(props, events, setErrorLoading) {
const {
appLifecycle,
dependenciesRequest,
@@ -165,7 +143,7 @@ function storeEffect(props, events, setErrorLoading, libraryReady) {
}
dispatch(apiThunk('_dash-layout', 'GET', 'layoutRequest'));
} else if (layoutRequest.status === STATUS.OK) {
- if (isEmpty(layout) && libraryReady) {
+ if (isEmpty(layout)) {
if (typeof hooks.layout_post === 'function') {
hooks.layout_post(layoutRequest.content);
}
@@ -208,8 +186,7 @@ function storeEffect(props, events, setErrorLoading, libraryReady) {
layoutRequest.status === STATUS.OK &&
!isEmpty(layout) &&
// Hasn't already hydrated
- appLifecycle === getAppState('STARTED') &&
- libraryReady
+ appLifecycle === getAppState('STARTED')
) {
let hasError = false;
try {
@@ -258,8 +235,7 @@ const Container = connect(
graphs: state.graphs,
history: state.history,
error: state.error,
- config: state.config,
- paths: state.paths
+ config: state.config
}),
dispatch => ({dispatch})
)(UnconnectedContainer);
diff --git a/dash/dash-renderer/src/CheckedComponent.react.js b/dash/dash-renderer/src/CheckedComponent.react.js
deleted file mode 100644
index 4eeed6d524..0000000000
--- a/dash/dash-renderer/src/CheckedComponent.react.js
+++ /dev/null
@@ -1,30 +0,0 @@
-import checkPropTypes from './checkPropTypes';
-import {propTypeErrorHandler} from './exceptions';
-import {createLibraryElement} from './libraries/createLibraryElement';
-import PropTypes from 'prop-types';
-
-export function CheckedComponent(p) {
- const {element, extraProps, props, children, type} = p;
-
- const errorMessage = checkPropTypes(
- element.propTypes,
- props,
- 'component prop',
- element
- );
- if (errorMessage) {
- propTypeErrorHandler(errorMessage, props, type);
- }
-
- return createLibraryElement(element, props, extraProps, children);
-}
-
-CheckedComponent.propTypes = {
- children: PropTypes.any,
- element: PropTypes.any,
- layout: PropTypes.any,
- props: PropTypes.any,
- extraProps: PropTypes.any,
- id: PropTypes.string,
- type: PropTypes.string
-};
diff --git a/dash/dash-renderer/src/TreeContainer.js b/dash/dash-renderer/src/TreeContainer.js
index b79980e9a8..304cd0be74 100644
--- a/dash/dash-renderer/src/TreeContainer.js
+++ b/dash/dash-renderer/src/TreeContainer.js
@@ -1,5 +1,7 @@
import React, {Component, memo, useContext} from 'react';
import PropTypes from 'prop-types';
+import Registry from './registry';
+import {propTypeErrorHandler} from './exceptions';
import {
addIndex,
assoc,
@@ -7,25 +9,25 @@ import {
concat,
dissoc,
equals,
- has,
isEmpty,
isNil,
+ has,
keys,
map,
mapObjIndexed,
- path as rpath,
- pathOr,
+ mergeRight,
pick,
pickBy,
propOr,
+ path as rpath,
+ pathOr,
type
} from 'ramda';
-import {batch} from 'react-redux';
-
import {notifyObservers, updateProps, onError} from './actions';
import isSimpleComponent from './isSimpleComponent';
import {recordUiEdit} from './persistence';
import ComponentErrorBoundary from './components/error/ComponentErrorBoundary.react';
+import checkPropTypes from './checkPropTypes';
import {getWatchedKeys, stringifyId} from './actions/dependencies';
import {
getLoadingHash,
@@ -33,12 +35,45 @@ import {
validateComponent
} from './utils/TreeContainer';
import {DashContext} from './APIController.react';
-import LibraryComponent from './libraries/LibraryComponent';
+import {batch} from 'react-redux';
const NOT_LOADING = {
is_loading: false
};
+function CheckedComponent(p) {
+ const {element, extraProps, props, children, type} = p;
+
+ const errorMessage = checkPropTypes(
+ element.propTypes,
+ props,
+ 'component prop',
+ element
+ );
+ if (errorMessage) {
+ propTypeErrorHandler(errorMessage, props, type);
+ }
+
+ return createElement(element, props, extraProps, children);
+}
+
+CheckedComponent.propTypes = {
+ children: PropTypes.any,
+ element: PropTypes.any,
+ layout: PropTypes.any,
+ props: PropTypes.any,
+ extraProps: PropTypes.any,
+ id: PropTypes.string
+};
+
+function createElement(element, props, extraProps, children) {
+ const allProps = mergeRight(props, extraProps);
+ if (Array.isArray(children)) {
+ return React.createElement(element, allProps, ...children);
+ }
+ return React.createElement(element, allProps, children);
+}
+
function isDryComponent(obj) {
return (
type(obj) === 'Object' &&
@@ -215,6 +250,8 @@ class BaseTreeContainer extends Component {
}
validateComponent(_dashprivate_layout);
+ const element = Registry.resolve(_dashprivate_layout);
+
// Hydrate components props
const childrenProps = pathOr(
[],
@@ -418,14 +455,17 @@ class BaseTreeContainer extends Component {
dispatch={_dashprivate_dispatch}
error={_dashprivate_error}
>
-
+ {_dashprivate_config.props_check ? (
+
+ ) : (
+ createElement(element, props, extraProps, children)
+ )}
);
}
diff --git a/dash/dash-renderer/src/actions/callbacks.ts b/dash/dash-renderer/src/actions/callbacks.ts
index e1e4b4601b..68320568e5 100644
--- a/dash/dash-renderer/src/actions/callbacks.ts
+++ b/dash/dash-renderer/src/actions/callbacks.ts
@@ -34,7 +34,7 @@ import {
CallbackResponseData
} from '../types/callbacks';
import {isMultiValued, stringifyId, isMultiOutputProp} from './dependencies';
-import {crawlLayout, urlBase} from './utils';
+import {urlBase} from './utils';
import {getCSRFHeader} from '.';
import {createAction, Action} from 'redux-actions';
import {addHttpHeaders} from '../actions';
@@ -44,9 +44,6 @@ import {handlePatch, isPatch} from './patch';
import {getPath} from './paths';
import {requestDependencies} from './requestDependencies';
-import loadLibrary from '../libraries/loadLibrary';
-import fetchDist from '../libraries/fetchDist';
-import {setLibraryLoaded} from './libraries';
export const addBlockedCallbacks = createAction(
CallbackActionType.AddBlocked
@@ -366,7 +363,6 @@ function handleServerside(
let runningOff: any;
let progressDefault: any;
let moreArgs = additionalArgs;
- const libraries = Object.keys(getState().libraries);
if (running) {
sideUpdate(running.running, dispatch, paths);
@@ -512,41 +508,8 @@ function handleServerside(
}
if (!long || data.response !== undefined) {
- const newLibs: string[] = [];
- Object.values(data.response as any).forEach(
- (newData: any) => {
- Object.values(newData).forEach(newProp => {
- crawlLayout(newProp, (c: any) => {
- if (
- c.namespace &&
- !libraries.includes(c.namespace) &&
- !newLibs.includes(c.namespace)
- ) {
- newLibs.push(c.namespace);
- }
- });
- });
- }
- );
- if (newLibs.length) {
- fetchDist(
- getState().config.requests_pathname_prefix,
- newLibs
- )
- .then(data => {
- return Promise.all(data.map(loadLibrary));
- })
- .then(() => {
- completeJob();
- finishLine(data);
- dispatch(
- setLibraryLoaded({libraries: newLibs})
- );
- });
- } else {
- completeJob();
- finishLine(data);
- }
+ completeJob();
+ finishLine(data);
} else {
// Poll chain.
setTimeout(
diff --git a/dash/dash-renderer/src/actions/libraries.ts b/dash/dash-renderer/src/actions/libraries.ts
deleted file mode 100644
index 5cac6b3597..0000000000
--- a/dash/dash-renderer/src/actions/libraries.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-import {LibrariesActions} from '../libraries/libraryTypes';
-
-const createAction = (type: LibrariesActions) => (payload: any) => ({
- type,
- payload
-});
-
-export const setLibraryLoading = createAction(LibrariesActions.LOAD);
-export const setLibraryLoaded = createAction(LibrariesActions.LOADED);
-export const setLibraryToLoad = createAction(LibrariesActions.TO_LOAD);
diff --git a/dash/dash-renderer/src/libraries/LibraryComponent.tsx b/dash/dash-renderer/src/libraries/LibraryComponent.tsx
deleted file mode 100644
index 0b8b18104c..0000000000
--- a/dash/dash-renderer/src/libraries/LibraryComponent.tsx
+++ /dev/null
@@ -1,47 +0,0 @@
-import React, {useContext, useEffect} from 'react';
-import {LibrariesContext} from './librariesContext';
-import Registry from '../registry';
-import {CheckedComponent} from '../CheckedComponent.react';
-import {createLibraryElement} from './createLibraryElement';
-
-type LibraryComponentProps = {
- type: string;
- namespace: string;
- props: any;
- extraProps: any;
- children: any;
- props_check: boolean;
-};
-
-const LibraryComponent = (props: LibraryComponentProps) => {
- const {props_check, namespace, type, ...rest} = props;
-
- const context = useContext(LibrariesContext);
-
- useEffect(() => {
- context.addToLoad(namespace);
- }, []);
-
- if (!context.isLoaded(namespace)) {
- return <>>;
- }
- const element = Registry.resolve({namespace, type});
- if (props_check) {
- return (
-
- );
- }
- return createLibraryElement(
- element,
- rest.props,
- rest.extraProps,
- rest.children
- );
-};
-export default LibraryComponent;
diff --git a/dash/dash-renderer/src/libraries/LibraryManager.tsx b/dash/dash-renderer/src/libraries/LibraryManager.tsx
deleted file mode 100644
index ad248be751..0000000000
--- a/dash/dash-renderer/src/libraries/LibraryManager.tsx
+++ /dev/null
@@ -1,67 +0,0 @@
-import React, {JSX, useEffect, useState} from 'react';
-
-import {createLibrariesContext, LibrariesContext} from './librariesContext';
-import {crawlLayout} from '../actions/utils';
-import {isEmpty} from 'ramda';
-
-type LibrariesManagerProps = {
- children: JSX.Element;
- requests_pathname_prefix: string;
- onReady: () => void;
- ready: boolean;
- layout?: any;
- initialLibraries?: string[];
-};
-
-const LibraryProvider = (props: LibrariesManagerProps) => {
- const {
- children,
- requests_pathname_prefix,
- onReady,
- ready,
- initialLibraries
- } = props;
- const contextValue = createLibrariesContext(
- requests_pathname_prefix,
- initialLibraries as string[],
- onReady,
- ready
- );
- return (
-
- {children}
-
- );
-};
-
-const LibraryManager = (props: LibrariesManagerProps) => {
- const {children, ready, layout} = props;
-
- const [initialLibraries, setInitialLibraries] = useState(
- null
- );
-
- useEffect(() => {
- if (layout && !isEmpty(layout) && !ready && !initialLibraries) {
- const libraries: string[] = [];
- crawlLayout(layout, (child: any) => {
- if (child.namespace && !libraries.includes(child.namespace)) {
- libraries.push(child.namespace);
- }
- });
- setInitialLibraries(libraries);
- }
- }, [layout, ready, initialLibraries]);
-
- if (!initialLibraries) {
- return children;
- }
-
- return (
-
- {children}
-
- );
-};
-
-export default LibraryManager;
diff --git a/dash/dash-renderer/src/libraries/createLibraryElement.js b/dash/dash-renderer/src/libraries/createLibraryElement.js
deleted file mode 100644
index e5ebe6fa68..0000000000
--- a/dash/dash-renderer/src/libraries/createLibraryElement.js
+++ /dev/null
@@ -1,10 +0,0 @@
-import {mergeRight} from 'ramda';
-import React from 'react';
-
-export function createLibraryElement(element, props, extraProps, children) {
- const allProps = mergeRight(props, extraProps);
- if (Array.isArray(children)) {
- return React.createElement(element, allProps, ...children);
- }
- return React.createElement(element, allProps, children);
-}
diff --git a/dash/dash-renderer/src/libraries/fetchDist.ts b/dash/dash-renderer/src/libraries/fetchDist.ts
deleted file mode 100644
index d82841e6d2..0000000000
--- a/dash/dash-renderer/src/libraries/fetchDist.ts
+++ /dev/null
@@ -1,12 +0,0 @@
-import {LibraryResource} from './libraryTypes';
-
-export default function fetchDist(
- pathnamePrefix: string,
- libraries: string[]
-): Promise {
- return fetch(`${pathnamePrefix}_dash-dist`, {
- body: JSON.stringify(libraries),
- headers: {'Content-Type': 'application/json'},
- method: 'POST'
- }).then(response => response.json());
-}
diff --git a/dash/dash-renderer/src/libraries/librariesContext.ts b/dash/dash-renderer/src/libraries/librariesContext.ts
deleted file mode 100644
index ed871850c8..0000000000
--- a/dash/dash-renderer/src/libraries/librariesContext.ts
+++ /dev/null
@@ -1,132 +0,0 @@
-import {createContext, useEffect, useState} from 'react';
-import {pathOr, toPairs} from 'ramda';
-import loadLibrary from './loadLibrary';
-import {batch, useDispatch, useSelector} from 'react-redux';
-import {LibrariesState} from './libraryTypes';
-import {
- setLibraryLoaded,
- setLibraryLoading,
- setLibraryToLoad
-} from '../actions/libraries';
-import fetchDist from './fetchDist';
-
-export type LibrariesContextType = {
- state: LibrariesState;
- isLoading: (libraryName: string) => boolean;
- isLoaded: (libraryName: string) => boolean;
- fetchLibraries: () => void;
- getLibrariesToLoad: () => string[];
- addToLoad: (libName: string) => void;
-};
-
-function librarySelector(s: any) {
- return s.libraries as LibrariesState;
-}
-
-export function createLibrariesContext(
- pathnamePrefix: string,
- initialLibraries: string[],
- onReady: () => void,
- ready: boolean
-): LibrariesContextType {
- const dispatch = useDispatch();
- const state = useSelector(librarySelector);
- const [callback, setCallback] = useState(-1);
-
- const isLoaded = (libraryName: string) =>
- pathOr(false, [libraryName, 'loaded'], state);
- const isLoading = (libraryName: string) =>
- pathOr(false, [libraryName, 'loading'], state);
-
- const addToLoad = (libraryName: string) => {
- const lib = state[libraryName];
- if (!lib) {
- // Check if already loaded on the window
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- if (window[libraryName]) {
- dispatch(setLibraryLoaded({libraries: [libraryName]}));
- } else {
- dispatch(setLibraryToLoad({library: libraryName}));
- }
- }
- // if lib is already in don't do anything.
- };
-
- const getLibrariesToLoad = () =>
- toPairs(state).reduce((acc: string[], [key, value]) => {
- if (value.toLoad) {
- acc.push(key);
- }
- return acc;
- }, []);
-
- const fetchLibraries = () => {
- const libraries = getLibrariesToLoad();
- if (!libraries.length) {
- return;
- }
-
- dispatch(setLibraryLoading({libraries}));
-
- fetchDist(pathnamePrefix, libraries)
- .then(data => {
- return Promise.all(data.map(loadLibrary));
- })
- .then(() => {
- dispatch(setLibraryLoaded({libraries}));
- setCallback(-1);
- onReady();
- });
- };
-
- useEffect(() => {
- batch(() => {
- const loaded: string[] = [];
- initialLibraries.forEach(lib => {
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
- // @ts-ignore
- if (window[lib]) {
- loaded.push(lib);
- } else {
- dispatch(setLibraryToLoad({library: lib}));
- }
- });
- if (loaded.length) {
- dispatch(setLibraryLoaded({libraries: loaded}));
- }
- if (loaded.length === initialLibraries.length) {
- onReady();
- }
- });
- }, [initialLibraries]);
-
- // Load libraries on a throttle to have time to gather all the components in one go.
- useEffect(() => {
- if (ready) {
- return;
- }
- const libraries = getLibrariesToLoad();
- if (!libraries.length) {
- return;
- }
- if (callback > 0) {
- window.clearTimeout(callback);
- }
- const timeout = window.setTimeout(fetchLibraries, 0);
- setCallback(timeout);
- }, [state, ready, initialLibraries]);
-
- return {
- state,
- isLoaded,
- isLoading,
- fetchLibraries,
- getLibrariesToLoad,
- addToLoad
- };
-}
-
-// eslint-disable-next-line @typescript-eslint/ban-ts-comment
-// @ts-ignore
-export const LibrariesContext = createContext(null);
diff --git a/dash/dash-renderer/src/libraries/libraryTypes.ts b/dash/dash-renderer/src/libraries/libraryTypes.ts
deleted file mode 100644
index b1c5f4887c..0000000000
--- a/dash/dash-renderer/src/libraries/libraryTypes.ts
+++ /dev/null
@@ -1,17 +0,0 @@
-export enum LibrariesActions {
- LOAD = 'LOAD_LIBRARY',
- LOADED = 'LOADED_LIBRARY',
- TO_LOAD = 'TO_LOAD'
-}
-
-export type LibrariesState = {
- [libname: string]: {
- toLoad: boolean;
- loading: boolean;
- loaded: boolean;
- };
-};
-export type LibraryResource = {
- type: '_js_dist' | '_css_dist';
- url: string;
-};
diff --git a/dash/dash-renderer/src/libraries/loadLibrary.ts b/dash/dash-renderer/src/libraries/loadLibrary.ts
deleted file mode 100644
index 0f83670c1d..0000000000
--- a/dash/dash-renderer/src/libraries/loadLibrary.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import {LibraryResource} from './libraryTypes';
-
-export default function (resource: LibraryResource) {
- let prom;
- const head = document.querySelector('head');
- if (resource.type === '_js_dist') {
- const element = document.createElement('script');
- element.src = resource.url;
- element.async = true;
- prom = new Promise((resolve, reject) => {
- element.onload = () => {
- resolve();
- };
- element.onerror = error => reject(error);
- });
-
- head?.appendChild(element);
- } else if (resource.type === '_css_dist') {
- const element = document.createElement('link');
- element.href = resource.url;
- element.rel = 'stylesheet';
- prom = new Promise((resolve, reject) => {
- element.onload = () => {
- resolve();
- };
- element.onerror = error => reject(error);
- });
- head?.appendChild(element);
- }
- return prom;
-}
diff --git a/dash/dash-renderer/src/reducers/libraries.ts b/dash/dash-renderer/src/reducers/libraries.ts
deleted file mode 100644
index 421108b486..0000000000
--- a/dash/dash-renderer/src/reducers/libraries.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import {assocPath, pipe} from 'ramda';
-import {LibrariesActions, LibrariesState} from '../libraries/libraryTypes';
-
-type LoadingPayload = {
- libraries: string[];
-};
-
-type LoadedPayload = {
- libraries: string[];
-};
-
-type ToLoadPayload = {
- library: string;
-};
-
-type LibrariesAction = {
- type: LibrariesActions;
- payload: LoadingPayload | LoadedPayload | ToLoadPayload;
-};
-
-function handleLoad(library: string, state: LibrariesState) {
- return pipe(
- assocPath([library, 'loading'], true),
- assocPath([library, 'toLoad'], false)
- )(state) as LibrariesState;
-}
-
-function handleLoaded(library: string, state: LibrariesState) {
- return pipe(
- assocPath([library, 'loaded'], true),
- assocPath([library, 'loading'], false)
- )(state) as LibrariesState;
-}
-
-export default function librariesReducer(
- state: LibrariesState = {},
- action: LibrariesAction
-): LibrariesState {
- switch (action.type) {
- case LibrariesActions.LOAD:
- return (action.payload as LoadingPayload).libraries.reduce(
- (acc, lib) => handleLoad(lib, acc),
- state
- );
- case LibrariesActions.LOADED:
- return (action.payload as LoadedPayload).libraries.reduce(
- (acc, lib) => handleLoaded(lib, acc),
- state
- );
- case LibrariesActions.TO_LOAD:
- return pipe(
- assocPath(
- [(action.payload as ToLoadPayload).library, 'toLoad'],
- true
- )
- )(state) as LibrariesState;
- default:
- return state;
- }
-}
diff --git a/dash/dash-renderer/src/reducers/reducer.js b/dash/dash-renderer/src/reducers/reducer.js
index f025d27354..97b71b6bce 100644
--- a/dash/dash-renderer/src/reducers/reducer.js
+++ b/dash/dash-renderer/src/reducers/reducer.js
@@ -18,7 +18,6 @@ import layout from './layout';
import loadingMap from './loadingMap';
import paths from './paths';
import callbackJobs from './callbackJobs';
-import libraries from './libraries';
export const apiRequests = [
'dependenciesRequest',
@@ -48,7 +47,6 @@ function mainReducer() {
}, apiRequests);
parts.callbackJobs = callbackJobs;
- parts.libraries = libraries;
return combineReducers(parts);
}
diff --git a/dash/dash-renderer/src/types/callbacks.ts b/dash/dash-renderer/src/types/callbacks.ts
index 6a499cf1d1..62fcb19d20 100644
--- a/dash/dash-renderer/src/types/callbacks.ts
+++ b/dash/dash-renderer/src/types/callbacks.ts
@@ -1,5 +1,3 @@
-import {LibraryResource} from '../libraries/libraryTypes';
-
type CallbackId = string | {[key: string]: any};
export interface ICallbackDefinition {
@@ -105,5 +103,4 @@ export type CallbackResponseData = {
running?: CallbackResponse;
runningOff?: CallbackResponse;
cancel?: ICallbackProperty[];
- resources: LibraryResource[];
};
diff --git a/dash/dash.py b/dash/dash.py
index 318015abe5..1876eecd15 100644
--- a/dash/dash.py
+++ b/dash/dash.py
@@ -404,8 +404,6 @@ def __init__( # pylint: disable=too-many-statements
add_log_handler=True,
hooks: Union[RendererHooks, None] = None,
routing_callback_inputs: Optional[Dict[str, Union[Input, State]]] = None,
- dynamic_loading=True,
- preloaded_libraries=None,
**obsolete,
):
_validate.check_obsolete(obsolete)
@@ -460,8 +458,6 @@ def __init__( # pylint: disable=too-many-statements
title=title,
update_title=update_title,
include_pages_meta=include_pages_meta,
- dynamic_loading=dynamic_loading,
- preloaded_libraries=preloaded_libraries or [],
)
self.config.set_read_only(
[
@@ -472,8 +468,6 @@ def __init__( # pylint: disable=too-many-statements
"serve_locally",
"compress",
"pages_folder",
- "dynamic_loading",
- "preloaded_libraries",
],
"Read-only: can only be set in the Dash constructor",
)
@@ -651,7 +645,6 @@ def _setup_routes(self):
self._add_url("_dash-update-component", self.dispatch, ["POST"])
self._add_url("_reload-hash", self.serve_reload_hash)
self._add_url("_favicon.ico", self._serve_default_favicon)
- self._add_url("_dash-dist", self.serve_dist, methods=["POST"])
self._add_url("", self.index)
if jupyter_dash.active:
@@ -806,10 +799,7 @@ def serve_reload_hash(self):
)
def serve_dist(self):
- libraries = [
- ComponentRegistry.namespace_to_package.get(lib, lib)
- for lib in flask.request.get_json()
- ]
+ libraries = flask.request.get_json()
dists = []
for dist_type in ("_js_dist", "_css_dist"):
resources = ComponentRegistry.get_resources(dist_type, libraries)
@@ -895,13 +885,7 @@ def _relative_url_path(relative_package_path="", namespace=""):
def _generate_css_dist_html(self):
external_links = self.config.external_stylesheets
-
- if self.config.dynamic_loading:
- links = self._collect_and_register_resources(
- self.css.get_library_css(self.config.preloaded_libraries)
- )
- else:
- links = self._collect_and_register_resources(self.css.get_all_css())
+ links = self._collect_and_register_resources(self.css.get_all_css())
return "\n".join(
[
@@ -936,27 +920,20 @@ def _generate_scripts_html(self):
self.scripts._resources._filter_resources(deps, dev_bundles=dev)
)
+ self.config.external_scripts
- )
-
- if not self.config.dynamic_loading:
- srcs += self._collect_and_register_resources(
+ + self._collect_and_register_resources(
self.scripts.get_all_scripts(dev_bundles=dev)
- )
- else:
- srcs += self._collect_and_register_resources(
- self.scripts.get_library_scripts(
- self.config.preloaded_libraries, dev_bundles=dev
+ + self.scripts._resources._filter_resources(
+ _dash_renderer._js_dist, dev_bundles=dev
+ )
+ + self.scripts._resources._filter_resources(
+ dcc._js_dist, dev_bundles=dev
+ )
+ + self.scripts._resources._filter_resources(
+ html._js_dist, dev_bundles=dev
+ )
+ + self.scripts._resources._filter_resources(
+ dash_table._js_dist, dev_bundles=dev
)
- )
-
- srcs += self._collect_and_register_resources(
- self.scripts._resources._filter_resources(
- _dash_renderer._js_dist, dev_bundles=dev
- )
- + self.scripts._resources._filter_resources(dcc._js_dist, dev_bundles=dev)
- + self.scripts._resources._filter_resources(html._js_dist, dev_bundles=dev)
- + self.scripts._resources._filter_resources(
- dash_table._js_dist, dev_bundles=dev
)
)
diff --git a/tests/integration/clientside/test_clientside_functions.py b/tests/integration/clientside/test_clientside_functions.py
index c00062835e..5a955a1564 100644
--- a/tests/integration/clientside/test_clientside_functions.py
+++ b/tests/integration/clientside/test_clientside_functions.py
@@ -2,7 +2,10 @@
import json
from multiprocessing import Value
+from flaky import flaky
+
+@flaky(max_runs=3)
def test_sp001_clientside_setprops(dash_duo):
call_count = Value("i", 0)
diff --git a/tests/integration/long_callback/test_basic_long_callback016.py b/tests/integration/long_callback/test_basic_long_callback016.py
index e822a408e4..ac65d16cf6 100644
--- a/tests/integration/long_callback/test_basic_long_callback016.py
+++ b/tests/integration/long_callback/test_basic_long_callback016.py
@@ -1,6 +1,7 @@
import sys
import pytest
+from flaky import flaky
from tests.integration.long_callback.utils import setup_long_callback_app
@@ -8,6 +9,7 @@
@pytest.mark.skipif(
sys.version_info < (3, 9), reason="Python 3.8 long callbacks tests hangs up"
)
+@flaky(max_runs=3)
def test_lcbc016_multi_page_cancel(dash_duo, manager):
with setup_long_callback_app(manager, "app_page_cancel") as app:
dash_duo.start_server(app)
diff --git a/tests/integration/renderer/test_libraries.py b/tests/integration/renderer/test_libraries.py
deleted file mode 100644
index e7332c99d3..0000000000
--- a/tests/integration/renderer/test_libraries.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from dash import Dash, html, Input, Output
-import dash_test_components as dt
-import dash_generator_test_component_standard as dgs
-
-
-def test_rblib001_dynamic_loading(dash_duo):
- app = Dash(__name__)
-
- app.layout = html.Div(
- [
- html.Button("Insert", id="insert-btn"),
- html.Div(id="output"),
- dgs.MyStandardComponent(id="dgs"),
- ]
- )
-
- @app.callback(
- Output("output", "children"),
- [Input("insert-btn", "n_clicks")],
- prevent_initial_call=True,
- )
- def update_output(_):
- import dash_generator_test_component_nested as dn
-
- return [
- dt.StyledComponent(value="Styled", id="styled"),
- dn.MyNestedComponent(value="nested", id="nested"),
- ]
-
- dash_duo.start_server(app)
-
- def assert_unloaded(namespace):
- assert dash_duo.driver.execute_script(
- f"return window['{namespace}'] === undefined"
- )
-
- def assert_loaded(namespace):
- assert dash_duo.driver.execute_script(
- f"return window['{namespace}'] !== undefined"
- )
-
- assert_unloaded(dt.package_name)
- assert_unloaded("dash_generator_test_component_nested")
- dash_duo.wait_for_element("#dgs")
- assert_unloaded(dt.package_name)
- assert_loaded(dgs.package_name)
-
- dash_duo.wait_for_element("#insert-btn").click()
-
- dash_duo.wait_for_element("#styled")
- assert_loaded(dt.package_name)
- assert_loaded("dash_generator_test_component_nested")
diff --git a/tests/integration/test_generation.py b/tests/integration/test_generation.py
index b888c5b2cc..1ed4f7ac78 100644
--- a/tests/integration/test_generation.py
+++ b/tests/integration/test_generation.py
@@ -56,13 +56,7 @@ def test_gene001_simple_callback(dash_duo):
def test_gene002_arbitrary_resources(dash_duo):
app = Dash(__name__)
- app.layout = Div(
- [
- Button("Click", id="btn"),
- Div(id="container"),
- MyStandardComponent(),
- ]
- )
+ app.layout = Div([Button("Click", id="btn"), Div(id="container")])
@app.callback(Output("container", "children"), [Input("btn", "n_clicks")])
def update_container(n_clicks):