Skip to content

Add react-vite example #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ci/prepare_playwright.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

set -eux

./single_example.sh typescript vanilla_webpack
./single_example.sh typescript vanilla_rspack
./single_example.sh typescript vanilla_vite
./single_example.sh typescript vanilla_webpack
./single_example.sh typescript react_vite
./single_example.sh typescript vue_vite
126 changes: 126 additions & 0 deletions ci/typescript/create_react_vite.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
#!/usr/bin/env bash

set -eux

export OUTPUT_DIRECTORY=../temp/typescript/react_vite

mkdir -p $OUTPUT_DIRECTORY
cd $OUTPUT_DIRECTORY
rm -rf *

function merge-json() {
# merge the second json file into the first.
TEMP_FILE=$(mktemp)
jq '. * input' $1 $2 > TEMP_FILE && mv TEMP_FILE $1
}

# 1. Create base vite project
npm create vite@latest . -- --template react-ts --yes

# 2. Build and run initial basic project
# npm install
# # npm run dev
# In a web browser navigate to http://localhost:5173/

# 3. Simplify by removing some unwanted files
rm src/assets/react.svg src/App.css src/index.css public/vite.svg

# 4. Replace src/App.tsx with a simple hello example
cat > src/App.tsx << EOF
function App() {
return (
<>
<div>Hello</div>
</>
)
}

export default App
EOF

# 5. Remove CSS lines from src/main.tsx by replacing it
cat > src/main.tsx << EOF
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)
EOF

# 6. Build and run the minimal example
# # npm run dev
# In a web browser navigate to http://localhost:5173/

# 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.
npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz

# 8. Create a new file src/components/BokehComponent.tsx containing a BokehJS plot component
mkdir -p src
cat > src/BokehComponent.tsx << EOF
import { useEffect, useRef } from 'react'
import * as Bokeh from "@bokeh/bokehjs";

console.info("BokehJS version:", Bokeh.version);

function create_bokehjs_plot(): Bokeh.Column {
const source = new Bokeh.ColumnDataSource({data: { x: [0.1, 0.9], y: [0.1, 0.9], size: [40, 10] }});

const plot = Bokeh.Plotting.figure({
title: "Example BokehJS plot", height: 500, width: 500,
x_range: [0, 1], y_range: [0, 1], sizing_mode: "stretch_width",
});

plot.scatter({ field: "x" }, { field: "y" }, {source, size: { field: "size" }});

const button = new Bokeh.Widgets.Button({label: "Click me to add a point", button_type: "primary"});
function button_callback() {
const data = source.data as any;
data.x.push(Math.random());
data.y.push(Math.random());
data.size.push(10 + Math.random()*30);
source.change.emit();
}
button.on_click(button_callback);

return new Bokeh.Column({children: [plot, button], sizing_mode: "stretch_width"});
}

export function BokehComponent() {
const shown = useRef(false);
useEffect(() => {
if (!shown.current) {
Bokeh.Plotting.show(create_bokehjs_plot(), "#target");
shown.current = true;
}
}, [])

return (
<>
<div id="target"></div>
</>
)
}
EOF

# 9. Replace src/App.tsx so that it uses the BokehComponent
cat > src/App.tsx << EOF
import { BokehComponent } from './BokehComponent.tsx'

function App() {
return (
<>
<BokehComponent />
</>
)
}

export default App
EOF

# 10. Rebuild and serve
# npm run dev
# In a web browser navigate to http://localhost:5173/
2 changes: 1 addition & 1 deletion ci/typescript/create_vue_vite.sh
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ EOF
# 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.
npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz

