@@ -17,30 +17,53 @@ This can be accomplished in different ways for different reasons:
17
17
* - Integration Method
18
18
- Use Case
19
19
20
+ * - :ref: `Dynamically Loaded Components `
21
+ - You want to **quickly experiment ** with IDOM and the Javascript ecosystem.
22
+
20
23
* - :ref: `Custom Javascript Components `
21
24
- You want to create polished software that can be **easily shared ** with others.
22
25
23
- * - :ref: `Dynamically Install Javascript ` (requires NPM _)
24
- - You want to **quickly experiment ** with IDOM and the Javascript ecosystem.
26
+
27
+ Dynamically Loaded Components
28
+ -----------------------------
29
+
30
+ .. note ::
31
+
32
+ This method is not recommended in production systems - see
33
+ :ref: `Distributing Javascript Components ` for more info.
34
+
35
+ IDOM makes it easy to draft your code when you're in the early stages of development by
36
+ using a CDN _ to dynamically load Javascript packages on the fly. In this example we'll
37
+ be using the ubiquitous React-based UI framework `Material UI `_.
38
+
39
+ .. example :: material_ui_button_no_action
40
+
41
+ So now that we can display a Material UI Button we probably want to make it do
42
+ something. Thankfully there's nothing new to learn here, you can pass event handlers to
43
+ the button just as you did when :ref: `getting started `. Thus, all we need to do is add
44
+ an ``onClick `` handler to the component:
45
+
46
+ .. example :: material_ui_button_on_click
25
47
26
48
27
49
Custom Javascript Components
28
50
----------------------------
29
51
30
- For projects that will be shared with others we recommend bundling your Javascript with
52
+ For projects that will be shared with others, we recommend bundling your Javascript with
31
53
`rollup <https://rollupjs.org/guide/en/ >`__ or `webpack <https://webpack.js.org/ >`__
32
54
into a
33
55
`web module <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules >`__.
34
56
IDOM also provides a
35
57
`template repository <https://github.com/idom-team/idom-react-component-cookiecutter >`__
36
58
that can be used as a blueprint to build a library of React components.
37
59
38
- The core benefit of loading Javascript in this way is that users of your code won't need
39
- to have NPM _ installed. Rather, they can use `` pip `` to install your Python package
40
- without any other build steps because the bundled Javascript you distributed with it
41
- will be symlinked into the IDOM client at runtime.
60
+ To work as intended, the Javascript bundle must provide named exports for the following
61
+ functions as well as any components that will be rendered.
62
+
63
+ .. note ::
42
64
43
- To work as intended, the Javascript bundle must export the following named functions:
65
+ The exported components do not have to be React-based since you'll have full control
66
+ over the rendering mechanism.
44
67
45
68
.. code-block :: typescript
46
69
@@ -63,25 +86,17 @@ These functions can be thought of as being analogous to those from React.
63
86
.. |reactDOM.unmountComponentAtNode | replace :: ``reactDOM.unmountComponentAtNode ``
64
87
.. _reactDOM.unmountComponentAtNode : https://reactjs.org/docs/react-api.html#createelement
65
88
66
- And will be called in the following manner:
89
+ And will be called in the following manner, where ``component `` is a named export of
90
+ your module:
67
91
68
92
.. code-block ::
69
93
70
94
// on every render
71
- renderElement(createElement(type , props), container);
95
+ renderElement(createElement(component , props), container);
72
96
// on unmount
73
97
unmountElement(container);
74
98
75
- Once you've done this, you can distribute the bundled javascript in your Python package
76
- and integrate it into IDOM by defining :class: `~idom.client.module.Module ` objects that
77
- load them from source:
78
-
79
- .. code-block ::
80
-
81
- import idom
82
- my_js_package = idom.Module("my-js-package", source_file="/path/to/my/bundle.js")
83
-
84
- The simplest way to try this out yourself though, is to hook in simple a hand-crafted
99
+ The simplest way to try this out yourself though, is to hook in a simple hand-crafted
85
100
Javascript module that has the requisite interface. In the example to follow we'll
86
101
create a very basic SVG line chart. The catch though is that we are limited to using
87
102
Javascript that can run directly in the browser. This means we can't use fancy syntax
@@ -91,58 +106,40 @@ like `JSX <https://reactjs.org/docs/introducing-jsx.html>`__ and instead will us
91
106
.. example :: super_simple_chart
92
107
93
108
94
- .. Links
95
- .. =====
109
+ Distributing Javascript Components
110
+ ----------------------------------
96
111
97
- .. _Material UI : https://material-ui.com/
98
- .. _NPM : https://www.npmjs.com
99
- .. _install NPM : https://www.npmjs.com/get-npm
100
-
101
-
102
-
103
- Dynamically Install Javascript
104
- ------------------------------
105
-
106
- .. warning ::
107
-
108
- - Before continuing `install NPM `_.
109
- - Not guaranteed to work in all client implementations
110
- (see :attr: `~idom.config.IDOM_CLIENT_MODULES_MUST_HAVE_MOUNT `)
111
-
112
- IDOM makes it easy to draft your code when you're in the early stages of development by
113
- using NPM _ to directly install Javascript packages on the fly. In this example we'll be
114
- using the ubiquitous React-based UI framework `Material UI `_ which can be installed
115
- using the ``idom `` CLI:
116
-
117
- .. code-block :: bash
118
-
119
- idom install @material-ui/core
112
+ There are two ways that you can distribute your :ref: `Custom Javascript Components `:
120
113
121
- Or at runtime with :func: ` idom.client.module.install ` (this is useful if you're working
122
- in a REPL or Jupyter Notebook):
114
+ - In a Python package via PyPI _
115
+ - Using a CDN _
123
116
124
- .. code-block ::
125
-
126
- import idom
127
- material_ui = idom.install("@material-ui/core")
128
- # or install multiple modules at once
129
- material_ui, *other_modules = idom.install(["@material-ui/core", ...])
130
-
131
- .. note ::
117
+ That can be subsequently loaded using the respective functions:
132
118
133
- Any standard javascript dependency specifier is allowed here.
119
+ - :func: `~idom.web.module.module_from_file `
120
+ - :func: `~idom.web.module.module_from_url `
134
121
135
- Once the package has been successfully installed, you can import and display the component:
122
+ These options are not mutually exclusive though - if you upload your Javascript
123
+ components to NPM _ and also bundle your Javascript inside a Python package, in principle
124
+ your users can determine which option work best for them. Regardless though, either you
125
+ or, if you give then the choice, your users, will have to consider the tradeoffs of
126
+ either approach.
136
127
137
- .. example :: material_ui_button_no_action
128
+ - Distribution via PyPI _ - This method is ideal for local usage since the user can
129
+ server all the Javascript components they depend on from their computer without
130
+ requiring a network connection.
138
131
132
+ - Distribution via a CDN _ - Most useful in production-grade applications where its assumed
133
+ the user has a network connection. In this scenario a CDN's
134
+ `edge network <https://en.wikipedia.org/wiki/Edge_computing >`__ can be used to bring
135
+ the Javascript source closer to the user in order to reduce page load times.
139
136
140
- Passing Props To Javascript Components
141
- --------------------------------------
142
137
143
- So now that we can install and display a Material UI Button we probably want to make it
144
- do something. Thankfully there's nothing new to learn here, you can pass event handlers
145
- to the button just as you did when :ref: `getting started `. Thus, all we need to do is
146
- add an ``onClick `` handler to the component:
138
+ .. Links
139
+ .. =====
147
140
148
- .. example :: material_ui_button_on_click
141
+ .. _Material UI : https://material-ui.com/
142
+ .. _NPM : https://www.npmjs.com
143
+ .. _install NPM : https://www.npmjs.com/get-npm
144
+ .. _CDN : https://en.wikipedia.org/wiki/Content_delivery_network
145
+ .. _PyPI : https://pypi.org/
0 commit comments