Skip to content

Commit 1c0380d

Browse files
authored
Merge pull request #1685 from plotly/move-renderer-build
Move the renderer build into the renderer dir
2 parents ca4fcf5 + 9810d96 commit 1c0380d

File tree

8 files changed

+73
-61
lines changed

8 files changed

+73
-61
lines changed

CHANGELOG.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This project adheres to [Semantic Versioning](https://semver.org/).
1010

1111
### Changed
1212
- [#1675](https://github.com/plotly/dash/pull/1675) Remove the constraint that `requests_pathname_prefix` ends with `routes_pathname_prefix`. When you are serving your app behind a reverse proxy that rewrites URLs that constraint needs to be violated.
13-
- [#1611](https://github.com/plotly/dash/pull/1611) Package dash-renderer artifacts and dependencies with Dash, and source renderer resources from within Dash.
13+
- [#1611](https://github.com/plotly/dash/pull/1611) and [#1685](https://github.com/plotly/dash/pull/1685) Package dash-renderer artifacts and dependencies with Dash, and source renderer resources from within Dash.
1414
- [#1567](https://github.com/plotly/dash/pull/1567) Julia component generator puts components into `src/jl` - fixes an issue on case-insensitive filesystems when the component name and module name match (modulo case) and no prefix is used. Also reduces JS/Julia clutter in the overloaded `src` directory.
1515

1616
### Fixed

MANIFEST.in

+2
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,5 @@ include dash/favicon.ico
55
include dash/extract-meta.js
66
include dash/deps/*.js
77
include dash/deps/*.map
8+
include dash/dash-renderer/build/*.js
9+
include dash/dash-renderer/build/*.map

dash/_dash_renderer.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@
3737

3838
_js_dist = [
3939
{
40-
"relative_package_path": "deps/dash_renderer.min.js",
41-
"dev_package_path": "deps/dash_renderer.dev.js",
40+
"relative_package_path": "dash-renderer/build/dash_renderer.min.js",
41+
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js",
4242
"external_url": "https://unpkg.com/[email protected]"
43-
"/dash_renderer/dash_renderer.min.js",
43+
"/build/dash_renderer.min.js",
4444
"namespace": "dash",
4545
},
4646
{
47-
"relative_package_path": "deps/dash_renderer.min.js.map",
48-
"dev_package_path": "deps/dash_renderer.dev.js.map",
47+
"relative_package_path": "dash-renderer/build/dash_renderer.min.js.map",
48+
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js.map",
4949
"namespace": "dash",
5050
"dynamic": True,
5151
},

dash/dash-renderer/init.template

+5-5
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ _js_dist_dependencies = [
3737

3838
_js_dist = [
3939
{
40-
"relative_package_path": "deps/dash_renderer.min.js",
41-
"dev_package_path": "deps/dash_renderer.dev.js",
40+
"relative_package_path": "dash-renderer/build/dash_renderer.min.js",
41+
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js",
4242
"external_url": "https://unpkg.com/dash-renderer@$version"
43-
"/dash_renderer/dash_renderer.min.js",
43+
"/build/dash_renderer.min.js",
4444
"namespace": "dash",
4545
},
4646
{
47-
"relative_package_path": "deps/dash_renderer.min.js.map",
48-
"dev_package_path": "deps/dash_renderer.dev.js.map",
47+
"relative_package_path": "dash-renderer/build/dash_renderer.min.js.map",
48+
"dev_package_path": "dash-renderer/build/dash_renderer.dev.js.map",
4949
"namespace": "dash",
5050
"dynamic": True,
5151
},

dash/dash-renderer/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "dash-renderer",
33
"version": "1.9.1",
44
"description": "render dash components in react",
5-
"main": "../deps/dash_renderer.min.js",
5+
"main": "build/dash_renderer.min.js",
66
"scripts": {
77
"prepublishOnly": "rm -rf lib && babel src --extensions=\".ts,.tsx,.js,.jsx\" --out-dir lib --copy-files",
88
"private::format.eslint": "eslint --quiet --fix src tests",
@@ -85,7 +85,7 @@
8585
"whatwg-fetch": "^3.6.2"
8686
},
8787
"files": [
88-
"../deps/*{.js,.map}",
88+
"build/*{.js,.map}",
8989
"/lib/**"
9090
],
9191
"prettier": "@plotly/prettier-config-dash"

dash/dash-renderer/webpack.base.config.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ const rendererOptions = {
4040
main: ['whatwg-fetch', './src/index.js'],
4141
},
4242
output: {
43-
path: path.resolve(__dirname, "..", "deps"),
43+
path: path.resolve(__dirname, "build"),
4444
filename: `${dashLibraryName}.dev.js`,
4545
library: dashLibraryName,
4646
libraryTarget: 'window',
@@ -64,7 +64,7 @@ module.exports = options => [
6464
{
6565
mode: 'production',
6666
output: {
67-
path: path.resolve(__dirname, "..", "deps"),
67+
path: path.resolve(__dirname, "build"),
6868
filename: `${dashLibraryName}.min.js`,
6969
library: dashLibraryName,
7070
libraryTarget: 'window',

dash/development/build_process.py

+24-21
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,20 @@ class BuildProcess(object):
2121
def __init__(self, main, deps_info):
2222
self.logger = logger
2323
self.main = main
24+
self.build_folder = self._concat(self.main, "build")
2425
self.deps_info = deps_info
2526
self.npm_modules = self._concat(self.main, "node_modules")
2627
self.package_lock = self._concat(self.main, "package-lock.json")
2728
self.package = self._concat(self.main, "package.json")
2829
self._parse_package(path=self.package)
29-
self.asset_paths = (self.build_folder, self.npm_modules)
30+
self.asset_paths = (self.deps_folder, self.npm_modules)
3031

3132
def _parse_package(self, path):
3233
with open(path, "r") as fp:
3334
package = json.load(fp)
3435
self.version = package["version"]
3536
self.name = package["name"]
36-
self.build_folder = self._concat(self.main, os.pardir, "deps")
37+
self.deps_folder = self._concat(self.main, os.pardir, "deps")
3738
self.deps = package["dependencies"]
3839

3940
@staticmethod
@@ -79,25 +80,27 @@ def build(self, build=None):
7980

8081
@job("compute the hash digest for assets")
8182
def digest(self):
82-
if not os.path.exists(self.build_folder):
83+
if not os.path.exists(self.deps_folder):
8384
try:
84-
os.makedirs(self.build_folder)
85+
os.makedirs(self.deps_folder)
8586
except OSError:
86-
logger.exception("🚨 having issues manipulating %s", self.build_folder)
87+
logger.exception("🚨 having issues manipulating %s", self.deps_folder)
8788
sys.exit(1)
8889

89-
copies = tuple(
90-
_
91-
for _ in os.listdir(self.build_folder)
92-
if os.path.splitext(_)[-1] in {".js", ".map"}
93-
)
94-
logger.info("bundles in %s %s", self.build_folder, copies)
95-
9690
payload = {self.name: self.version}
97-
for copy in copies:
98-
payload["MD5 ({})".format(copy)] = compute_md5(
99-
self._concat(self.build_folder, copy)
91+
92+
for folder in (self.deps_folder, self.build_folder):
93+
copies = tuple(
94+
_
95+
for _ in os.listdir(folder)
96+
if os.path.splitext(_)[-1] in {".js", ".map"}
10097
)
98+
logger.info("bundles in %s %s", folder, copies)
99+
100+
for copy in copies:
101+
payload["MD5 ({})".format(copy)] = compute_md5(
102+
self._concat(folder, copy)
103+
)
101104

102105
with open(self._concat(self.main, "digest.json"), "w") as fp:
103106
json.dump(payload, fp, sort_keys=True, indent=4, separators=(",", ":"))
@@ -108,11 +111,11 @@ def digest(self):
108111

109112
@job("copy and generate the bundles")
110113
def bundles(self, build=None):
111-
if not os.path.exists(self.build_folder):
114+
if not os.path.exists(self.deps_folder):
112115
try:
113-
os.makedirs(self.build_folder)
116+
os.makedirs(self.deps_folder)
114117
except OSError:
115-
logger.exception("🚨 having issues manipulating %s", self.build_folder)
118+
logger.exception("🚨 having issues manipulating %s", self.deps_folder)
116119
sys.exit(1)
117120

118121
self._parse_package(self.package_lock)
@@ -138,20 +141,20 @@ def bundles(self, build=None):
138141

139142
shutil.copyfile(
140143
self._concat(self.npm_modules, scope, name, subfolder, filename),
141-
self._concat(self.build_folder, target),
144+
self._concat(self.deps_folder, target),
142145
)
143146

144147
_script = "build:dev" if build == "local" else "build:js"
145148
logger.info("run `npm run %s`", _script)
146-
os.chdir(self._concat(self.build_folder, os.pardir, "dash-renderer"))
149+
os.chdir(self.main)
147150
run_command_with_process("npm run {}".format(_script))
148151

149152
logger.info("generate the `__init__.py` from template and versions")
150153
with open(self._concat(self.main, "init.template")) as fp:
151154
t = string.Template(fp.read())
152155

153156
with open(
154-
self._concat(self.build_folder, os.pardir, "_dash_renderer.py"), "w"
157+
self._concat(self.deps_folder, os.pardir, "_dash_renderer.py"), "w"
155158
) as fp:
156159
fp.write(t.safe_substitute(versions))
157160

tests/integration/test_scripts.py

+32-25
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import time
22
import pytest
33

4-
from selenium.webdriver.common.by import By
5-
64
import dash_html_components as html
75
import dash_core_components as dcc
86

@@ -12,20 +10,26 @@
1210
from dash.exceptions import PreventUpdate
1311

1412

15-
def findSyncPlotlyJs(scripts):
16-
for script in scripts:
17-
if "dash_core_components/plotly" in script.get_attribute("src"):
18-
return script
13+
def get_script_sources(dash_duo):
14+
return [s.get_attribute("src") for s in dash_duo.find_elements("script")]
15+
16+
17+
def hasSyncPlotlyJs(dash_duo):
18+
return any("dash_core_components/plotly" in s for s in get_script_sources(dash_duo))
19+
20+
21+
def hasAsyncPlotlyJs(dash_duo):
22+
return any(
23+
"dash_core_components/async-plotlyjs" in s for s in get_script_sources(dash_duo)
24+
)
1925

2026

21-
def findAsyncPlotlyJs(scripts):
22-
for script in scripts:
23-
if "dash_core_components/async-plotlyjs" in script.get_attribute("src"):
24-
return script
27+
def hasWindowPlotly(dash_duo):
28+
return dash_duo.driver.execute_script("return !!window.Plotly")
2529

2630

2731
@pytest.mark.parametrize("is_eager", [True, False])
28-
def test_scripts(dash_duo, is_eager):
32+
def test_scri001_scripts(dash_duo, is_eager):
2933
app = Dash(__name__, eager_loading=is_eager)
3034
app.layout = html.Div([dcc.Graph(id="output", figure={"data": [{"y": [3, 1, 2]}]})])
3135

@@ -37,16 +41,18 @@ def test_scripts(dash_duo, is_eager):
3741
dev_tools_hot_reload=False,
3842
)
3943

40-
# Give time for the async dependency to be requested (if any)
41-
time.sleep(2)
44+
# Wait for the graph to appear
45+
dash_duo.find_element(".js-plotly-plot")
4246

43-
scripts = dash_duo.driver.find_elements(By.CSS_SELECTOR, "script")
47+
assert hasSyncPlotlyJs(dash_duo) is is_eager
4448

45-
assert (findSyncPlotlyJs(scripts) is None) is not is_eager
46-
assert (findAsyncPlotlyJs(scripts) is None) is is_eager
49+
# Webpack 5 deletes the script tag immediately after evaluating it
50+
# https://github.com/plotly/dash/pull/1685#issuecomment-877199466
51+
assert hasAsyncPlotlyJs(dash_duo) is False
52+
assert hasWindowPlotly(dash_duo) is True
4753

4854

49-
def test_scripts_on_request(dash_duo):
55+
def test_scri002_scripts_on_request(dash_duo):
5056
app = Dash(__name__, eager_loading=False)
5157
app.layout = html.Div(id="div", children=[html.Button(id="btn")])
5258

@@ -68,15 +74,16 @@ def load_chart(n_clicks):
6874
# Give time for the async dependency to be requested (if any)
6975
time.sleep(2)
7076

71-
scripts = dash_duo.driver.find_elements(By.CSS_SELECTOR, "script")
72-
assert findSyncPlotlyJs(scripts) is None
73-
assert findAsyncPlotlyJs(scripts) is None
77+
assert hasSyncPlotlyJs(dash_duo) is False
78+
assert hasAsyncPlotlyJs(dash_duo) is False
79+
assert hasWindowPlotly(dash_duo) is False
7480

7581
dash_duo.find_element("#btn").click()
7682

77-
# Give time for the async dependency to be requested (if any)
78-
time.sleep(2)
83+
# Wait for the graph to appear
84+
dash_duo.find_element(".js-plotly-plot")
7985

80-
scripts = dash_duo.driver.find_elements(By.CSS_SELECTOR, "script")
81-
assert findSyncPlotlyJs(scripts) is None
82-
assert findAsyncPlotlyJs(scripts) is not None
86+
assert hasSyncPlotlyJs(dash_duo) is False
87+
# Again, webpack 5 deletes the script tag immediately after evaluating it
88+
assert hasAsyncPlotlyJs(dash_duo) is False
89+
assert hasWindowPlotly(dash_duo) is True

0 commit comments

Comments
 (0)