Cannot open old Snack

Hi,

When opening an older Snack, it get stuck on loading.

in the data loaded into INITIAL_DATA on the editor page there is an problem with an old depency which breaks the script.

“error”:Error: Invalid dependency ‘@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.ttf’ (name can only contain URL-friendly characters)

Please help, how to retrieve my Snack…

Hi

Can you post a link to the snack?

I can confirm that I get the same error when trying to load that snack:

I also see the dependency error you’re referring to. The HTML of the snack contains something like the following (reformatted and some stuff stripped out to make things clearer):

window.__INITIAL_DATA__ = {
  "data": {
    "type": "success",
    "snack": {
      // [...]
      "sdkVersion": "34.0.0",
      "created": "2019-10-04T07:10:10.107Z",
      "manifest": {
        "name": "leaselabsdemoSnack",
        "sdkVersion": "34.0.0",
        "description": "No description",
        "dependencies": {
          // [...]
          "@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.ttf": "10.0.5"
        }
      },
      "previewLocation": "https://snack-code-uploads.s3.us-west-1.amazonaws.com/~preview/b9840f2bf3eb43ef363614b79a55a022",
      "status": "SUCCESS",
      "dependencies": {
        // [...]
        "@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.ttf": {
          "version": "10.0.5",
          "resolved": "10.0.5",
          "peerDependencies": {},
          "error": Error: Invalid dependency '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.ttf' (name can only contain URL-friendly characters)
        }
      },
      // [...]
    },
    // [...]
  },
  // [...]
}

So the problem here is that the error message is not quoted, so it breaks the JSON:

          "error": Error: Invalid dependency '@expo/vector-icons/build/vendor/react-native-vector-icons/Fonts/FontAwesome.ttf' (name can only contain URL-friendly characters)

that caused window.__INITIAL_DATA__ not to be defined, so app.bundle.js breaks.

One of the Expo team members will have to have a look, but if you like I can send you a quick’n’dirty script I just wrote that can extract the code and download the assets if you feed it the “code” part of the JSON from __INITIAL_DATA__.

Hi, a script to extract would be great!

@jochem see below:

Extract the code part of the __INITIAL_DATA__ into /tmp/snack.json, create a new directory, change to that directory and then run this quick’n’dirty script:

#!/usr/bin/env python3

# The HTML of a snack contains the snack's code and links to the assets in `window.__INITIAL_DATA__`
# If you extract the value of the "code" key from this JSON and save it to /tmp/snack.json, the following
# code will reconstruct the JS and assets.
# Unfortunately, the package.json is not included, but the main thing needed from there is the list
# of dependencies, which is (mostly) available in the "manifest" part of the JSON.

import json
import requests
import os
import os.path

def make_parent_dirs(path):
    dirs = path.split("/")[:-1]
    for i in range(len(dirs)):
        p = os.path.join(*(dirs[:i+1]))
        if not os.path.isdir(p):
            os.mkdir(p)

code = json.load(open("/tmp/snack.json"))

for path, data in code.items():
    if ".." in path or path.startswith("/"):
        raise Exception("Dodgy path")
    make_parent_dirs(path)
    if data["type"] == "CODE":
        f = open(path, "w")
        f.write(data["contents"])
        f.flush()
        f.close()
    elif data["type"] == "ASSET":
        r = requests.get(data["contents"])
        f = open(path, "wb")
        f.write(r.content)
        f.flush()
        f.close()

You’ll need to cut the part of the __INITIAL_DATA__ JSON containing the code and paste it into /tmp/snack.json. So it should look something like this:

{"App.js":{"type":"CODE","contents":"import * as React from 'react';[...]"}}

You’ll also need to reconstruct package.json, which you can do by e.g. creating a new project and then installing the necessary dependencies based on the ones shown in the “manifest” section of the __INITIAL_DATA__.

This happened to be a problem in the snack-sdk. The problem has been fixed in [sdk] Fix dependencies object modification & scoped dependency names by IjzerenHein · Pull Request #37 · expo/snack · GitHub

We’ll be rolling the fix out to the Snack web app later today.

1 Like

The fixes have been deployed to production, it should now work :+1:

1 Like

The Snacks I tried here don’t work:

are those linked to from anywhere? we don’t maintain those, they just happened to be used at some point. is there something in particular that you’re looking for?