Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(api): refactor sandpack provider #342

Merged
merged 20 commits into from
Feb 17, 2022
Merged

Conversation

danilowoz
Copy link
Member

@danilowoz danilowoz commented Jan 27, 2022

This PR aims to solve a few inconsistencies and redundancies in the surface API for the main components (Sandpack and SandpackProvider). Although I could take this opportunity to introduce more changes in the organization of files, I would rather do only the necessary changes and spent more time writing tests.

It's important to point out that with #276 and #326, this PR will trigger a major bump in the versions of the packages.

Breaking changes:

  • SandpackRunner has been deprecated: as the same result can be done using the SandpackPreview component;
  • SandpackProvider API: it fixes a few inconsistencies, which used to lead to very common mistakes. From now on, it's very alike to Sandpack API, except that for some exceptions;
  • customSetup.main has been deprecated: due to redundancy, use options.activePath instead;
  • customSetup.files has been deprecated: due to redundancy, use files instead;

Example:

<>
  <Sandpack 
    files={{ "file.js": "" }} 
    customSetup={{ 
      entry: "file.js"
    }}
    options={{
      activePath: "file.js"
    }}
  />

  <SandpackProvider 
    files={{ "file.js": "" }} 
    customSetup={{ 
      entry: "file.js"
    }}
    options={{
      activePath: "file.js"
    }}
  >
    ...
  </SandpackProvider>
</>

Others features

  • Added a bunch of unit tests, mostly covering the getSandpackStateFromProps, which is one of the core utility in Sandpack;
  • Rewrite all messages errors: bring more clarity, consistency and it introduces the scope in the message error;
  • Merge dependencies into any package.json that is provided from files;

A migration guide will be addressed in another situation.

Closes #325 closes #329

@codesandbox-ci
Copy link

codesandbox-ci bot commented Jan 27, 2022

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit 0a5a9ef:

Sandbox Source
Sandpack Blog Example 1 Configuration

@github-actions
Copy link

github-actions bot commented Jan 27, 2022

Size changes

sandpack-react

Total base (gzip) Total current (gzip) +/-
161 kb 159 kb 🎉 -1 kb (-0.87%)
Details
Dependency name / file Base Current +/-
index.css 28 kb File removed ⚠️
webpack 487 bytes File removed ⚠️
0 522 kb 522 kb ✅ 0 byte
main 455 kb 475 kb ⚠️ +20 kb (+4.39%)
@codesandbox/sandpack-react 73 kb 79 kb ⚠️ +6 kb (+8.93%)
@code-hike/classer 1 kb 1 kb ✅ 0 byte
@codemirror/state 35 kb 35 kb ✅ 0 byte
@codemirror/view 164 kb 164 kb ✅ 0 byte
@codemirror/highlight 12 kb 12 kb ✅ 0 byte
@codemirror/lang-css 11 kb 11 kb ✅ 0 byte
@codemirror/lang-javascript 6 kb 6 kb ✅ 0 byte
@codemirror/lang-html 15 kb 15 kb ✅ 0 byte
@stitches/core New file 16 kb ⚠️
@codesandbox/sandpack-client 13 kb 13 kb ✅ 0 byte
@codemirror/closebrackets 6 kb 6 kb ✅ 0 byte
@codemirror/matchbrackets 4 kb 4 kb ✅ 0 byte
@codemirror/commands 24 kb 24 kb ✅ 0 byte
@codemirror/comment 4 kb 5 kb ✅ 0 byte
@codemirror/gutter 10 kb 10 kb ✅ 0 byte
@codemirror/history 9 kb 9 kb ✅ 0 byte
@react-hook/intersection-observer 2 kb 2 kb ✅ 0 byte
@lezer/common 33 kb 33 kb ✅ 0 byte
style-mod 3 kb 3 kb ✅ 0 byte
@codemirror/text 13 kb 13 kb ✅ 0 byte
@codemirror/rangeset 16 kb 16 kb ✅ 0 byte
w3c-keyname 2 kb 2 kb ✅ 0 byte
@codemirror/language 19 kb 19 kb ✅ 0 byte
@lezer/css 9 kb 9 kb ✅ 0 byte
@lezer/html 12 kb 12 kb ✅ 0 byte
@lezer/javascript 54 kb 54 kb ✅ 0 byte
@codemirror/autocomplete 33 kb 33 kb ✅ 0 byte
@react-hook/passive-layout-effect 191 bytes 191 bytes ✅ 0 byte
@lezer/lr 31 kb 31 kb ✅ 0 byte
@codemirror/tooltip 14 kb 14 kb ✅ 0 byte
lodash.isequal 18 kb 18 kb ✅ 0 byte
codesandbox-import-utils 367 bytes 367 bytes ✅ 0 byte
react-devtools-inline 823 kb 823 kb ✅ 0 byte
package-build-stats New file 487 bytes ⚠️
lz-string 9 kb 9 kb ✅ 0 byte
intersection-observer 13 kb 13 kb ✅ 0 byte
react-is 2 kb 2 kb ✅ 0 byte

