alephjs / aleph.js

The Full-stack Framework in Deno.
https://aleph.deno.dev/
MIT License
5.27k stars 166 forks source link

Micro Frontends with Aleph idea #206

Open aadamsx opened 3 years ago

aadamsx commented 3 years ago

I've read about this feature think this would be a great feature addition to Aleph:

https://medium.com/the-hamato-yogi-chronichels/lets-build-micro-frontends-with-nextjs-and-module-federation-b48c2c916680

https://github.com/vercel/next.js/issues/6040#issuecomment-490723276

hastebrot commented 3 years ago

I see a chance, that something similar to module federation will be much easier and more elegant to implement with Deno and Aleph than with Node, Webpack 5 and NextJS 10.

I wonder if there could be an export_map.json in the future, that uses Deno to bundle modules on component-level (React components).

ije commented 3 years ago

@hastebrot interest, i think this can be done very easy in deno since we use es modules via url, export_map.json looks great! at next stage we are going to support Vue, that can give us a good view about micro frontends

tsukhu commented 3 years ago

if you compare this to single-spa where they also use import-maps for microfrontends.

For example: here the my-deno-lib is exposing a component Thing

{
  "imports": {
    "~/": "./",
    "aleph/": "https://deno.land/x/aleph@v0.3.0-alpha.33/",
    "aleph/types": "https://deno.land/x/aleph@v0.3.0-alpha.33/types.ts",
    "framework": "https://deno.land/x/aleph@v0.3.0-alpha.33/framework/core/mod.ts",
    "framework/react": "https://deno.land/x/aleph@v0.3.0-alpha.33/framework/react/mod.ts",
    "react": "https://esm.sh/react@17.0.2",
    "react-dom": "https://esm.sh/react-dom@17.0.2",
    "my-deno-lib": "https://unpkg.com/my-deno-lib@0.1.3/dist/my-deno-lib.esm.js"
  },
  "scopes": {}
}

And can be used like this

import { useDeno } from 'framework/react'
import React from 'react'
import Logo from '~/components/logo.tsx'
import useCounter from '~/lib/useCounter.ts'
import { Thing } from 'my-deno-lib';

export default function Home() {
  const [count, isSyncing, increase, decrease] = useCounter()
  const version = useDeno(() => Deno.version.deno)

  return (
    <div className="page">
      <head>
        <title>Hello World - Aleph.jss</title>
        <link rel="stylesheet" href="../style/index.css" />
      </head>
      <p className="logo"><Logo /></p>
      <h1>Welcome to use <strong>Aleph.js</strong>!</h1>
      <Thing />
...
    </div>
  )
}

The problem currently is that I cannot get the import-maps to work dynamically . This is I should require to restart the server to make a change in the import map. Also HMR currently does not pick up new version updates in the import maps.

It potentially works as Microfrontends now however we do need a rebuild. However if the import-maps can be made part of the HMR and be provided externally that will be ideal

To Reproduce

See the library component in dark blue image

Change the library component to version 0.1.2 in the import-map

{
  "imports": {
    "~/": "./",
    "aleph/": "https://deno.land/x/aleph@v0.3.0-alpha.33/",
    "aleph/types": "https://deno.land/x/aleph@v0.3.0-alpha.33/types.ts",
    "framework": "https://deno.land/x/aleph@v0.3.0-alpha.33/framework/core/mod.ts",
    "framework/react": "https://deno.land/x/aleph@v0.3.0-alpha.33/framework/react/mod.ts",
    "react": "https://esm.sh/react@17.0.2",
    "react-dom": "https://esm.sh/react-dom@17.0.2",
    "my-deno-lib": "https://unpkg.com/my-deno-lib@0.1.2/dist/my-deno-lib.esm.js"
  },
  "scopes": {}
}

image