developit / htm

Hyperscript Tagged Markup: JSX alternative using standard tagged templates, with compiler support.
Apache License 2.0
8.67k stars 170 forks source link

type=module and react aliasing #200

Closed damianobarbati closed 3 years ago

damianobarbati commented 3 years ago

This is simple amazing: no webpack, no babel but I'm using preact and components in the browser ❤️

How do you alias react=>preact in the browser? I mean, if you import a module which relies on react it throws in console:

Uncaught TypeError: Failed to resolve module specifier "react". Relative references must start with either "/", "./", or "../".

Simple example:

import { html } from 'https://unpkg.com/htm/preact/standalone.module.js';
import { useForm } from 'https://unpkg.com/react-hook-form/dist/index.esm.js';
...

What's the correct way to overcome this?

developit commented 3 years ago

@damianobarbati unfortunately, there is no easy way to do this with unpkg. Unpkg transforms imports to explicit URLs and doesn't provide an aliasing option.

You can use npm.reversehttp.com though. It's a dependency bundling service I run that is fronted by CloudFlare's CDN. You give it a comma-separated list of npm modules, and it serves an ES Module with all of those combined into one file with their exports merge together:

// the exports from the modules are combined (convenient)
import {
  html, render,  // these are from preact & htm
  useForm, FormProvider   // these are from react-hook-form
} from 'https://npm.reversehttp.com/preact,react:preact/compat,htm/preact,react-hook-form';
                                             // ^ this aliases react to preact/compat

function App() {
  const form = useForm();
  // etc
}

render(html`
  <${FormProvider}>
    <${App} />
  <//>
`, document.body);

You can play with the modules in that bundle URL here to generate different variations: https://npm.reversehttp.com/#preact,react:preact/compat,htm/preact,react-hook-form

developit commented 3 years ago

Also - I know you're looking to do development in-browser and avoid transpile stuff, but FWIW we just released WMR that is about as close as you can get to that experience. It's basically a static file server, but it rewrites your JavaScript imports to a local CDN that streams modules from npm. It also supports JSX by converting it to HTM (without Babel). Best of all, it's a single JavaScript file with no dependencies:

mkdir demo && cd demo
echo '<script type="module" src="index.js"></script>' > index.html
echo 'import { render } from "preact"; render(<h1>Hi!</h1>);' > index.js
npx wmr
# Listening on http://localhost:8080
damianobarbati commented 3 years ago

@developit thanks so much for answering so quick.

I'm giving this a try today!

My main concern when using type=module and preact is the ability to use other libraries dependent on peact. They are about to use the react render method (once transpiled in dist) and if a global reference or anything aliasing that to the preact render method is not available, then it won't work. This limits the scope an application/prototype built like this to use the whole react ecosystem.

Is this correct?

developit commented 3 years ago

Only for ES Modules, yes. There is no spec for aliasing (other than import maps, but it's only supported in Chrome and quite manual), which means setups that depend on aliasing can only work if the CDN provides it.