Skip to content

Commit e762b77

Browse files
authored
Add react-vite example (#34)
1 parent 19e676a commit e762b77

File tree

11 files changed

+399
-15
lines changed

11 files changed

+399
-15
lines changed

ci/prepare_playwright.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44

55
set -eux
66

7+
./single_example.sh typescript vanilla_webpack
78
./single_example.sh typescript vanilla_rspack
89
./single_example.sh typescript vanilla_vite
9-
./single_example.sh typescript vanilla_webpack
10+
./single_example.sh typescript react_vite
1011
./single_example.sh typescript vue_vite

ci/typescript/create_react_vite.sh

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env bash
2+
3+
set -eux
4+
5+
export OUTPUT_DIRECTORY=../temp/typescript/react_vite
6+
7+
mkdir -p $OUTPUT_DIRECTORY
8+
cd $OUTPUT_DIRECTORY
9+
rm -rf *
10+
11+
function merge-json() {
12+
# merge the second json file into the first.
13+
TEMP_FILE=$(mktemp)
14+
jq '. * input' $1 $2 > TEMP_FILE && mv TEMP_FILE $1
15+
}
16+
17+
# 1. Create base vite project
18+
npm create vite@latest . -- --template react-ts --yes
19+
20+
# 2. Build and run initial basic project
21+
# npm install
22+
# # npm run dev
23+
# In a web browser navigate to http://localhost:5173/
24+
25+
# 3. Simplify by removing some unwanted files
26+
rm src/assets/react.svg src/App.css src/index.css public/vite.svg
27+
28+
# 4. Replace src/App.tsx with a simple hello example
29+
cat > src/App.tsx << EOF
30+
function App() {
31+
return (
32+
<>
33+
<div>Hello</div>
34+
</>
35+
)
36+
}
37+
38+
export default App
39+
EOF
40+
41+
# 5. Remove CSS lines from src/main.tsx by replacing it
42+
cat > src/main.tsx << EOF
43+
import { StrictMode } from 'react'
44+
import { createRoot } from 'react-dom/client'
45+
import App from './App.tsx'
46+
47+
createRoot(document.getElementById('root')!).render(
48+
<StrictMode>
49+
<App />
50+
</StrictMode>,
51+
)
52+
EOF
53+
54+
# 6. Build and run the minimal example
55+
# # npm run dev
56+
# In a web browser navigate to http://localhost:5173/
57+
58+
# 7. Add BokehJS dependency to this project. This assumes the package has been built and copied to the root directory of this repository as outlined in the top-level README.md.
59+
npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz
60+
61+
# 8. Create a new file src/components/BokehComponent.tsx containing a BokehJS plot component
62+
mkdir -p src
63+
cat > src/BokehComponent.tsx << EOF
64+
import { useEffect, useRef } from 'react'
65+
import * as Bokeh from "@bokeh/bokehjs";
66+
67+
console.info("BokehJS version:", Bokeh.version);
68+
69+
function create_bokehjs_plot(): Bokeh.Column {
70+
const source = new Bokeh.ColumnDataSource({data: { x: [0.1, 0.9], y: [0.1, 0.9], size: [40, 10] }});
71+
72+
const plot = Bokeh.Plotting.figure({
73+
title: "Example BokehJS plot", height: 500, width: 500,
74+
x_range: [0, 1], y_range: [0, 1], sizing_mode: "stretch_width",
75+
});
76+
77+
plot.scatter({ field: "x" }, { field: "y" }, {source, size: { field: "size" }});
78+
79+
const button = new Bokeh.Widgets.Button({label: "Click me to add a point", button_type: "primary"});
80+
function button_callback() {
81+
const data = source.data as any;
82+
data.x.push(Math.random());
83+
data.y.push(Math.random());
84+
data.size.push(10 + Math.random()*30);
85+
source.change.emit();
86+
}
87+
button.on_click(button_callback);
88+
89+
return new Bokeh.Column({children: [plot, button], sizing_mode: "stretch_width"});
90+
}
91+
92+
export function BokehComponent() {
93+
const shown = useRef(false);
94+
useEffect(() => {
95+
if (!shown.current) {
96+
Bokeh.Plotting.show(create_bokehjs_plot(), "#target");
97+
shown.current = true;
98+
}
99+
}, [])
100+
101+
return (
102+
<>
103+
<div id="target"></div>
104+
</>
105+
)
106+
}
107+
EOF
108+
109+
# 9. Replace src/App.tsx so that it uses the BokehComponent
110+
cat > src/App.tsx << EOF
111+
import { BokehComponent } from './BokehComponent.tsx'
112+
113+
function App() {
114+
return (
115+
<>
116+
<BokehComponent />
117+
</>
118+
)
119+
}
120+
121+
export default App
122+
EOF
123+
124+
# 10. Rebuild and serve
125+
# npm run dev
126+
# In a web browser navigate to http://localhost:5173/

ci/typescript/create_vue_vite.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ EOF
4949
# 7. Add BokehJS dependency to this project. This assumes the package has been built and copied to the root directory of this repository as outlined in the top-level README.md.
5050
npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz
5151

52-
# 8. Create a new file of src/components/BokehComponent.vue with code to create BokehJS plot
52+
# 8. Create a new file src/components/BokehComponent.vue containing a BokehJS plot component
5353
mkdir -p src/components
5454
cat > src/components/BokehComponent.vue << EOF
5555
<script setup lang="ts">

recipes/src/recipes/typescript/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
export * from './react_vite_recipe';
12
export * from './vanilla_rspack_recipe';
23
export * from './vanilla_vite_recipe';
34
export * from './vanilla_webpack_recipe';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import { Recipe } from '../../recipe';
2+
import { CommandStep, CreateFileStep, RemoveFilesStep, ReplaceFileStep } from '../../step';
3+
import { baseTypeScriptExample } from './common';
4+
5+
export class ReactViteRecipe extends Recipe {
6+
constructor() {
7+
super(
8+
'typescript',
9+
'react',
10+
'vite',
11+
'Create an initial basic project using `create-vite`.'
12+
);
13+
14+
this.add(new CommandStep(
15+
'Create base `vite` project',
16+
['npm create vite@latest . -- --template react-ts --yes']
17+
));
18+
19+
this.add(new CommandStep(
20+
'Build and run initial basic project',
21+
['npm install', 'npm run dev'],
22+
'In a web browser navigate to http://localhost:5173/',
23+
true
24+
));
25+
26+
this.add(new RemoveFilesStep(
27+
'Simplify by removing some unwanted files',
28+
['src/assets/react.svg', 'src/App.css', 'src/index.css', 'public/vite.svg']
29+
));
30+
31+
this.add(new ReplaceFileStep(
32+
'Replace `src/App.tsx` with a simple hello example',
33+
'src/App.tsx',
34+
`function App() {
35+
return (
36+
<>
37+
<div>Hello</div>
38+
</>
39+
)
40+
}
41+
42+
export default App`)
43+
);
44+
45+
46+
this.add(new ReplaceFileStep(
47+
'Remove CSS lines from `src/main.tsx` by replacing it',
48+
'src/main.tsx',
49+
`import { StrictMode } from 'react'
50+
import { createRoot } from 'react-dom/client'
51+
import App from './App.tsx'
52+
53+
createRoot(document.getElementById('root')!).render(
54+
<StrictMode>
55+
<App />
56+
</StrictMode>,
57+
)`)
58+
);
59+
60+
this.add(new CommandStep(
61+
'Build and run the minimal example',
62+
['npm run dev'],
63+
'In a web browser navigate to http://localhost:5173/',
64+
true
65+
));
66+
67+
this.add(new CommandStep(
68+
'Add BokehJS dependency to this project. This assumes the package has been built and ' +
69+
'copied to the root directory of this repository as outlined in the top-level `README.md`.',
70+
['npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz']
71+
));
72+
73+
this.add(new CreateFileStep(
74+
'Create a new file `src/components/BokehComponent.tsx` containing a BokehJS plot component',
75+
'src/BokehComponent.tsx',
76+
"import { useEffect, useRef } from 'react'\n" +
77+
baseTypeScriptExample.import + "\n" +
78+
baseTypeScriptExample.version + "\n" +
79+
baseTypeScriptExample.function + "\n" +
80+
`export function BokehComponent() {
81+
const shown = useRef(false);
82+
useEffect(() => {
83+
if (!shown.current) {` + "\n" +
84+
' ' + baseTypeScriptExample.show() +
85+
` shown.current = true;
86+
}
87+
}, [])
88+
89+
return (
90+
<>
91+
<div id="target"></div>
92+
</>
93+
)
94+
}`)
95+
);
96+
97+
this.add(new ReplaceFileStep(
98+
'Replace `src/App.tsx` so that it uses the `BokehComponent`',
99+
'src/App.tsx',
100+
`import { BokehComponent } from './BokehComponent.tsx'
101+
102+
function App() {
103+
return (
104+
<>
105+
<BokehComponent />
106+
</>
107+
)
108+
}
109+
110+
export default App`)
111+
);
112+
113+
this.add(new CommandStep(
114+
'Rebuild and serve',
115+
['npm run dev'],
116+
'In a web browser navigate to http://localhost:5173/'
117+
));
118+
}
119+
}

recipes/src/recipes/typescript/vue_vite_recipe.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ createApp(App).mount('#app')`)
6161
));
6262

6363
this.add(new CreateFileStep(
64-
'Create a new file of `src/components/BokehComponent.vue` with code to create BokehJS plot',
64+
'Create a new file `src/components/BokehComponent.vue` containing a BokehJS plot component',
6565
'src/components/BokehComponent.vue',
6666
'<script setup lang="ts">\n' +
6767
"import { useTemplateRef, onMounted } from 'vue'\n" +

recipes/src/util.ts

+4-5
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@ export function fileExtension(filename: string): string {
88
export function languageFromExtension(filename: string): string {
99
const extension = fileExtension(filename);
1010
switch (extension) {
11-
case '.html': {
12-
return 'html';
13-
}
14-
case '.json': {
15-
return 'json';
11+
case '.html':
12+
case '.json':
13+
case '.tsx': {
14+
return extension;
1615
}
1716
case '.ts':
1817
case '.vue': {

0 commit comments

Comments
 (0)