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.
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.
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
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
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
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
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
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
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:
import { onMount } from 'svelte';
import { writable } from 'svelte/writable';
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
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
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
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
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
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!
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).