# 8. Create a new file of src/components/BokehComponent.vue with code to create BokehJS plot
# 8. Create a new file src/components/BokehComponent.vue containing a BokehJS plot component
mkdir -p src/components
cat > src/components/BokehComponent.vue << EOF
<script setup lang="ts">
Expand Down
1 change: 1 addition & 0 deletions recipes/src/recipes/typescript/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './react_vite_recipe';
export * from './vanilla_rspack_recipe';
export * from './vanilla_vite_recipe';
export * from './vanilla_webpack_recipe';
Expand Down
119 changes: 119 additions & 0 deletions recipes/src/recipes/typescript/react_vite_recipe.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Recipe } from '../../recipe';
import { CommandStep, CreateFileStep, RemoveFilesStep, ReplaceFileStep } from '../../step';
import { baseTypeScriptExample } from './common';

export class ReactViteRecipe extends Recipe {
constructor() {
super(
'typescript',
'react',
'vite',
'Create an initial basic project using `create-vite`.'
);

this.add(new CommandStep(
'Create base `vite` project',
['npm create vite@latest . -- --template react-ts --yes']
));

this.add(new CommandStep(
'Build and run initial basic project',
['npm install', 'npm run dev'],
'In a web browser navigate to http://localhost:5173/',
true
));

this.add(new RemoveFilesStep(
'Simplify by removing some unwanted files',
['src/assets/react.svg', 'src/App.css', 'src/index.css', 'public/vite.svg']
));

this.add(new ReplaceFileStep(
'Replace `src/App.tsx` with a simple hello example',
'src/App.tsx',
`function App() {
return (
<>
<div>Hello</div>
</>
)
}

export default App`)
);


this.add(new ReplaceFileStep(
'Remove CSS lines from `src/main.tsx` by replacing it',
'src/main.tsx',
`import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'

createRoot(document.getElementById('root')!).render(
<StrictMode>
<App />
</StrictMode>,
)`)
);

this.add(new CommandStep(
'Build and run the minimal example',
['npm run dev'],
'In a web browser navigate to http://localhost:5173/',
true
));

this.add(new CommandStep(
'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`.',
['npm install ../../../../bokeh-bokehjs-3.8.0-dev.1.tgz']
));

this.add(new CreateFileStep(
'Create a new file `src/components/BokehComponent.tsx` containing a BokehJS plot component',
'src/BokehComponent.tsx',
"import { useEffect, useRef } from 'react'\n" +
baseTypeScriptExample.import + "\n" +
baseTypeScriptExample.version + "\n" +
baseTypeScriptExample.function + "\n" +
`export function BokehComponent() {
const shown = useRef(false);
useEffect(() => {
if (!shown.current) {` + "\n" +
' ' + baseTypeScriptExample.show() +
` shown.current = true;
}
}, [])

return (
<>
<div id="target"></div>
</>
)
}`)
);

this.add(new ReplaceFileStep(
'Replace `src/App.tsx` so that it uses the `BokehComponent`',
'src/App.tsx',
`import { BokehComponent } from './BokehComponent.tsx'

function App() {
return (
<>
<BokehComponent />
</>
)
}

export default App`)
);

this.add(new CommandStep(
'Rebuild and serve',
['npm run dev'],
'In a web browser navigate to http://localhost:5173/'
));
}
}
2 changes: 1 addition & 1 deletion recipes/src/recipes/typescript/vue_vite_recipe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ createApp(App).mount('#app')`)
));

this.add(new CreateFileStep(
'Create a new file of `src/components/BokehComponent.vue` with code to create BokehJS plot',
'Create a new file `src/components/BokehComponent.vue` containing a BokehJS plot component',
'src/components/BokehComponent.vue',
'<script setup lang="ts">\n' +
"import { useTemplateRef, onMounted } from 'vue'\n" +
Expand Down
9 changes: 4 additions & 5 deletions recipes/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ export function fileExtension(filename: string): string {
export function languageFromExtension(filename: string): string {
const extension = fileExtension(filename);
switch (extension) {
case '.html': {
return 'html';
}
case '.json': {
return 'json';
case '.html':
case '.json':
case '.tsx': {
return extension;
}
case '.ts':
case '.vue': {
Expand Down
Loading