|
1 | 1 | # Sandpack |
2 | 2 |
|
3 | | -A bundler that completely works in the browser, utilizing browser APIs. |
| 3 | +A bundler that completely works in the browser and takes advantage of it. |
4 | 4 |
|
5 | 5 | ## Why? |
6 | 6 |
|
7 | 7 | Online code playgrounds are getting more popular: they provide an easy way to play with code without installation. Until a year ago it was very hard to play with bigger web applications in the browser; there was no bundler that was comparable with local bundlers and worked in the browser. |
8 | 8 |
|
9 | | -CodeSandbox came along, and still had a pretty basic bundler. However, as CodeSandbox got more popular its bundler got more advanced. Nowadays the bundler has comparable feature parity with Webpack, and it would be a shame if others couldn't use the functionality. |
| 9 | +CodeSandbox came along, and still had a pretty basic bundler. However, as CodeSandbox got more popular its bundler got more advanced. Nowadays the bundler is used for all kinds of bigger web projects, and it would be a shame if others couldn't use the functionality. |
10 | 10 |
|
11 | | -This library acts as an interface with the bundler of CodeSandbox. It allows you to run any code on a web page, from Vue projects to React projects. With everything that CodeSandbox supports as well. |
| 11 | +This library acts as an interface with the bundler of CodeSandbox. It allows you to run any code on a web page, from Vue projects to React projects to Parcel projects. With everything that CodeSandbox supports as well. |
12 | 12 |
|
13 | | -## So what can the bundler do? |
| 13 | +## So what can this bundler do? |
14 | 14 |
|
15 | | -This is a list of features that the bundler supports, the list may be outdated. |
| 15 | +This is a list of features that the bundler supports out of the box, the list may be outdated. |
16 | 16 |
|
17 | | -1. Hot Module Reloading API (`module.hot`) |
18 | | -2. npm dependencies |
19 | | -3. Supports most common transpilers (vue, babel, typescript, css) |
20 | | -4. Friendly error overlay |
21 | | -5. Parallel transpiling |
22 | | -6. On-demand transpiler loading |
| 17 | +1. Hot Module Reloading API (`module.hot`) |
| 18 | +2. npm dependencies |
| 19 | +3. Most common transpilers (vue, babel, typescript, css, etc...) |
| 20 | +4. Parallel transpiling |
| 21 | +5. On-demand transpiler loading |
| 22 | +6. Webpack loader syntax (`!raw-loader!./test.js`) |
| 23 | +7. Friendly error overlay (using `create-react-app` overlay) |
| 24 | +8. Transpilation result caching |
23 | 25 |
|
24 | 26 | ## Example usage |
25 | 27 |
|
26 | | -There are multiple ways to use the bundler. We provided two ways, but we're open to PRs to extend ways to use this! |
| 28 | +This repo serves as an interface to communicate with the bundler. The bundler itself is hosted on `sandpack-{version}.codesandbox.io` and is heavily cached by a CDN. We also included the necessary files under `bundler` if you want to host the bundler yourself. |
27 | 29 |
|
28 | 30 | ### Using the Manager |
29 | 31 |
|
30 | | -The Manager is a plain JavaScript implementation, you can use it by importing Manager. |
| 32 | +The Manager is a class implementation, you can use it by importing Manager. |
31 | 33 |
|
32 | 34 | ```js |
33 | | -import { Manager } from 'codesandbox-playground'; |
| 35 | +import { Manager } from 'sandpack'; |
34 | 36 |
|
35 | | -// Let's say you want to show the preview on #preview |
36 | | -const m = new Manager( |
| 37 | +// There are two ways of initializing a preview, you can give it either an iframe element or a selector of an element to create an iframe on. |
| 38 | +const manager = new Manager( |
37 | 39 | '#preview', |
38 | 40 | { |
39 | 41 | files: { |
40 | 42 | '/index.js': { |
41 | 43 | code: `console.log(require('uuid'))`, |
42 | 44 | }, |
43 | 45 | }, |
| 46 | + entry: '/index.js', |
44 | 47 | dependencies: { |
45 | 48 | uuid: 'latest', |
46 | 49 | }, |
47 | | - entry: '/index.js', |
48 | | - } /* you can give a third argument with extra options, described at the bottom */ |
| 50 | + } /* We support a third parameter for advanced options, you can find more info in the bottom */ |
49 | 51 | ); |
50 | 52 |
|
51 | | -// This will show the preview on the #preview element, you can now send new code |
52 | | -// by calling 'sendCode(files, dependencies, entry)'. We will automatically determine |
53 | | -// how to hot update the preview. |
54 | | -m.sendCode( |
55 | | - { |
| 53 | +// When you make a change you can just run `updatePreview`, we'll automatically discover |
| 54 | +// which files have changed and hot reload them. |
| 55 | +manager.updatePreview({ |
| 56 | + files: { |
56 | 57 | '/index.js': { |
57 | | - code: `console.log('other code')`, |
| 58 | + code: `console.log('New Text!')`, |
| 59 | + }, |
| 60 | + entry: '/index.js', |
| 61 | + dependencies: { |
| 62 | + uuid: 'latest', |
58 | 63 | }, |
59 | 64 | }, |
| 65 | +}); |
| 66 | +``` |
| 67 | + |
| 68 | +If you specify a `package.json` in the list of files we will use that as source of truth instead, we infer `dependencies` and `entry` from it: |
| 69 | + |
| 70 | +```js |
| 71 | +// We infer dependencies and the entry point from package.json |
| 72 | +const PACKAGE_JSON_CODE = JSON.stringify( |
60 | 73 | { |
61 | | - uuid: 'latest', |
| 74 | + title: 'test', |
| 75 | + main: 'index.js', |
| 76 | + dependencies: { |
| 77 | + uuid: 'latest', |
| 78 | + }, |
62 | 79 | }, |
63 | | - '/index.js' |
| 80 | + null, |
| 81 | + 2 |
64 | 82 | ); |
| 83 | + |
| 84 | +// Give it either a selector or an iframe element as first argument, the second arguments are the files |
| 85 | +const manager = new Manager('#preview', { |
| 86 | + files: { |
| 87 | + '/index.js': { |
| 88 | + code: `console.log(require('uuid'))`, |
| 89 | + }, |
| 90 | + '/package.json': { |
| 91 | + code: PACKAGE_JSON_CODE, |
| 92 | + }, |
| 93 | + }, |
| 94 | +}); |
65 | 95 | ``` |
66 | 96 |
|
67 | 97 | ### As a React Component |
68 | 98 |
|
69 | | -We included a React component you can use, the implementation is fairly simple. |
| 99 | +We built another library called `react-sandpack` for usage with `sandpack`. This library provides basic React components for editors, including `FileExplorer`, `CodeEditor` and `BrowserPreview`. This serves as a library that makes it easier to build embeddable or full blown online code editors. |
| 100 | + |
| 101 | +An example implementation: |
70 | 102 |
|
71 | 103 | ```jsx |
72 | | -import Preview from 'codesandbox-playground/dist/components/Preview'; |
| 104 | +import React from 'react'; |
| 105 | +import { render } from 'react-dom'; |
| 106 | +import { |
| 107 | + FileExplorer, |
| 108 | + CodeMirror, |
| 109 | + BrowserPreview, |
| 110 | + SandpackProvider, |
| 111 | +} from 'react-sandpack'; |
73 | 112 |
|
74 | 113 | const files = { |
75 | 114 | '/index.js': { |
76 | | - code: ` |
77 | | - console.log('hey') |
78 | | - `, |
| 115 | + code: "document.body.innerHTML = `<div>${require('uuid')}</div>`", |
79 | 116 | }, |
80 | 117 | }; |
81 | 118 |
|
82 | 119 | const dependencies = { |
83 | | - react: 'latest', |
| 120 | + uuid: 'latest', |
84 | 121 | }; |
85 | 122 |
|
86 | | -export default () => <Preview files={files} dependencies={dependencies} entry="/index.js" />; |
| 123 | +const App = () => ( |
| 124 | + <SandpackProvider files={files} dependencies={dependencies} entry="/index.js"> |
| 125 | + <div style={{ display: 'flex', width: '100%', height: '100%' }}> |
| 126 | + <FileExplorer style={{ width: 300 }} /> |
| 127 | + <CodeMirror style={{ flex: 1 }} /> |
| 128 | + <BrowserPreview style={{ flex: 1 }} /> |
| 129 | + </div> |
| 130 | + </SandpackProvider> |
| 131 | +); |
87 | 132 | ``` |
88 | 133 |
|
89 | | -We will automatically hot update the preview as the props update. |
| 134 | +The above code will render a File Explorer, a working code editor and a preview with browser navigation. For more info about `react-sandpack` you can go here: https://github.com/CompuIves/codesandbox-client/tree/master/packages/react-sandpack. |
0 commit comments