Skip to content

drwpow/snowpack-preact-ts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

View Demo

Michael Scott’s Dunder Mifflin Scranton Meredith Palmer Memorial Celebrity Rabies Awareness Pro-Am Fun Run Race For The Cure

snowpack + Preact + TypeScript

Example using TypeScript, Preact, and snowpack, a new ESM bundler. Uses [Sass][sass] for styling.

Other Languages

Example

npm i
npm start

It’ll run a multi-page app at localhost:5000.

Note: changes to .tsx & .scss files will re-build automatically, but changes to src/index.html will require a restart of the dev server

💁 Explanation

Type handling is the difficult part of using TypeScript with snowpack, since browsers don’t support it. The core concepts of pulling this off are:

  1. Having a separate src/ and dist/ folders
  2. Using this fix in tsconfig.json (discussion):
      "compilerOptions": {
        "paths": {
          "/web_modules/*.js": [
            "node_modules/@types/*",
            "node_modules/*",
            "web_modules/*.js",
          ]
        }
      }

The first point is a rather obvious one: since TypeScript isn’t supported by browsers, we’ll have to keep our source code separate from our compile directory. That’s easy enough, but when you compile it, now you have a lot of these in your code:

import preact from "preact";

A browser doesn’t know what to do with that! That’s not a proper path, and it’s also missing the .js extension. However, if you try modifying your TypeScript to:

import preact from "./web_modules/preact.js";

Now TypeScript can’t resolve those modules or their types! However, by aliasing these imports a special way, we can do something clever:

  "compilerOptions": {
    "paths": {
      "/web_modules/*.js": [
        "node_modules/@types/*",
        "node_modules/*",
        "web_modules/*.js",
      ]
    }
  }

This lets us do the following in our project (we’ll always need to do this for all web_modules):

import preact from "/web_modules/preact.js";

Let’s break down what this tells TypeScript:

  • /web_modules/*.js tells TypeScript to take any import matching this pattern and treat it differently (“this pattern” meaning any import that starts with a /, then has web_modules, then anything (*), then ends in .js).
  • How should TypeScript treat them differently? Well, it should try and find the * in any of the following folders:
    • First, try node_modules/@types/* (for the modules that have external types)
    • Next, try node_modules/* to see if the original library has types
    • Lastly, try web_modules/* to see if snowpack ported the types over.

Usually, the types will be found somewhere within node_modules and TypeScript is happy.

But wait—what about browsers? Well that’s the best part! If we look at our output code:

import preact from "/web_modules/preact.js";

That /web_modules/preact.js resolves to be an actual path to our ESM on our server (assuming web_modules was installed at the root)! So the alias we were using for TypeScript also happened to be a valid path the browser understands.

If you need to install web_modules somewhere else other than the root, then you can change the --dest of snowpack as well as the option under "paths" in tsconfig.json as-needed.


If you’re using ESLint, you’ll have to add a few more rules to keep it happy (you may already be familiar with this if you’ve used TypeScript & JSX before):

{
  "rules": {
    "import/extensions": "off", // we need this for browsers
    "import/no-absolute-path": "off", // we also need this
    "import/no-unresolved": "off", // TypeScript got this
    "react/jsx-filename-extension": [
      "error",
      { "extensions": [".js", ".jsx", ".tsx"] }
    ]
  }
}

About

snowpack + Preact + TypeScript

Resources

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •