isolet-widget-isolation

安装量: 332
排名: #9760

安装

npx skills add https://github.com/aradotso/trending-skills --skill isolet-widget-isolation

isolet Widget Isolation Skill by ara.so — Daily 2026 Skills collection. isolet-js packages any component (React, Solid, Svelte, vanilla JS, etc.) into a self-contained, isolated widget. Widgets render inside shadow DOM by default, so styles are fully scoped. Output formats include IIFE (script tag), ESM, and CommonJS. Install npm install isolet-js Core API: createIsolet import { createIsolet } from "isolet-js" ; const widget = createIsolet ( { name : "my-widget" , // required: unique identifier mount : myMountFn , // required: (container, props) => cleanup | void css : h1 { color: red; } , // optional: scoped CSS isolation : "shadow-dom" , // "shadow-dom" | "scoped" | "none" shadowMode : "open" , // "open" | "closed" hostAttributes : { "data-widget" : "true" } , zIndex : 9999 , } ) ; widget . mount ( document . body , { title : "Hello" } ) ; // mount into target widget . update ( { title : "Updated" } ) ; // update props widget . unmount ( ) ; // tear down // Instance properties widget . container ; // HTMLElement — the render container widget . shadowRoot ; // ShadowRoot | null widget . mounted ; // boolean Framework Adapters React import { createIsolet } from "isolet-js" ; import { react } from "isolet-js/react" ; function Greeting ( { name } : { name : string } ) { return < h1

Hello, { name } ! </ h1

; } const widget = createIsolet ( { name : "greeting" , mount : react ( Greeting ) , css : h1 { color: tomato; font-family: sans-serif; } , } ) ; widget . mount ( document . body , { name : "World" } ) ; widget . update ( { name : "Isolet" } ) ; widget . unmount ( ) ; Vanilla JS import { createIsolet } from "isolet-js" ; import { vanilla } from "isolet-js/vanilla" ; const widget = createIsolet ( { name : "counter" , mount : vanilla ( ( container , props ) => { let count = props . initial ?? 0 ; const btn = document . createElement ( "button" ) ; btn . textContent = Count: ${ count } ; btn . onclick = ( ) => { btn . textContent = Count: ${ ++ count } ; } ; container . appendChild ( btn ) ; // Return cleanup function return ( ) => container . removeChild ( btn ) ; } ) , } ) ; widget . mount ( document . getElementById ( "app" ) , { initial : 5 } ) ; Solid import { createIsolet } from "isolet-js" ; import { render } from "solid-js/web" ; import App from "./App" ; const widget = createIsolet ( { name : "solid-widget" , mount ( container , props ) { const dispose = render ( ( ) => < App { ... props } /> , container ) ; return dispose ; // dispose is the cleanup function } , } ) ; Svelte import { createIsolet } from "isolet-js" ; import App from "./App.svelte" ; const widget = createIsolet ( { name : "svelte-widget" , mount ( container , props ) { const app = new App ( { target : container , props } ) ; return ( ) => app . $destroy ( ) ; } , } ) ; Isolation Modes // Full CSS isolation — shadow DOM (default) createIsolet ( { name : "w" , mount : fn , isolation : "shadow-dom" } ) ; // Scoped — plain div wrapper, styles injected globally createIsolet ( { name : "w" , mount : fn , isolation : "scoped" } ) ; // No isolation — mounts directly into target element createIsolet ( { name : "w" , mount : fn , isolation : "none" } ) ; CLI npx isolet-js init

scaffold isolet.config.ts

npx isolet-js build

bundle widget(s) from config

npx isolet-js build --watch

rebuild on file changes

npx isolet-js build --minify

minified production build

Config File // isolet.config.ts import { defineConfig } from "isolet-js" ; export default defineConfig ( { name : "my-widget" , entry : "./src/index.ts" , styles : "./src/widget.css" , // CSS to inline; url() assets become data URIs format : [ "iife" , "esm" ] , // output formats outDir : "./dist" , // default: "dist" globalName : "MyWidget" , // global name for IIFE builds external : [ "react" ] , // don't bundle these deps dts : true , // emit .d.ts files minify : true , // minify output platform : "browser" , // target platform } ) ; Multiple Widgets export default defineConfig ( [ { name : "widget-a" , entry : "./src/a.ts" , styles : "./src/a.css" } , { name : "widget-b" , entry : "./src/b.ts" , format : [ "esm" ] } , ] ) ; CSS & Asset Handling The build pipeline handles everything automatically: styles in config → CSS is read, url() references (fonts, images) inlined as data URIs, result available as ISOLET_CSS in your entry .css imports → converted to JS string exports (shadow DOM safe) Asset imports ( .png , .woff2 , .mp3 , etc.) → inlined as data URIs styles: "./path.css" in createIsolet → resolved and inlined at build time // Entry file using ISOLET_CSS injected by CLI import { createIsolet } from "isolet-js" ; import { react } from "isolet-js/react" ; import MyComponent from "./MyComponent" ; declare const ISOLET_CSS : string ; export const widget = createIsolet ( { name : "my-widget" , css : ISOLET_CSS , // populated from config.styles at build time mount : react ( MyComponent ) , } ) ; Or reference the CSS path directly (auto-resolved at build time): createIsolet ( { name : "my-widget" , styles : "./widget.css" , // isolet build resolves this mount : react ( MyComponent ) , } ) ; Manual Vite Plugin Setup If using Vite directly instead of the CLI: // vite.config.ts import { defineConfig } from "vite" ; import { cssTextPlugin , inlineAssetsPlugin , autoStylesPlugin , } from "isolet-js/plugins" ; export default defineConfig ( { plugins : [ cssTextPlugin ( ) , inlineAssetsPlugin ( ) , autoStylesPlugin ( ) ] , } ) ; Script Tag (IIFE) Usage < script src = " https://unpkg.com/isolet-js/dist/index.iife.js "

</ script

< script

const { createIsolet } = ISOLET ; const widget = createIsolet ( { name : "inline-widget" , mount ( container , props ) { container . innerHTML = `

Hello, ${props.name ?? "World"}!

; } , css : p { font-family: sans-serif; color: navy; } ` , } ) ; widget . mount ( document . body , { name : "Visitor" } ) ; </ script

For a bundled custom widget via IIFE: // isolet.config.ts export default defineConfig ( { name : "my-widget" , entry : "./src/index.ts" , format : [ "iife" ] , globalName : "MyWidget" , minify : true , } ) ;

< script src = " ./dist/my-widget.iife.js "

</ script

< script

MyWidget . widget . mount ( document . getElementById ( "root" ) , { title : "Hi" } ) ; </ script

Common Patterns Lazy-mount on demand const widget = createIsolet ( { name : "chat" , mount : react ( ChatApp ) , css : styles } ) ; document . getElementById ( "open-chat" ) . addEventListener ( "click" , ( ) => { if ( ! widget . mounted ) { widget . mount ( document . body , { userId : currentUserId } ) ; } } ) ; document . getElementById ( "close-chat" ) . addEventListener ( "click" , ( ) => { widget . unmount ( ) ; } ) ; z-index overlay widget const modal = createIsolet ( { name : "modal" , mount : react ( ModalComponent ) , css : modalStyles , zIndex : 10000 , hostAttributes : { role : "dialog" , "aria-modal" : "true" } , } ) ; Reactive props updates const widget = createIsolet ( { name : "status" , mount : react ( StatusBar ) , css } ) ; widget . mount ( document . body , { status : "idle" } ) ; // Later, update without remounting: widget . update ( { status : "loading" } ) ; widget . update ( { status : "done" } ) ; Troubleshooting Styles leaking in or out Use isolation: "shadow-dom" (default). Verify your css option or styles path is correctly set — without CSS in the shadow root, the host page styles will not apply inside. ISOLET_CSS is undefined This variable is only injected by the isolet build CLI when styles is set in config. For manual Vite builds, add autoStylesPlugin() to your Vite config. Component not rendering Ensure the mount function appends to container , not to document.body . In shadow DOM mode, the container is inside the shadow root. Cleanup not running Return a cleanup function from your mount callback. Without it, widget.unmount() cannot tear down framework internals (timers, subscriptions, etc.). IIFE global not found Check globalName in config matches what you reference in HTML. The runtime core exposes globalThis.ISOLET when no globalName is set. External deps not found at runtime If you set external: ["react"] , the host page must provide React globally or via module federation before your widget script loads.

返回排行榜