replicant

Replicant

Svelte <Repl>

REPLicant - Svelte Summit 2020

This is the source code for a talk I gave at Svelte Summit 2020. This is actual code I wrote during the talk with a few later additions to clean things up. I will add a link to the video when it is published.

Table of Contents

Differences from the talk

The only thing this app does that the version in the talk doesn't is resolve npm module imports to a CDN. So import x from 'randommodule' works in this app too. You can read more details about this here.

Usage

Note: I use pnpm but this will probably work fine with yarn or npm depsite the lockfile warnings.

Clone and install

git clone https://github.com/pngwn/REPLicant.git && cd REPLicant

pnpm i # or yarn or npm i

Run the dev server and play around:

pnpm dev

Commits

initial setup and config

This commit setups the basics. It is the svelte-template after running the setupTypescript script with a few extra config files (.prettierrc.yaml and .gitignore).

We also add some basic typescript interfaces and data structures for the REPL.

Browse the repo at this point
View the commit

repl code editor

This commit adds an input, which is our rudimentary code editor and keeps the contents of the input in sync with the component state we setup earlier.

Browse the repo at this point
View the diff

tabbed interface

This commit adds a tabbed UI allowing us to switch between the different components, marking them as active. The 'active' component is the component we are currently editing in the REPL.

Browse the repo at this point
View the diff

new component creation

This commit adds a button allowing the creation of a new component in the REPL as well as accompanying logic. This only supports the creation of svelte components (.svelte files) and the name is automatically generated.

Browse the repo at this point
View the diff

web worker setup

This commit sets up the basic web worker boilerplate as well as some simple messaging to make sure things are working as expected.

It also adds another entrypoint in the rollup config, to bundle the worker file seperately.

Browse the repo at this point
View the diff

Svelte package imports

This commit setups the rollup basics that we need and resolves svelte imports to the CDN we are using (jsdelivr) as we have no file system. It resolve the follwing cases:

  • plain 'svelte' imports: import { onMount } from 'svelte';
  • svelte 'sub imports': import { writable } from 'svelte/writable';
  • relative imports from a svelte package: import x from './file.js'; where the importing module is module is a svelte module that we handled above.

In addition to resolving the paths, it also fetches the source code from the cdn and passes it to the bundler.

Browse the repo at this point
View the diff

Local package imports

This commit resolves local REPL imports that don't exist anywhere except in memory. These are the components that the user is creating live in the browser.

It also compiles svelte components to valid javascript and returns that to the bundler.

And finally it passes this final bundle back to the main thread.

Browse the repo at this point
View the diff

Iframe setup

This commit sets up the basic ifram boilerplate, giving it a valid srcdoc, listening for any posted messages inside. In the parent component (outside of the iframe) we pass a simple message down to check everything is working.

Browse the repo at this point
View the diff

Evaluate and render

This commit evaluates the bundle in the iframe via a dynamic import using blob urls and then renders the component to the page.

Browse the repo at this point
View the diff

NPM module imports

This did not appear in the talk

This is similar to the earlier resolution steps. This commit resolves npm module imports to the CDN. It does this by fetching the package.json and reading it to work out where teh entry point is. This enables import x from 'any-random-package';.

Unlike with the svelte packages, where we can easily workout what the structure looks like, the entrypoint for a given npm module can vary significantly. We just get the package.json to remove any ambiguity.

This also works for Svelte-specific packages that are using the svelte field to point to uncompile .svelte files.

Browse the repo at this point
View the diff

What next?

This is just the start, from here you can go on to add whatever features you like.

Maybe you want allow importing different file types, that would just require a new transform that convert that format into JavaScript, just like we did with .svelte files.

Perhaps you'd like to add additional UI features. Draggable tabs, more user feedback. Syntax highlighting and code completion could be added by using a dedicated code editor such as monaco-editor or codemirror(which is used by the official Svelte REPL).

Maybe you want to improve the performance of the data-loading and compilation by adding some caching for those behaviours inside the web worker.

The list is endless, check the repl on the Svelte site for inspiration but don't let that limit you!

Further reading

Questions

If you have questions or feedback then feel to file an issue here, bug me on twitter (@evilpingwin), or you can grab me on discord (@pngwn).

Top categories

Loading Svelte Themes