├── .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 | ![ScreenShot](screenshot.gif) 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 | 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 | --------------------------------------------------------------------------------