Skip to content

Commit 6c10fca

Browse files
committed
Move react package to use vite
1 parent 79692fc commit 6c10fca

File tree

3 files changed

+316
-7
lines changed

3 files changed

+316
-7
lines changed

packages/react/index.html

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<!--
2+
~ Copyright (c) 2021-2023 Datalayer, Inc.
3+
~
4+
~ MIT License
5+
-->
6+
7+
<!doctype html>
8+
<html>
9+
<head>
10+
<title>Jupyter React Example</title>
11+
<script id="datalayer-config-data" type="application/json">
12+
{
13+
"jupyterServerUrl": "https://prod1.datalayer.run/api/jupyter-server",
14+
"jupyterServerToken": "60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6",
15+
"runUrl": "https://prod1.datalayer.run",
16+
"token": "",
17+
"cpuEnvironment": "python-cpu-env",
18+
"gpuEnvironment": "pytorch-gpu-env",
19+
"credits": 1
20+
}
21+
</script>
22+
<script id="jupyter-config-data" type="application/json">
23+
{
24+
"appName": "Jupyter React",
25+
"baseUrl": "https://oss.datalayer.run/api/jupyter-server",
26+
"wsUrl": "wss://oss.datalayer.run/api/jupyter-server",
27+
"token": "60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6",
28+
"appUrl": "/lab",
29+
"themesUrl": "/lab/api/themes",
30+
"disableRTC": false,
31+
"terminalsAvailable": "false",
32+
"mathjaxUrl": "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js",
33+
"mathjaxConfig": "TeX-AMS_CHTML-full,Safe"
34+
}
35+
</script>
36+
<script
37+
data-jupyter-widgets-cdn="https://cdn.jsdelivr.net/npm/"
38+
data-jupyter-widgets-cdn-only="true"
39+
></script>
40+
<link
41+
rel="shortcut icon"
42+
href="data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAC7SURBVFiF7ZU9CgIxEIXfTHbPopfYc+pJ9AALtmJnZSOIoJWFoCTzLHazxh/Ebpt5EPIxM8XXTCKTxYyMCYwJFhOYCo4JFiMuu317PZwaqEBUIar4YMmskL73DytGjgu4gAt4PDJdzkkzMBloBhqBgcu69XW+1I+rNSQESNDuaMEhdP/Fj/7oW+ACLuACHk/3F5BAfuMLBjm8/ZnxNvNtHmY4b7Ztut0bqStoVSHfWj9Z6mr8LXABF3CBB3nvkDfEVN6PAAAAAElFTkSuQmCC"
43+
type="image/x-icon"
44+
/>
45+
<link
46+
href="https://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css"
47+
rel="stylesheet"
48+
/>
49+
</head>
50+
51+
<body>
52+
<div id="root"></div>
53+
<script type="module">
54+
// Dynamically import the entry point based on environment variable
55+
const entryPoint = import.meta.env.VITE_ENTRY || 'NotebookThemeColormode';
56+
const entryMap = {
57+
App: '/src/app/App.tsx',
58+
Cell: '/src/examples/Cell.tsx',
59+
Console: '/src/examples/Console.tsx',
60+
FileBrowser: '/src/examples/FileBrowser.tsx',
61+
Notebook: '/src/examples/Notebook.tsx',
62+
NotebookThemeColormode: '/src/examples/NotebookThemeColormode.tsx',
63+
Terminal: '/src/examples/Terminal.tsx',
64+
Viewer: '/src/examples/Viewer.tsx',
65+
};
66+
67+
const modulePath =
68+
entryMap[entryPoint] || '/src/examples/NotebookThemeColormode.tsx';
69+
import(modulePath).then(module => {
70+
console.log(`Loaded entry: ${entryPoint} from ${modulePath}`);
71+
});
72+
</script>
73+
</body>
74+
</html>