sandpack-client

Total base (gzip) Total current (gzip) +/-
7 kb 7 kb ✅ 0 byte
Details
Dependency name / file Base Current +/-
webpack 487 bytes File removed ⚠️
main 20 kb 21 kb ✅ 0 byte
@codesandbox/sandpack-client 10 kb 11 kb ✅ 0 byte
codesandbox-import-utils 3 kb 3 kb ✅ 0 byte
lodash.isequal 18 kb 18 kb ✅ 0 byte
package-build-stats New file 487 bytes ⚠️

@danilowoz danilowoz changed the title initial version feat(api): refactor sandpack provider Jan 27, 2022
@danilowoz danilowoz marked this pull request as ready for review February 1, 2022 20:05
Copy link
Member

@DeMoorJasper DeMoorJasper left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really nice refactor, found some small typos and a question about file path normalization

sandpack-client/src/client.ts Outdated Show resolved Hide resolved
sandpack-client/src/utils.ts Outdated Show resolved Hide resolved
}
const getPackageJsonFile = (): string | undefined => {
if (newFiles["/package.json"]) return "/package.json";
if (newFiles["package.json"]) return "package.json";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we normalise these paths at some point? Just a note for potential future improvements

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, indeed we need to address it. I noted this problem when I was trying to implement a new feature, which fetches sandboxes from CodeSandbox, and I faced a ton of issues (see resolveFile for instance).

Here's the task: #353

@danilowoz danilowoz added this to the v1.0.0 milestone Feb 2, 2022
@danilowoz danilowoz changed the base branch from main to major-release February 2, 2022 14:31
Copy link
Collaborator

@alexnm alexnm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

const strategies = [".js", ".jsx", ".ts", ".tsx"];
const leadingSlash = Object.keys(files).every((file) => file.startsWith("/"));

while (!resolvedPath && index < strategies.length) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would benefit from some comments for future proofness

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, thanks for mentioning it. I'll revisit it later in this task, there is still room for improvements there

const leadingSlash = Object.keys(files).every((file) => file.startsWith("/"));

while (!resolvedPath && index < strategies.length) {
const slashPath = (): string => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: I would extract this as a general util for strings/paths

@@ -184,42 +183,6 @@ experience by modifying the `recompileDelay` value or by setting the
/>
```

## Sandpack Runner
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would maybe keep the docs about Sandpack Runner with a mention that it was deprecated and an example of how to use the Preview to get the same result. WDYT?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense. But I would only add an example of how to use the Preview and leave to mention the deprecated component in the Migration Guide. I'll add to my to-do list to address all the documentation parts at once.


/**
* @category Presets
*/
export const Sandpack: React.FC<SandpackProps> = (props) => {
// Combine files with customSetup to create the user input structure
const userInputSetup = props.files
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feels good to get rid of this kind of logic :)

openPaths: props.options?.openPaths,
activePath: props.options?.activePath,
recompileMode: props.options?.recompileMode,
recompileDelay: props.options?.recompileDelay,
autorun: props.options?.autorun ?? true,
autorun: props.options?.autorun,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

haven't searched for this, but doesn't the autorun need to be true by default?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but I leave the SandpackContext to set the default values

customSetup={userInputSetup}
customSetup={props.customSetup}
files={props.files}
options={providerOptions}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 this looks so much better now

@danilowoz danilowoz merged commit 6f28197 into major-release Feb 17, 2022
@danilowoz danilowoz deleted the feat/custom-setup branch February 17, 2022 20:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants