Go Svelte one component at a time
npm install --save-dev svelte-injector svelte
Then configure your bundler of choice to accept Svelte files.
Create your Svelte App: --> reference
src/svelte/main
import App from './App.svelte';
const svelteEntrypoint = document.createElement('div');
svelteEntrypoint.id = 'svelte-entrypoint';
document.body.prepend(svelteEntrypoint);
// Create Svelte App
new App({
target: svelteEntrypoint
});
Note: Svelte needs to share the DOM with your existing app. It's recommended you don't use document.body
as the App target while you are migrating.
App.svelte
<script>
import { InjectedComponents } from "svelte-injector";
</script>
<InjectedComponents/>
Use svelte-loader
or rollup-plugin-svelte
in your bundler. Make sure you are not excluding /svelte-injector/
as it lives in your /node-modules/
Import the component class into your framework controller, then use create()
.
import Hello from './Hello.svelte';
import { create } from 'svelte-injector';
create(target, Hello, props);
Register component class to use it anywhere.
Import your components somewhere in your bundle (es: create an index.module
file)
import Hello from './Hello.svelte';
import { registerComponent } from 'svelte-injector';
registerComponent('hello', Hello);
// OR for lazy loading dynamic imports
registerComponent('hello', async () => {
return (await import('./Hello.svelte')).default; //The given function will only be called when *hydrate* finds a component with the name "hello"
});
then use this string as the second argument of create()
import { create } from 'svelte-injector';
create(target, 'hello', props);
Place HTML placeholders and then hydrate
them
Use this notation in the template:
<div data-component-name="hello">
<template class="props"">
<!--JSON formatted-->
{"name": "hello"}
</template>
</div>
Then call hydrate()
to update the components tree in Svelte.
import { hydrate } from 'svelte-injector';
hydrate(target);
You can use data-to-render
attribute as an {if}
block in Svelte
<div data-component-name="hello" data-to-render"true">
<template class="props"">
<!--JSON formatted-->
{"name": "hello"}
</template>
</div>
On multi page applications you can create components directly from the source HTML.
If any page of your source contains component markup, just hydrate
the body to render them.
import { hydrate } from 'svelte-injector';
hydrate(document.body);
NOTE: make sure to hydrate the body only after registering your components.
This project was created to easily migrate apps from AngularJs to Svelte, but it is not framework specific.
Svelte components should NOT be aware of the fact that they were used by another framework.
Use the built-in React component.
import { SvelteComponent } from 'svelte-injector/react';
// Using the class
import Component from 'src/Component.svelte';
function YourComponent(props) {
return <SvelteComponent component={Component} props={{ name: 'world' }} />;
}
// Using the registered name
function YourComponent(props) {
return <SvelteComponent component={'hello'} props={{ name: 'world' }} />;
}
// Conditional rendering
function YourComponent(props) {
return <SvelteComponent component={'hello'} props={{ name: 'world' }} to-render={props.render} />;
}
export type SvelteComponentProps = {
component: string | typeof SvelteComponentClass;
props?: any;
toRender?: boolean;
options?: CreateOptions;
onMount?: (element: SvelteElement) => void;
};
Use the built-in AngularJS component.
Register your Svelte component
// /svelte/index.module.ts
import { registerComponent } from 'svelte-injector';
import Component from 'src/Component.svelte';
registerComponent('component-name', Component);
// /angularjs/index.module.ts
import { svelteComponent } from 'svelte-injector/angularjs';
angular.component('svelteComponent', svelteComponent);
Now in any AngularJS component you can use:
<svelte-component component="component-name" props="$ctrl.svelteProps" />
const bindings = {
component: '@', // Registered component name
props: '?<', // Props object
toRender: '?<', // Ng-if
options: '?<', // HydrateOptions
encode: '?<', // encode props?
onMount: '?&' // Function called with "element" param on mount
};
Docs in progress
Interface SvelteElement
object
The new props object. All previous props will be dropped.
boolean
Set if the component should render of not. Useful for conditional rendering.
Destroys the component.
HTMLElement
The element in which the component will be rendered
SvelteComponent | string
The Svelte component Class or the registered component name
object
An object with props compatible with the Svelte Component
boolean
(default = true)Boolean that indicates if the component should render immediately.
CreateOptions
(defaults)Object with options
Promise<SvelteElement>
A promise that resolves the SvelteElement
when the component is mounted or created (when toRender = false)
string
The name of the link
SvelteComponent | function
The Svelte Component class or an async functions that returns one (useful for dynamic imports and lazy loading).
HTMLElement
The element in which the components will be looked for.
HydrateOptions
(defaults)Object with options
Promise<SvelteElement[]>
A promise array for each created component that resolves the SvelteElement
when the component is mounted or created (when data-to-render = false)
string
name of the component as previously registered with registerComponent()
typeof SvelteComponent
The Class of the registered component, if any
typeof SvelteComponent
Class of the component as previously registered with registerComponent()
string
The name of the registered component, if any
Returns an HTML string representing the props template HTML element, as expected from hydrate
.
Returns stringified (and encoded?) string from a props object, as expected from the parser.
Options object are the optional last argument of create
and hydrate
methods.
Create a MutationObserver on the element parent and destroy the component if no longer in the DOM
Create a MutationObserver on the element parent and destroy the component if no longer in the DOM
Create a MutationObserver on the props element and update the component on props updates.
All functions from SvelteInjector are now named exports.
import { create } from 'svelte-injector';
create(target, Component, props);
// or
import * as SvelteInjector from 'svelte-injector';
SvelteInjector.create(target, Component, props);
The link
function has been renamed to registerComponent
.
The main methods have been renamed
createElement --> create
createElementFromTemplate, syncTemplate --> hydrate
Use of data-props
attribute is no longer supported. Props should be expressed in the new template format:
<div data-component-name="hello" data-to-render"true">
<template class="props"">
<!--JSON formatted-->
{"name": "hello"}
</template>
</div>