├── .gitignore
├── README.md
├── package.json
├── rollup.config.js
├── screenshot.gif
└── src
└── index.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | coverage
4 | dist/
5 | .yarn/cache
6 | .yarn/unplugged
7 | .yarn/build-state.yml
8 | .pnp.*
9 | yarn.lock
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # svelte-preprocessor-fetch
2 |
3 | > A preprocessor for Svelte that can be used to fetch data before components are compiled.
4 |
5 | ## Demos
6 |
7 | 
8 |
9 | ## Installation
10 |
11 | ```bash
12 | yarn add -D svelte-preprocessor-fetch
13 | ```
14 |
15 | ## Usage
16 |
17 | ### With `rollup-plugin-svelte`
18 |
19 | ```js
20 | // rollup.config.js
21 | import svelte from 'rollup-plugin-svelte';
22 | import preprocessFetch from 'svelte-preprocessor-fetch'
23 |
24 | export default {
25 | ...,
26 | plugins: [
27 | svelte({
28 | preprocess: preprocessFetch()
29 | })
30 | ]
31 | }
32 | ```
33 |
34 | ### In components
35 |
36 | Create a function called `getStaticProps()` in your script tag and do your fetches here. The content of this function must be fully self-container. You can not use any variables from outside or import any packages. It has support for fetch via `node-fetch`.
37 |
38 | The data is available using as `data` in your component.
39 |
40 | ```html
41 |
59 |
60 |
61 | Continents:
62 |
63 | {#each data.continents as { name }}
64 | -
65 |
{name}
66 |
67 | {/each}
68 |
69 |
70 | ```
71 |
72 | ## Caveats
73 |
74 | This preprocessor is probably extremely brittle, PRs are welcome to improve it further.
75 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-preprocessor-fetch",
3 | "version": "1.0.7",
4 | "description": "A preprocessor for Svelte can be used to fetch data before the component is compiled.",
5 | "main": "dist/index.js",
6 | "module": "dist/module.js",
7 | "repository": "https://github.com/kevmodrome/svelte-preprocessor-fetch",
8 | "keywords": [
9 | "svelte",
10 | "preprocess",
11 | "fetch"
12 | ],
13 | "scripts": {
14 | "compile": "rollup -c"
15 | },
16 | "author": "Kevin Åberg Kultalahti",
17 | "license": "MIT",
18 | "dependencies": {
19 | "acorn": "^7.1.1",
20 | "acorn-walk": "^7.1.1",
21 | "node-fetch": "^2.6.0"
22 | },
23 | "devDependencies": {
24 | "@babel/core": "7.8.7",
25 | "@babel/preset-env": "7.8.7",
26 | "@babel/register": "7.8.6",
27 | "rollup": "2.0.3",
28 | "rollup-plugin-babel": "4.4.0",
29 | "rollup-plugin-node-resolve": "5.2.0"
30 | },
31 | "babel": {
32 | "presets": [
33 | [
34 | "@babel/env",
35 | {
36 | "targets": {
37 | "node": 8
38 | }
39 | }
40 | ]
41 | ],
42 | "env": {
43 | "test": {
44 | "sourceMaps": "inline"
45 | }
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/rollup.config.js:
--------------------------------------------------------------------------------
1 | import resolve from "rollup-plugin-node-resolve";
2 | import babel from "rollup-plugin-babel";
3 |
4 | const dev = process.env.NODE_ENV !== "production";
5 |
6 | export default {
7 | input: "./src/index.js",
8 | external: ["path", "node-sass"],
9 | plugins: [resolve(), babel()],
10 | output: [
11 | {
12 | file: "./dist/index.js",
13 | format: "cjs",
14 | sourcemap: dev
15 | },
16 | {
17 | file: "./dist/module.js",
18 | format: "es",
19 | sourcemap: dev
20 | }
21 | ]
22 | };
23 |
--------------------------------------------------------------------------------
/screenshot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kevmodrome/svelte-preprocessor-fetch/b2fb40af7536e8873ef38b7a1ad2e3f6cb07c9e6/screenshot.gif
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | const fetch = require("node-fetch");
2 | const acorn = require("acorn");
3 | const walk = require("acorn-walk");
4 |
5 | export default function preprocessFetch() {
6 | return {
7 | async script({ content }) {
8 | const tree = acorn.parse(content, { sourceType: "module" });
9 | let start, end;
10 |
11 | walk.simple(tree, {
12 | FunctionDeclaration(node) {
13 | if (node.id.name === "getStaticProps") {
14 | start = node.body.start;
15 | end = node.body.end;
16 | }
17 | }
18 | });
19 |
20 | if (!start) return { code: content };
21 |
22 | const code = content.slice(start, end);
23 |
24 | const data = await eval("(async () => {" + code + "})()");
25 |
26 | return { code: insert_data(data, content) };
27 | }
28 | };
29 | }
30 |
31 | function insert_data(data, content) {
32 | var newContent = "const data = " + JSON.stringify(data) + ";" + content;
33 | return newContent;
34 | }
35 |
--------------------------------------------------------------------------------