mirror of https://github.com/alibaba/ice.git
				
				
				
			feat: support canvans 2d for cache (#6367)
* feat: support canvans 2d for cache * fix: image src hydrate * chore: update lock * fix: img not match when ssr * fix: canvas dispalay * chore: remove runtime * chore: add event for taobao * chore: add window.WindVane * chore: add declare * chore: add changeset * feat: add cacheCanvasToStorage to ref * chore: modify function * feat: add @ice/cache-canvas * feat: replace mounted * chore: add dependence to useCallback * chore: add try to Storage * chore: import CacheCanvas from ice in example * chore: add changeset * chore: add conment * feat: add rendered * feat: add getSnapshot * feat: modify * chore: add import meta * chore: add CacheCanvasProps
This commit is contained in:
		
							parent
							
								
									cf8a78e379
								
							
						
					
					
						commit
						018238f904
					
				|  | @ -0,0 +1,5 @@ | |||
| --- | ||||
| '@ice/cache-canvas': patch | ||||
| --- | ||||
| 
 | ||||
| feat: support cache of 2d cavans | ||||
|  | @ -0,0 +1,5 @@ | |||
| --- | ||||
| '@ice/plugin-canvas': patch | ||||
| --- | ||||
| 
 | ||||
| feat: support cache of 2d cavans | ||||
|  | @ -0,0 +1,2 @@ | |||
| defaults | ||||
| ios_saf 9 | ||||
|  | @ -0,0 +1,10 @@ | |||
| import { defineConfig } from '@ice/app'; | ||||
| import canvasPlugin from '@ice/plugin-canvas'; | ||||
| 
 | ||||
| export default defineConfig(() => ({ | ||||
|   plugins: [ | ||||
|     canvasPlugin(), | ||||
|   ], | ||||
|   ssr: true, | ||||
|   ssg: false, | ||||
| })); | ||||
|  | @ -0,0 +1,25 @@ | |||
| { | ||||
|   "name": "@examples/canvas-project", | ||||
|   "version": "1.0.0", | ||||
|   "private": true, | ||||
|   "scripts": { | ||||
|     "start": "ice start", | ||||
|     "build": "ice build" | ||||
|   }, | ||||
|   "description": "", | ||||
|   "author": "", | ||||
|   "license": "MIT", | ||||
|   "dependencies": { | ||||
|     "@ice/app": "workspace:*", | ||||
|     "@ice/plugin-canvas": "workspace:*", | ||||
|     "@ice/runtime": "workspace:*", | ||||
|     "react": "^18.0.0", | ||||
|     "react-dom": "^18.0.0", | ||||
|     "@ice/cache-canvas": "workspace:*" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/react": "^18.0.0", | ||||
|     "@types/react-dom": "^18.0.0", | ||||
|     "webpack": "^5.86.0" | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| import { defineAppConfig } from 'ice'; | ||||
| 
 | ||||
| export default defineAppConfig(() => ({})); | ||||
|  | @ -0,0 +1,7 @@ | |||
| export default function Bar() { | ||||
|   return ( | ||||
|     <div> | ||||
|       bar | ||||
|     </div> | ||||
|   ); | ||||
| } | ||||
|  | @ -0,0 +1,22 @@ | |||
| import { Meta, Title, Links, Main, Scripts } from 'ice'; | ||||
| 
 | ||||
| function Document() { | ||||
|   return ( | ||||
|     <html> | ||||
|       <head> | ||||
|         <meta charSet="utf-8" /> | ||||
|         <meta name="description" content="ICE Demo" /> | ||||
|         <meta name="viewport" content="width=device-width, initial-scale=1" /> | ||||
|         <Meta /> | ||||
|         <Title /> | ||||
|         <Links /> | ||||
|       </head> | ||||
|       <body> | ||||
|         <Main /> | ||||
|         <Scripts /> | ||||
|       </body> | ||||
|     </html> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export default Document; | ||||
|  | @ -0,0 +1,65 @@ | |||
| import { definePageConfig, CacheCanvas } from 'ice'; | ||||
| import { useRef } from 'react'; | ||||
| import styles from './index.module.css'; | ||||
| 
 | ||||
| export type RefCacheCanvas = { | ||||
|   cacheCanvasToStorage: () => void; | ||||
| }; | ||||
| 
 | ||||
| const GAME_CANVAS_ID = 'canvas-id'; | ||||
| 
 | ||||
| export default function Home() { | ||||
|   const childRef = useRef<RefCacheCanvas>(); | ||||
|   const initFunc = () => { | ||||
|     return new Promise((resolve) => { | ||||
|       const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement; | ||||
|       if (canvas && typeof canvas.getContext === 'function') { | ||||
|         let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d'); | ||||
| 
 | ||||
|         ctx?.fillRect(25, 25, 100, 100); | ||||
|         ctx?.clearRect(45, 45, 60, 60); | ||||
|         ctx?.strokeRect(50, 50, 50, 50); | ||||
|       } | ||||
| 
 | ||||
|       setTimeout(() => { | ||||
|         console.log('canvas paint ready!'); | ||||
|         resolve(true); | ||||
|       }, 5000); | ||||
|     }); | ||||
|   }; | ||||
|   return ( | ||||
|     <> | ||||
|       <h2 className={styles.title}>Home Page</h2> | ||||
|       <CacheCanvas | ||||
|         ref={childRef} | ||||
|         id={GAME_CANVAS_ID} | ||||
|         init={initFunc} | ||||
|         fallback={() => <div>fallback</div>} | ||||
|       /> | ||||
|       <button | ||||
|         style={{ display: 'block' }} | ||||
|         onClick={() => { | ||||
|           console.log('active cache!'); | ||||
|           childRef.current?.cacheCanvasToStorage(); | ||||
|         }} | ||||
|       >cache canvas</button> | ||||
|     </> | ||||
|   ); | ||||
| } | ||||
| 
 | ||||
| export const pageConfig = definePageConfig(() => { | ||||
|   return { | ||||
|     title: 'Home', | ||||
|     meta: [ | ||||
|       { | ||||
|         name: 'theme-color', | ||||
|         content: '#000', | ||||
|       }, | ||||
|       { | ||||
|         name: 'title-color', | ||||
|         content: '#f00', | ||||
|       }, | ||||
|     ], | ||||
|     auth: ['admin'], | ||||
|   }; | ||||
| }); | ||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 35 KiB | 
|  | @ -0,0 +1,3 @@ | |||
| .title { | ||||
|   color: red; | ||||
| } | ||||
|  | @ -0,0 +1,3 @@ | |||
| export interface AppData { | ||||
|   title: string; | ||||
| } | ||||
|  | @ -0,0 +1 @@ | |||
| /// <reference types="@ice/app/types" />
 | ||||
|  | @ -0,0 +1,32 @@ | |||
| { | ||||
|   "compileOnSave": false, | ||||
|   "buildOnSave": false, | ||||
|   "compilerOptions": { | ||||
|     "baseUrl": ".", | ||||
|     "outDir": "build", | ||||
|     "module": "esnext", | ||||
|     "target": "es6", | ||||
|     "jsx": "react-jsx", | ||||
|     "moduleResolution": "node", | ||||
|     "allowSyntheticDefaultImports": true, | ||||
|     "lib": ["es6", "dom"], | ||||
|     "sourceMap": true, | ||||
|     "allowJs": true, | ||||
|     "rootDir": "./", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noImplicitThis": true, | ||||
|     "noImplicitAny": false, | ||||
|     "importHelpers": true, | ||||
|     "strictNullChecks": true, | ||||
|     "suppressImplicitAnyIndexErrors": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "skipLibCheck": true, | ||||
|     "paths": { | ||||
|       "@/*": ["./src/*"], | ||||
|       "ice": [".ice"] | ||||
|     } | ||||
|   }, | ||||
|   "include": ["src", ".ice", "ice.config.*"], | ||||
|   "exclude": ["build", "public"] | ||||
| } | ||||
|  | @ -0,0 +1,46 @@ | |||
| # @ice/cache-canvas | ||||
| 
 | ||||
| React component for supporting canvas for cache. | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| ```bash | ||||
| npm i @ice/cache-canvas -S | ||||
| ``` | ||||
| 
 | ||||
| ```jsx | ||||
| import MainGame from './game'; // eva.js 的封装 | ||||
| 
 | ||||
| const GAME_CANVAS = 'game-canvas'; | ||||
| 
 | ||||
| export default (props) => { | ||||
|   useEffect(() => { | ||||
|     const gameEl = document.getElementById(GAME_CANVAS); | ||||
|     new MainGame(gameEl, getGameHeight()); | ||||
|   }, []); | ||||
| 
 | ||||
|   const init = () => { | ||||
|      return new Promise((resolve) => { | ||||
|       const canvas: HTMLCanvasElement | null = document.getElementById(GAME_CANVAS_ID) as HTMLCanvasElement; | ||||
|       if (canvas && typeof canvas.getContext === 'function') { | ||||
|         let ctx: CanvasRenderingContext2D | null = canvas.getContext('2d'); | ||||
| 
 | ||||
|         ctx?.fillRect(25, 25, 100, 100); | ||||
|         ctx?.clearRect(45, 45, 60, 60); | ||||
|         ctx?.strokeRect(50, 50, 50, 50); | ||||
|       } | ||||
| 
 | ||||
|       setTimeout(() => { | ||||
|         console.log('canvas paint ready!'); | ||||
|         resolve(true); | ||||
|       }, 5000); | ||||
|     }); | ||||
|   } | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|        <CanvasCache id={GAME_CANVAS} useCache={false} init={init} /> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| ``` | ||||
|  | @ -0,0 +1,29 @@ | |||
| { | ||||
|   "name": "@ice/cache-canvas", | ||||
|   "version": "0.0.8", | ||||
|   "description": "", | ||||
|   "main": "./esm/index.js", | ||||
|   "types": "./esm/index.d.ts", | ||||
|   "scripts": { | ||||
|     "watch": "tsc -w", | ||||
|     "build": "tsc", | ||||
|     "prepublishOnly": "npm run build" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "author": "", | ||||
|   "license": "ISC", | ||||
|   "devDependencies": { | ||||
|     "react": "^18.0.0", | ||||
|     "react-dom": "^18.0.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "universal-env": "^3.3.3" | ||||
|   }, | ||||
|   "peerDependencies": { | ||||
|     "react": "^18", | ||||
|     "react-dom": "^18" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,161 @@ | |||
| import { useEffect, useState, useImperativeHandle, forwardRef, useCallback } from 'react'; | ||||
| import type { | ||||
|   HTMLAttributes, | ||||
|   ReactElement, | ||||
| } from 'react'; | ||||
| import * as React from 'react'; | ||||
| import { isNode } from 'universal-env'; | ||||
| import { Storage } from './storage'; | ||||
| 
 | ||||
| declare global { | ||||
|   interface ImportMeta { | ||||
|     // The build target for ice.js
 | ||||
|     // Usually `web` or `node` or `weex`
 | ||||
|     target: string; | ||||
|     // The renderer for ice.js
 | ||||
|     renderer: 'client' | 'server'; | ||||
|     // ice.js defined env variables
 | ||||
|     env: Record<string, string>; | ||||
|   } | ||||
| 
 | ||||
|   interface Window { | ||||
|     WindVane: { | ||||
|       call: Function; | ||||
|     }; | ||||
|     _windvane_backControl: Function | null; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export type RefCacheCanvas = { | ||||
|   // Call the API to store the canvas in storage.
 | ||||
|   cacheCanvasToStorage: () => void; | ||||
| }; | ||||
| 
 | ||||
| export type CacheCanvasProps = { | ||||
|   id: string; | ||||
|   init: () => Promise<any>; | ||||
|   useCache?: Boolean; | ||||
|   getSnapshot?: () => String; | ||||
|   fallback?: ReactElement; | ||||
|   style?: HTMLAttributes; | ||||
|   className?: HTMLAttributes; | ||||
| }; | ||||
| 
 | ||||
| export const CacheCanvas = forwardRef((props: CacheCanvasProps, ref) => { | ||||
|   const { | ||||
|     id, | ||||
|     init, | ||||
|     useCache = true, | ||||
|     getSnapshot, | ||||
|     fallback, | ||||
|     style, | ||||
|     className, | ||||
|     ...rest | ||||
|   } = props; | ||||
| 
 | ||||
|   const [renderedCanvas, setRenderedCanvas] = useState(!useCache); | ||||
|   const [mounted, setMounted] = useState(false); | ||||
| 
 | ||||
|   const cacheKey = `cache-canvas-${id}`; | ||||
| 
 | ||||
|   const cacheCanvasFunc = useCallback(() => { | ||||
|     // Cache base64 string of canvas.
 | ||||
|     const canvas: HTMLCanvasElement | null = document.getElementById(id) as HTMLCanvasElement; | ||||
|     let strBase64; | ||||
|     if (typeof getSnapshot === 'function') { | ||||
|       strBase64 = getSnapshot(); | ||||
|     } else { | ||||
|       strBase64 = canvas.toDataURL(); | ||||
|     } | ||||
|     // Cache base64 string when canvas rendered.
 | ||||
|     if (renderedCanvas && strBase64) { | ||||
|       Storage.setItem(cacheKey, strBase64); | ||||
|     } | ||||
|   }, [id, renderedCanvas, cacheKey, getSnapshot]); | ||||
| 
 | ||||
|   useImperativeHandle(ref, () => ({ | ||||
|     cacheCanvasToStorage: cacheCanvasFunc, | ||||
|   })); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     setMounted(true); | ||||
|   }, []); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (window.WindVane) { | ||||
|       window.WindVane.call('WebAppInterface', 'enableHookNativeBack', {}); | ||||
|       window._windvane_backControl = () => { | ||||
|         cacheCanvasFunc(); | ||||
|         // Windvane must return a string value of true for it to work properly.
 | ||||
|         return 'true'; | ||||
|       }; | ||||
|     } | ||||
|     document.addEventListener('wvBackClickEvent', cacheCanvasFunc, false); | ||||
|     window.addEventListener('beforeunload', cacheCanvasFunc); | ||||
| 
 | ||||
|     return () => { | ||||
|       window.removeEventListener('beforeunload', cacheCanvasFunc); | ||||
|       window.removeEventListener('wvBackClickEvent', cacheCanvasFunc); | ||||
|       if (window._windvane_backControl) { | ||||
|         window._windvane_backControl = null; | ||||
|       } | ||||
|     }; | ||||
|   }, [cacheCanvasFunc]); | ||||
| 
 | ||||
|   useEffect(() => { | ||||
|     if (mounted && typeof init === 'function') { | ||||
|       const res = init(); | ||||
|       if (res instanceof Promise) { | ||||
|         res.then(() => { | ||||
|           setRenderedCanvas(true); | ||||
|         }); | ||||
|       } | ||||
|     } | ||||
|   }, [mounted, init]); | ||||
| 
 | ||||
|   return ( | ||||
|     <> | ||||
|       <canvas | ||||
|         {...rest} | ||||
|         className={className} | ||||
|         style={renderedCanvas ? style : { ...style, display: 'none' }} | ||||
|         id={id} | ||||
|       /> | ||||
|       { | ||||
|         !renderedCanvas && (<> | ||||
|           <img | ||||
|             className={className} | ||||
|             style={style} | ||||
|             src={Storage.getItem(cacheKey) || ''} | ||||
|             id={`canvas-img-${id}`} | ||||
|           /> | ||||
|           { | ||||
|             (typeof fallback === 'function') && (<div | ||||
|               id={`fallback-${id}`} | ||||
|               style={isNode || Storage.getItem(cacheKey) ? { display: 'none' } : { display: 'block' }} | ||||
|             > | ||||
|               { | ||||
|                 fallback() | ||||
|               } | ||||
|             </div>) | ||||
|           } | ||||
|           <script | ||||
|             dangerouslySetInnerHTML={{ | ||||
|               __html: ` | ||||
|                   const base64Data = localStorage.getItem('${cacheKey}'); | ||||
|                   const fallback = document.getElementById('fallback-${id}'); | ||||
|                   if (base64Data) { | ||||
|                     const img = document.getElementById('canvas-img-${id}'); | ||||
|                     img && (img.src = base64Data); | ||||
|                     fallback && (fallback.style.display = 'none'); | ||||
|                   } else { | ||||
|                     fallback && (fallback.style.display = 'block'); | ||||
|                   } | ||||
|                 `,
 | ||||
|               }} | ||||
|           /> | ||||
|         </>) | ||||
|       } | ||||
|     </> | ||||
|   ); | ||||
| }); | ||||
|  | @ -0,0 +1,26 @@ | |||
| const cache = {}; | ||||
| 
 | ||||
| export const Storage = { | ||||
|   setItem: (key, value) => { | ||||
|     try { | ||||
|       if (typeof window === 'object' && window.localStorage) { | ||||
|         return localStorage.setItem(key, value); | ||||
|       } | ||||
| 
 | ||||
|       return (cache[key] = value); | ||||
|     } catch (e) { | ||||
|       console.error('Storage setItem error:', e); | ||||
|     } | ||||
|   }, | ||||
|   getItem: (key) => { | ||||
|     try { | ||||
|       if (typeof window === 'object' && window.localStorage) { | ||||
|         return localStorage.getItem(key); | ||||
|       } | ||||
| 
 | ||||
|       return cache[key] || ''; | ||||
|     } catch (e) { | ||||
|       console.error('Storage getItem error:', e); | ||||
|     } | ||||
|   }, | ||||
| }; | ||||
|  | @ -0,0 +1,3 @@ | |||
| export function isFunction(obj: any): obj is Function { | ||||
|   return typeof obj === 'function'; | ||||
| } | ||||
|  | @ -0,0 +1,12 @@ | |||
| { | ||||
|   "extends": "../../tsconfig.base.json", | ||||
|   "compilerOptions": { | ||||
|     "baseUrl": "./", | ||||
|     "rootDir": "src", | ||||
|     "outDir": "esm" | ||||
|   }, | ||||
|   "allowJs": true, | ||||
|   "include": [ | ||||
|     "src" | ||||
|   ] | ||||
| } | ||||
|  | @ -0,0 +1,16 @@ | |||
| # @ice/plugin-canvas | ||||
| 
 | ||||
| An ice.js plugin for canvas projects. | ||||
| 
 | ||||
| ## Usage | ||||
| 
 | ||||
| Add plugin in `ice.config.mts`: | ||||
| 
 | ||||
| ```js | ||||
| import { defineConfig } from 'ice'; | ||||
| import canvasPlugin from '@ice/plugin-canvas'; | ||||
| 
 | ||||
| export default defineConfig(() => ({ | ||||
|   plugins: [canvasPlugin({ /* options */ })], | ||||
| })); | ||||
| ```   | ||||
|  | @ -0,0 +1,49 @@ | |||
| { | ||||
|   "name": "@ice/plugin-canvas", | ||||
|   "version": "0.0.2", | ||||
|   "description": "Provide canvas render support for ice.js", | ||||
|   "license": "MIT", | ||||
|   "type": "module", | ||||
|   "exports": { | ||||
|     ".": { | ||||
|       "import": "./esm/index.js", | ||||
|       "default": "./esm/index.js" | ||||
|     }, | ||||
|     "./CacheCanvas": { | ||||
|       "types": "./esm/CacheCanvas.d.ts", | ||||
|       "import": "./esm/CacheCanvas.js", | ||||
|       "default": "./esm/CacheCanvas.js" | ||||
|     }, | ||||
|     "./runtime": { | ||||
|       "types": "./esm/runtime.d.ts", | ||||
|       "import": "./esm/runtime.js", | ||||
|       "default": "./esm/runtime.js" | ||||
|     }, | ||||
|     "./*": "./*" | ||||
|   }, | ||||
|   "main": "./esm/index.js", | ||||
|   "types": "./esm/index.d.ts", | ||||
|   "files": [ | ||||
|     "esm", | ||||
|     "!esm/**/*.map" | ||||
|   ], | ||||
|   "dependencies": { | ||||
|     "@ice/cache-canvas": "workspace:*", | ||||
|     "@ice/runtime": "^1.2.4" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@ice/app": "^3.2.1", | ||||
|     "webpack": "^5.86.0" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "http", | ||||
|     "url": "https://github.com/alibaba/ice/tree/master/packages/plugin-canvas" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "watch": "tsc -w", | ||||
|     "build": "tsc" | ||||
|   }, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   } | ||||
| } | ||||
|  | @ -0,0 +1,15 @@ | |||
| import type { Plugin } from '@ice/app/types'; | ||||
| 
 | ||||
| const PLUGIN_NAME = '@ice/plugin-canvas'; | ||||
| 
 | ||||
| const plugin: Plugin = () => ({ | ||||
|   name: PLUGIN_NAME, | ||||
|   setup: async ({ generator }) => { | ||||
|     generator.addExport({ | ||||
|       source: '@ice/cache-canvas', | ||||
|       specifier: ['CacheCanvas'], | ||||
|     }); | ||||
|   }, | ||||
| }); | ||||
| 
 | ||||
| export default plugin; | ||||
|  | @ -0,0 +1,10 @@ | |||
| { | ||||
|   "extends": "../../tsconfig.base.json", | ||||
|   "compilerOptions": { | ||||
|     "baseUrl": "./", | ||||
|     "rootDir": "src", | ||||
|     "outDir": "esm", | ||||
|     "jsx": "react" | ||||
|   }, | ||||
|   "include": ["src"] | ||||
| } | ||||
|  | @ -134,6 +134,29 @@ importers: | |||
|       speed-measure-webpack-plugin: 1.5.0_webpack@5.86.0 | ||||
|       webpack: 5.86.0 | ||||
| 
 | ||||
|   examples/cavans-project: | ||||
|     specifiers: | ||||
|       '@ice/app': workspace:* | ||||
|       '@ice/cache-canvas': workspace:* | ||||
|       '@ice/plugin-canvas': workspace:* | ||||
|       '@ice/runtime': workspace:* | ||||
|       '@types/react': ^18.0.0 | ||||
|       '@types/react-dom': ^18.0.0 | ||||
|       react: ^18.0.0 | ||||
|       react-dom: ^18.0.0 | ||||
|       webpack: ^5.86.0 | ||||
|     dependencies: | ||||
|       '@ice/app': link:../../packages/ice | ||||
|       '@ice/cache-canvas': link:../../packages/cache-canvas | ||||
|       '@ice/plugin-canvas': link:../../packages/plugin-cavans | ||||
|       '@ice/runtime': link:../../packages/runtime | ||||
|       react: 18.2.0 | ||||
|       react-dom: 18.2.0_react@18.2.0 | ||||
|     devDependencies: | ||||
|       '@types/react': 18.0.34 | ||||
|       '@types/react-dom': 18.0.11 | ||||
|       webpack: 5.86.0 | ||||
| 
 | ||||
|   examples/csr-project: | ||||
|     specifiers: | ||||
|       '@ice/app': workspace:* | ||||
|  | @ -1034,6 +1057,17 @@ importers: | |||
|       webpack-dev-server: 4.15.0_webpack@5.86.0 | ||||
|       ws: 8.12.1 | ||||
| 
 | ||||
|   packages/cache-canvas: | ||||
|     specifiers: | ||||
|       react: ^18.0.0 | ||||
|       react-dom: ^18.0.0 | ||||
|       universal-env: ^3.3.3 | ||||
|     dependencies: | ||||
|       universal-env: 3.3.3 | ||||
|     devDependencies: | ||||
|       react: 18.2.0 | ||||
|       react-dom: 18.2.0_react@18.2.0 | ||||
| 
 | ||||
|   packages/create-ice: | ||||
|     specifiers: | ||||
|       '@iceworks/generate-project': ^2.0.2 | ||||
|  | @ -1238,6 +1272,19 @@ importers: | |||
|       '@types/react-dom': 18.0.11 | ||||
|       regenerator-runtime: 0.13.11 | ||||
| 
 | ||||
|   packages/plugin-cavans: | ||||
|     specifiers: | ||||
|       '@ice/app': ^3.2.1 | ||||
|       '@ice/cache-canvas': workspace:* | ||||
|       '@ice/runtime': ^1.2.4 | ||||
|       webpack: ^5.86.0 | ||||
|     dependencies: | ||||
|       '@ice/cache-canvas': link:../cache-canvas | ||||
|       '@ice/runtime': link:../runtime | ||||
|     devDependencies: | ||||
|       '@ice/app': link:../ice | ||||
|       webpack: 5.86.0 | ||||
| 
 | ||||
|   packages/plugin-css-assets-local: | ||||
|     specifiers: | ||||
|       '@ice/app': ^3.1.2 | ||||
|  | @ -9670,8 +9717,8 @@ packages: | |||
|     engines: {node: '>=10'} | ||||
|     hasBin: true | ||||
|     dependencies: | ||||
|       JSONStream: 1.3.5 | ||||
|       is-text-path: 1.0.1 | ||||
|       JSONStream: 1.3.5 | ||||
|       lodash: 4.17.21 | ||||
|       meow: 8.1.2 | ||||
|       split2: 3.2.2 | ||||
|  | @ -18677,12 +18724,6 @@ packages: | |||
|   /react-dev-utils/12.0.1_y75l3d5in5mgvug53qfq62ncxu: | ||||
|     resolution: {integrity: sha512-84Ivxmr17KjUupyqzFode6xKhjwuEJDROWKJy/BthkL7Wn6NJ8h4WE6k/exAv6ImS+0oZLRRW5j/aINMHyeGeQ==} | ||||
|     engines: {node: '>=14'} | ||||
|     peerDependencies: | ||||
|       typescript: '>=2.7' | ||||
|       webpack: '>=4' | ||||
|     peerDependenciesMeta: | ||||
|       typescript: | ||||
|         optional: true | ||||
|     dependencies: | ||||
|       '@babel/code-frame': 7.18.6 | ||||
|       address: 1.2.2 | ||||
|  | @ -18713,7 +18754,9 @@ packages: | |||
|     transitivePeerDependencies: | ||||
|       - eslint | ||||
|       - supports-color | ||||
|       - typescript | ||||
|       - vue-template-compiler | ||||
|       - webpack | ||||
| 
 | ||||
|   /react-dom/17.0.2_react@17.0.2: | ||||
|     resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue