{"id":15681452,"url":"https://github.com/drwpow/snowpack-preact-ts","last_synced_at":"2025-06-19T23:38:24.010Z","repository":{"id":45317516,"uuid":"186310714","full_name":"drwpow/snowpack-preact-ts","owner":"drwpow","description":"snowpack + Preact + TypeScript","archived":false,"fork":false,"pushed_at":"2021-12-21T17:05:32.000Z","size":1584,"stargazers_count":11,"open_issues_count":21,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-07T07:03:59.241Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pika-web-preact.powers.now.sh","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/drwpow.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-12T22:27:59.000Z","updated_at":"2021-12-16T11:14:52.000Z","dependencies_parsed_at":"2022-09-10T01:30:32.906Z","dependency_job_id":null,"html_url":"https://github.com/drwpow/snowpack-preact-ts","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/drwpow/snowpack-preact-ts","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drwpow%2Fsnowpack-preact-ts","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drwpow%2Fsnowpack-preact-ts/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drwpow%2Fsnowpack-preact-ts/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drwpow%2Fsnowpack-preact-ts/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/drwpow","download_url":"https://codeload.github.com/drwpow/snowpack-preact-ts/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/drwpow%2Fsnowpack-preact-ts/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260851172,"owners_count":23072551,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-03T16:54:47.932Z","updated_at":"2025-06-19T23:38:18.999Z","avatar_url":"https://github.com/drwpow.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ca href=\"https://pika-web-preact.powers.now.sh\"\u003e\u003cimg alt=\"View Demo\" src=\"https://img.shields.io/badge/%E2%96%B3-View%20Demo-black\"/\u003e\u003c/a\u003e\n\n![Michael Scott’s Dunder Mifflin\n        Scranton Meredith Palmer Memorial Celebrity Rabies Awareness Pro-Am Fun\n        Run Race For The Cure](./src/static/michaelscottsdundermifflinscrantonmeredithpalmermemorialcelebrityrabiesawarenessproamfunrunraceforthecure.gif)\n\n# snowpack + Preact + TypeScript\n\nExample using TypeScript, Preact, and [snowpack][snowpack], a new ESM\nbundler. Uses [Sass][sass] for styling.\n\n## Other Languages\n\n- [Vue][pika-web-vue]\n\n## Example\n\n```bash\nnpm i\nnpm start\n```\n\nIt’ll run a multi-page app at `localhost:5000`.\n\n_Note: changes to `.tsx` \u0026 `.scss` files will re-build automatically, but\nchanges to `src/index.html` will require a restart of the dev server_\n\n### 💁 Explanation\n\nType handling is the difficult part of using TypeScript with snowpack, since\nbrowsers don’t support it. The core concepts of pulling this off are:\n\n1. Having a separate `src/` and `dist/` folders\n1. Using this fix in `tsconfig.json` ([discussion][tsconfig]):\n   ```json\n     \"compilerOptions\": {\n       \"paths\": {\n         \"/web_modules/*.js\": [\n           \"node_modules/@types/*\",\n           \"node_modules/*\",\n           \"web_modules/*.js\",\n         ]\n       }\n     }\n   ```\n\nThe first point is a rather obvious one: since TypeScript isn’t supported by\nbrowsers, we’ll have to keep our source code separate from our compile\ndirectory. That’s easy enough, but when you compile it, now you have a lot of\nthese in your code:\n\n```js\nimport preact from \"preact\";\n```\n\nA browser doesn’t know what to do with that! That’s not a proper path, and\nit’s also missing the `.js` extension. However, if you try modifying your\nTypeScript to:\n\n```ts\nimport preact from \"./web_modules/preact.js\";\n```\n\nNow TypeScript can’t resolve those modules or their types! However, by\naliasing these imports a special way, we can do something clever:\n\n```json\n  \"compilerOptions\": {\n    \"paths\": {\n      \"/web_modules/*.js\": [\n        \"node_modules/@types/*\",\n        \"node_modules/*\",\n        \"web_modules/*.js\",\n      ]\n    }\n  }\n```\n\nThis lets us do the following in our project (we’ll always need to do this\nfor all web_modules):\n\n```ts\nimport preact from \"/web_modules/preact.js\";\n```\n\nLet’s break down what this tells TypeScript:\n\n- `/web_modules/*.js` tells TypeScript to take any import matching this\n  pattern and treat it differently (“this pattern” meaning any import that\n  starts with a `/`, then has `web_modules`, then anything (`*`), then ends in\n  `.js`).\n- How should TypeScript treat them differently? Well, it should try and find the `*` in any of the following folders:\n  - First, try `node_modules/@types/*` (for the modules that have external types)\n  - Next, try `node_modules/*` to see if the original library has types\n  - Lastly, try `web_modules/*` to see if snowpack ported the types over.\n\nUsually, the types will be found somewhere within `node_modules` and\nTypeScript is happy.\n\nBut wait—what about browsers? Well that’s the best part! If we look at our output code:\n\n```js\nimport preact from \"/web_modules/preact.js\";\n```\n\nThat `/web_modules/preact.js` resolves to be an actual path to our ESM on our\nserver (assuming `web_modules` was installed at the root)! So the alias we\nwere using for TypeScript also happened to be a valid path the browser\nunderstands.\n\nIf you need to install `web_modules` somewhere else other than the root, then\nyou can change the `--dest` of snowpack as well as the option under\n`\"paths\"` in `tsconfig.json` as-needed.\n\n---\n\nIf you’re using ESLint, you’ll have to add a few more rules to keep it happy\n(you may already be familiar with this if you’ve used TypeScript \u0026 JSX\nbefore):\n\n```json\n{\n  \"rules\": {\n    \"import/extensions\": \"off\", // we need this for browsers\n    \"import/no-absolute-path\": \"off\", // we also need this\n    \"import/no-unresolved\": \"off\", // TypeScript got this\n    \"react/jsx-filename-extension\": [\n      \"error\",\n      { \"extensions\": [\".js\", \".jsx\", \".tsx\"] }\n    ]\n  }\n}\n```\n\n[pika-web-vue]: https://github.com/dangodev/pika-web-vue\n[snowpack]: https://www.snowpack.dev/\n[tsconfig]: https://github.com/pikapkg/web/issues/4#issuecomment-469094924\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrwpow%2Fsnowpack-preact-ts","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdrwpow%2Fsnowpack-preact-ts","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdrwpow%2Fsnowpack-preact-ts/lists"}