packages/react/package.json

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,21 @@
2929
"access": "public"
3030
},
3131
"scripts": {
32-
"build": "gulp resources-to-lib && tsc && webpack",
33-
"build:lib": "tsc",
32+
"build": "gulp resources-to-lib && tsc && cross-env BUILD_LIB=true vite build",
33+
"build:lib": "cross-env BUILD_LIB=true vite build",
34+
"build:types": "tsc",
3435
"build:prod": "gulp resources-to-lib && tsc && npm run clean && npm run build:lib",
3536
"build:tsc:watch:res": "gulp resources-to-lib-watch",
3637
"build:tsc:watch:tsc": "tsc --watch",
3738
"build:webpack": "cross-env BUILD_APP=true webpack-cli build",
39+
"build:vite": "vite build",
3840
"clean": "rimraf node_modules lib dist build tsconfig.tsbuildinfo",
3941
"clean:all": "npm run clean:lib && npm run clean:labextension && npm run clean:lintcache",
4042
"clean:labextension": "rimraf datalayer/labextension",
4143
"clean:lib": "rimraf lib tsconfig.tsbuildinfo",
4244
"clean:lintcache": "rimraf .eslintcache .stylelintcache",
43-
"dev": "run-p -c 'start:*'",
45+
"dev": "vite",
46+
"dev:webpack": "run-p -c 'start:*'",
4447
"eslint": "npm eslint:check --fix",
4548
"eslint:check": "eslint . --cache --ext .ts,.tsx",
4649
"example": "run-p -c 'start:*'",
@@ -51,10 +54,12 @@
5154
"prettier": "npm prettier:base --write --list-different",
5255
"prettier:base": "prettier \"**/*{.ts,.tsx,.js,.jsx,.css,.json,.md}\"",
5356
"prettier:check": "npm prettier:base --check",
54-
"start": "run-p -c 'start:*'",
57+
"preview": "vite preview",
58+
"start": "vite",
5559
"start:webpack": "webpack serve",
56-
"start-noconfig": "cross-env NO_CONFIG=true webpack serve",
57-
"start-local": "run-p -c 'start-local:*'",
60+
"start-noconfig": "cross-env NO_CONFIG=true vite",
61+
"start-noconfig:webpack": "cross-env NO_CONFIG=true webpack serve",
62+
"start-local": "cross-env LOCAL_JUPYTER_SERVER=true vite",
5863
"start-local:webpack": "cross-env LOCAL_JUPYTER_SERVER=true webpack serve",
5964
"start-local:jupyter-server": "cd ./../.. && npm run jupyter:server",
6065
"stylelint": "npm stylelint:check --fix",
@@ -237,7 +242,11 @@
237242
"webpack": "^5.74.0",
238243
"webpack-cli": "^5.1.4",
239244
"webpack-dev-server": "^4.9.3",
240-
"whatwg-fetch": "^3.6.2"
245+
"whatwg-fetch": "^3.6.2",
246+
"vite": "^5.4.0",
247+
"@vitejs/plugin-react": "^4.6.0",
248+
"vite-plugin-treat-umd-as-commonjs": "^0.1.4",
249+
"buffer": "^6.0.3"
241250
},
242251
"eslintIgnore": [
243252
"node_modules",

packages/react/vite.config.ts

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
* Copyright (c) 2021-2023 Datalayer, Inc.
3+
*
4+
* MIT License
5+
*/
6+
7+
import { defineConfig } from 'vite';
8+
import react from '@vitejs/plugin-react';
9+
import { treatAsCommonjs } from 'vite-plugin-treat-umd-as-commonjs';
10+
import * as path from 'node:path';
11+
import { fileURLToPath } from 'node:url';
12+
13+
const __filename = fileURLToPath(import.meta.url);
14+
const __dirname = path.dirname(__filename);
15+
16+
// Entry points for examples (dev mode)
17+
const ENTRY_POINTS: Record<string, string> = {
18+
app: './src/app/App.tsx',
19+
cell: './src/examples/Cell.tsx',
20+
console: './src/examples/Console.tsx',
21+
filebrowser: './src/examples/FileBrowser.tsx',
22+
notebook: './src/examples/Notebook.tsx',
23+
notebookthemecolormode: './src/examples/NotebookThemeColormode.tsx',
24+
terminal: './src/examples/Terminal.tsx',
25+
viewer: './src/examples/Viewer.tsx',
26+
};
27+
28+
// Get current entry from environment or default
29+
const CURRENT_ENTRY = process.env.VITE_ENTRY || 'notebookthemecolormode';
30+
31+
const IS_PRODUCTION = process.env.NODE_ENV === 'production';
32+
const IS_LOCAL_JUPYTER_SERVER = process.env.LOCAL_JUPYTER_SERVER === 'true';
33+
const IS_NO_CONFIG = process.env.NO_CONFIG === 'true';
34+
const BUILD_LIB = process.env.BUILD_LIB === 'true';
35+
36+
export default defineConfig(({ mode, command }) => {
37+
const isServe = command === 'serve';
38+
const isBuild = command === 'build';
39+
40+
// Library build configuration
41+
if (isBuild && BUILD_LIB) {
42+
return {
43+
build: {
44+
lib: {
45+
entry: path.resolve(__dirname, 'src/index.ts'),
46+
name: 'JupyterReact',
47+
formats: ['es', 'cjs'],
48+
fileName: format => `index.${format === 'es' ? 'js' : 'cjs'}`,
49+
},
50+
outDir: 'lib',
51+
sourcemap: true,
52+
rollupOptions: {
53+
external: [
54+
'react',
55+
'react-dom',
56+
'react/jsx-runtime',
57+
/^@jupyterlab\/.*/,
58+
/^@lumino\/.*/,
59+
/^@jupyter\/.*/,
60+
/^@jupyter-widgets\/.*/,
61+
/^@jupyterlite\/.*/,
62+
],
63+
output: {
64+
preserveModules: true,
65+
preserveModulesRoot: 'src',
66+
assetFileNames: assetInfo => {
67+
if (assetInfo.name?.endsWith('.css')) {
68+
return '[name][extname]';
69+
}
70+
return 'assets/[name]-[hash][extname]';
71+
},
72+
},
73+
},
74+
},
75+
plugins: [react(), treatAsCommonjs()],
76+
};
77+
}
78+
79+
// Development server and example build configuration
80+
return {
81+
root: __dirname,
82+
server: {
83+
port: 3208,
84+
host: true,
85+
hmr: {
86+
overlay: false,
87+
},
88+
proxy: IS_LOCAL_JUPYTER_SERVER
89+
? {
90+
'/api': {
91+
target: 'http://localhost:8686',
92+
ws: true,
93+
changeOrigin: true,
94+
},
95+
'/terminals': {
96+
target: 'http://localhost:8686',
97+
ws: true,
98+
changeOrigin: true,
99+
},
100+
}
101+
: undefined,
102+
},
103+
plugins: [
104+
react(),
105+
treatAsCommonjs(),
106+
{
107+
name: 'raw-css-as-string',
108+
enforce: 'pre',
109+
async resolveId(source, importer) {
110+
if (source.endsWith('.raw.css') && !source.includes('?raw')) {
111+
const resolved = await this.resolve(source + '?raw', importer, {
112+
skipSelf: true,
113+
});
114+
if (resolved) return resolved.id;
115+
return null;
116+
}
117+
return null;
118+
},
119+
},
120+
{
121+
name: 'fix-text-query',
122+
enforce: 'pre',
123+
async resolveId(source, importer) {
124+
if (source.includes('?text')) {
125+
const fixed = source.replace('?text', '?raw');
126+
const resolved = await this.resolve(fixed, importer, {
127+
skipSelf: true,
128+
});
129+
if (resolved) {
130+
return resolved.id;
131+
}
132+
return fixed;
133+
}
134+
return null;
135+
},
136+
},
137+
{
138+
name: 'handle-theme-css',
139+
enforce: 'pre',
140+
transform(code, id) {
141+
if (id.includes('style/theme.css')) {
142+
return {
143+
code: `export default ${JSON.stringify(code)};`,
144+
map: null,
145+
};
146+
}
147+
},
148+
},
149+
{
150+
name: 'copy-assets',
151+
generateBundle(options, bundle) {
152+
// Copy pypi and schema files
153+
for (const [fileName, source] of Object.entries(bundle)) {
154+
if (fileName.includes('pypi/') || fileName.includes('schema/')) {
155+
// These will be handled by rollup asset configuration
156+
}
157+
}
158+
},
159+
},
160+
],
161+
assetsInclude: ['**/*.whl', '**/*.raw.css', '**/*.ipynb', '**/*.json'],
162+
resolve: {
163+
alias: [
164+
{
165+
find: /^~(.*)$/,
166+
replacement: '$1',
167+
},
168+
{
169+
find: 'stream',
170+
replacement: 'stream-browserify',
171+
},
172+
],
173+
},
174+
define: {
175+
global: 'globalThis',
176+
'process.env': process.env,
177+
__webpack_public_path__: '""',
178+
},
179+
worker: {
180+
format: 'es',
181+
},
182+
optimizeDeps: {
183+
include: ['react', 'react-dom', '@primer/react', 'styled-components'],
184+
exclude: [
185+
'@jupyterlab/application',
186+
'@jupyterlab/apputils',
187+
'@jupyterlite/server',
188+
'@jupyterlite/pyodide-kernel',
189+
],
190+
esbuildOptions: {
191+
loader: {
192+
'.whl': 'text',
193+
},
194+
},
195+
},
196+
build: {
197+
outDir: 'dist',
198+
rollupOptions: {
199+
input: isServe
200+
? undefined
201+
: {
202+
main: path.resolve(__dirname, 'index.html'),
203+
...Object.fromEntries(
204+
Object.entries(ENTRY_POINTS).map(([name, entry]) => [
205+
name,
206+
path.resolve(__dirname, entry),
207+
])
208+
),
209+
},
210+
output: {
211+
assetFileNames: assetInfo => {
212+
if (assetInfo.name && /pypi\//.test(assetInfo.name)) {
213+
return 'pypi/[name][extname]';
214+
}
215+
if (assetInfo.name && /schema\//.test(assetInfo.name)) {
216+
return 'schema/[name][extname]';
217+
}
218+
return 'assets/[name]-[hash][extname]';
219+
},
220+
chunkFileNames: 'chunks/[name]-[hash].js',
221+
entryFileNames: '[name].js',
222+
},
223+
},
224+
},
225+
};
226+
});

0 commit comments

Comments
 (0)