aleph.js icon indicating copy to clipboard operation
aleph.js copied to clipboard

v0.3.0

Open ije opened this issue 4 years ago • 36 comments

Here's the roadmap for v0.3.0 updates.

Features

  • [x] plugin system
  • [x] framework system
  • [x] ~~new jsx transform~~
  • [x] jsx magic
  • [x] inline style
  • [ ] analyze for production

New JSX transform

~~with new jsx transform, now we can use jsx without importing React.~~

We have decided to postpone this feature until later. See #94 for details.

JSX magic

The new compiler will transpile the JSX intelligently, with this you don't need to import specific components, like Head, Link, etc. Just use the native JSX elements instead:

export default function App() {
  return (
    <>
      {/* head for ssr */}
      <head>
        <title>Hello World</title>
      </head>

      {/* import css */}
      <link rel="stylesheet" href="../styles/app.css" />

      {/* redirct pages */}
      <a href="/about">About</a>

      {/* nav link */}
      <a
        rel="nav"
        href="/about"
        data-active-className="active"
        data-active-style={{ color: 'purple' }}
      >About</a>

      {/* prefetch pages */}
      <a rel="prefetch" href="/about">About</a>

      {/* custom scripts */}
      <script src="https://cdn.google.com/ga.js"></script>
      <script>{`
        function gtag() {
          dataLayer.push(arguments)
         }
         window.dataLayer = window.dataLayer || [];
         gtag("js", new Date());
         gtag("config", "G-1234567890");
      `}</script>
    </>
  )
}

Inline CSS

Add inline CSS by style tag with SSR support:

const color = '#d63369'

export default function App() {
  return (
    <>
      <h1>Hello World</h1>
      <style>{`
        h1 {
          color: ${color};
        }
      `}</style>
    </>
  )
}

New Compiler & Bundler (#28)

  • [x] use swc compiler in Rust instead of tsc
  • [x] bundle code in production mode by esbuild
  • [x] polyfills
    • [x] ~~es5~~
    • [x] es2015 - es2021

Screen-Shot-2020-11-24-at-23 02 22

Plugins

  • [x] builtin css-loader with postcss processor
  • [x] ~~sass-loader (improved by @shadowtime2000 (#41))~~
  • [x] ~~wasm-loader~~
  • [x] markdown-loader

APIs

  • [x] support middlewares
  • [x] ~~decodeBody~~ readBody (#35) thanks @shinspiegel

Server

  • [x] support custom server
  • [x] path rewrites
  • [x] https(tls)
  • [x] gzip/br encoding

Improvements

  • [x] simplify cli output
  • [x] init command UI (#47)
  • [ ] ErrorBoundary UI

Optimization

  • [x] modulepreload (#9) @shadowtime2000
  • [x] cache remote deps
  • [ ] ~~compilation symlink mode~~

Deployment platform support

  • [x] Vercel
    • [x] build
    • [x] APIs(functions)

ije avatar Oct 26 '20 10:10 ije

use https://alephjs.org/mod.ts import URL

Are the urls not going to be versioned?

lucacasonato avatar Oct 26 '20 17:10 lucacasonato

@lucacasonato https://alephjs.org/mod.ts may map to the cli version during the compilation, it's a vague idea

ije avatar Oct 26 '20 18:10 ije

Interesting. I would be careful about magic resolving like that though. It will break all kinds of tooling (deno info, deno cache, deno vscode extension).

lucacasonato avatar Oct 26 '20 19:10 lucacasonato

Aleph.js looks very promising. I have some suggestions:

  1. Designing a plugin API so the community can also contribute to ecosystem.
  2. Using a monorepo, so the code related to core and plugins, and examples are separated.
  3. Use a folder named static for holding static files and build output to public rather than output. This is usually the convention and hosting services have defaults for this folder.
  4. Regarding: support custom server(oak?) -> You can see Sapper for implementation references.
  5. Create a Discord server for communication.

mohsenkhanpour avatar Nov 08 '20 14:11 mohsenkhanpour

@mohsenkhanpour thanks for your kind suggestions!

  1. Aleph.js already has a plugin system, pleas check plugins and example.
  2. Aleph.js works in Deno, monorepo is just Url prefix, will do in the future on-demand.
  3. this repository is a library, directory public and dist(SSG output) will be applied in your application.
  4. i like Sapper too.
  5. will consider, any suggestion?

ije avatar Nov 08 '20 14:11 ije

@ije

  1. Yes, I checked plugins and examples. What I meant was like a more elaborate API, for example Gatsbyjs provides some hooks to Gatsby lifecycle like onPreBuild,onPostBuild ... also as I see now plugins don't accept options. For example config for plugin could be:
// For default options:
plugins: [`aleph-plugin-sass`] 
// For customized option:
plugins: [
  {
    resolve: `aleph-plugin-sass`,
    options: {
      postCssPlugins: [somePostCssPlugin()],
      precision: 6,
    },
  },
]

also having a naming convention for plugins would be very helpful, Gatsby uses like gatsby-plugin-* : For general plugins like sass, less, analytics, CSP, manifest. gatsby-transformer-* : For transformers plugins like image optimization, markdown transformation. gatsby-source-* : For sourcing data during build. Using these plugins you can source data from many source: markdown, yaml, wordpress, .... gatsby-theme-*: These are themes that come with preconfigured options.

Having these kinds of convention can give meaningful purpose to plugin system and lead to a rich ecosystem.

2.Yes. What I meant was like less tangled folder structure. This is not necessary now as you said, however as the number of examples and plugins increase it could be a wise idea.

3.I wasn't talking about this repository, I was talking about the application. In the docs it says put your static files in public folder, and build command outputs a output folder. Using public folder to hold static assets may cause hosting automation to think it should serve public folder, whereas it should serve output folder. Using static folder for static assets, and building to public is more conventional.

5.Just create a server, and put the link on the website/repo Readme.md , and please invite us.

mohsenkhanpour avatar Nov 08 '20 14:11 mohsenkhanpour

@ije Also supporting CSS modules:

// For global CSS
import ".\style.css"

and

// For CSS modules
import styles from ".\style.module.css"

CRA, Next.js, and Gatbsyjs all support this out of the box.

mohsenkhanpour avatar Nov 08 '20 15:11 mohsenkhanpour

@mohsenkhanpour

  1. the plugin system is vary simple, currently only support module import resolve and transform code, since we don't use webpack/rollup/babel. (api)
  2. oh sorry! i think static should be a sub-folder of the public folder, Aleph.js server will serve the public dir as root directly. All files in public folder will be copied to output dir by SSG for example, you want put some javascript or css, even wasm files in your application public and you have some images:
    • /public/static/images/logo.png -> /static/images/logo.png
    • /public/styles/global.css -> /styles/global.css
    • /public/scritps/42.wasm -> /scritps/42.wasm
    • /public/ga.js -> /ga.js
    • /public/favicon.icon -> /favicon.icon

ije avatar Nov 08 '20 15:11 ije

@mohsenkhanpour CSS modules will be supported directly in the future.

ije avatar Nov 08 '20 15:11 ije

What is needed for the API functions to be available in the Vercel?

shinspiegel avatar Dec 05 '20 20:12 shinspiegel

@shinspiegel If you take a look at the serverless functions Vercel docs it seems like only NodeJS is supported for serverless functions. Once Deno is supported, it should be able to work fine, though it may need some communication with the team on serverless functions for Vercel.

shadowtime2000 avatar Dec 05 '20 20:12 shadowtime2000

@shinspiegel @shadowtime2000 this https://github.com/TooTallNate/vercel-deno can help, we should fork it to support aleph's routing

ije avatar Dec 05 '20 23:12 ije

I have tried serverless with Deno, Vercel definitely supports it. Vercel also supports Python, Ruby and Go. Netlify Functions currently support JavaScript (with the option to bundle npm dependencies from package.json) and Go. @ije @shadowtime2000 @shinspiegel As far as I know serverless functions are not dependent on the client side library. You send a request and you receive a response. Routing is often handled by client side routing libraries. I would say tying routing to serverless functions, and making it a requirement to use Vercel Deno for routing is an extremely fragile architecture. Why do you say it should be forked to support Aleph's routing?

mohsenkhanpour avatar Dec 06 '20 08:12 mohsenkhanpour

@masataka The APIRequest of Aleph is not a standard ServerRequest of std which vercel-deno is using, we need to inject router info base on api file path and support dynamic api routes:

// /api/hello/[name].ts

import type { APIRequest } from "https://deno.land/x/aleph/types.ts"

export default function handler(req: APIRequest) {
  req.status(200).json({ name: 'Hello ' + req.params.name })
}

This can not work in Vercel with vercel-deno.

ije avatar Dec 06 '20 08:12 ije

@ije I see. I confused it with client side routes, however you are refereeing to API routes. It's like server routes of Sapper, and Dynamic api routes of Next.js. So these API dynamic routes will also work for dev server, and production server (for example if you want to self host, Aleph).

I suppose Netlify doesn't support such feature. Have you done any research?

mohsenkhanpour avatar Dec 06 '20 09:12 mohsenkhanpour

@shinspiegel @shadowtime2000 this https://github.com/TooTallNate/vercel-deno can help, we should fork it to support aleph's routing

Forking it would be a great idea. I suppose people who use other frameworks could also benefit from using Deno on the serverless side.

@ije BTW have you thought of how to implement custom server (oak)? I see it is in the check list, but there isn't much discussion about it.

How does Sapper's custom server and custom API routing work?

This is the custom server of default Sapper template: https://github.com/sveltejs/sapper-template/blob/master/src/server.js

To make it work with Vercel's dynamic routing they just default export the custom server instance. https://github.com/thgh/vercel-sapper

It's a bit confusing. Is Vercel able to run custom server instance?

mohsenkhanpour avatar Dec 06 '20 09:12 mohsenkhanpour

@mohsenkhanpour

It's a bit confusing. Is Vercel able to run custom server instance?

I don't believe so, Vercel runs on AWS Lambda and is purely serverless hence the cheaper pricings with frameworks like NextJS and BlitzJS (and soon AlephJS) with stuff like API routes

shadowtime2000 avatar Dec 23 '20 05:12 shadowtime2000

@shadowtime2000 It might be that https://github.com/thgh/vercel-sapper converts the custom server to serverless friendly code.

How do you think Aleph can implement custom server (eg. oak) in a serverless compatible way?

mohsenkhanpour avatar Dec 23 '20 06:12 mohsenkhanpour

@mohsenkhanpour That is probably what is going on, NextJS says you can't get the advantages of a serverless architecture when using a custom server implementation, I think it is best to go with that for now... we can probably implement conversion or something in v0.4.

shadowtime2000 avatar Dec 23 '20 07:12 shadowtime2000

We could look into using an adapter system kind of like SvelteKit where you plug an adapter into the aleph.config.(ts|js). It could be possible to have Vercel support with the File System API though that sadly only supports Node. We could also just do it without the file system API. This requires some further research

shadowtime2000 avatar Jan 10 '21 22:01 shadowtime2000

It seems like with the new project restructure the only thing we need JSDoc in now is redirect. I guess JSDoc for internal code would be pretty cool because it makes it easier for potential contributors to understand the codebase.

EDIT: actually i think there are a couple other functions we need JSDoc for tho too

shadowtime2000 avatar Jan 22 '21 05:01 shadowtime2000

@shadowtime2000 good to hear that! writing JSDoc is always hard for me...

ije avatar Jan 22 '21 06:01 ije

@mohsenkhanpour @shadowtime2000 Custom server is ready in the latest branch.

with deno std http server:

import { serve } from "https://deno.land/std/http/server.ts"
import { Application, Server } from "https://deno.land/x/aleph/server/mod.ts"

const app = new Appliaction() 
const server = new Server(app)
const s = serve({ port: 8080 })

for await (const r of s) {
  server.handle(r)
}

with oak:

import { Application as Oak } from "https://deno.land/x/oak/mod.ts";
import { Application, Server } from "https://deno.land/x/aleph/server/mod.ts"

const oak = new Oak()
const app = new Appliaction() 
const server = new Server(app)

oak.use((ctx) => {
  server.handle(ctx.request)
})

await oak.listen({ port: 8080 })

ije avatar Jan 29 '21 13:01 ije

Great work.
I will update the website and write docs for it. What is the default path for custom server?

mohsenkhanpour avatar Jan 29 '21 14:01 mohsenkhanpour

Server choice of std vs oak might be an option that could be picked from when the Init UI (https://github.com/alephjs/aleph.js/pull/47) is in place. Could skip the need for documentation.

thegaryroberts avatar Feb 06 '21 01:02 thegaryroberts

Server choice of std vs oak might be an option that could be picked from when the Init UI (#47) is in place. Could skip the need for documentation.

I don't think this is the best way to do this - a custom server is a more "advanced" configuration so users should be able to implement it on their own.

shadowtime2000 avatar Feb 07 '21 00:02 shadowtime2000

I disagree, oak is the Deno module (not NodeJS too, only Deno) with the most stars listed on deno.land. It means that many people use it, this choice should be available.

Hunam6 avatar Mar 28 '21 02:03 Hunam6

@Hunam6 I don't think popularity should be the deciding factor. Just because many people use it shouldn't really mean that the choice should be available. Going for a custom server architecture instead of a basic serverless like option is something that should only done once you have a full grasp because if you mess up the entire app goes down. I think it is a good idea to instead kind of "force" people to read the docs on it so they can understand.

shadowtime2000 avatar Mar 28 '21 03:03 shadowtime2000

@ije I think we need to add more details to Contributing.md on how to start and test application

getspooky avatar Apr 13 '21 17:04 getspooky

What's the current state of Vercel API functions? I can help

Maybe we can fork vercel-deno? https://github.com/TooTallNate/vercel-deno

hazae41 avatar May 06 '21 11:05 hazae41

this probably isnt the best place to put this but could anyone give me some pointers on making a plugin for Aleph?

Lite5h4dow avatar Aug 21 '21 09:08 Lite5h4dow

@Lite5h4dow the docs updating will land later includes the plugin writing guid!

ije avatar Aug 22 '21 19:08 ije

Thankyou 😊

Lite5h4dow avatar Aug 22 '21 19:08 Lite5h4dow

@Lite5h4dow https://alephjs.org/docs/api-reference/plugin-api it is

ije avatar Aug 23 '21 19:08 ije

What's the current state of Vercel API functions? I can help

Maybe we can fork vercel-deno? https://github.com/TooTallNate/vercel-deno

i implemented this forked from @lucacasonato prior works at https://github.com/alephjs/vercel-aleph

ije avatar Aug 28 '21 06:08 ije

Is Vue/pluggable-frameworks still a v0.4.0 goal? There's no specific issue for it that I can find, so there's nothing listed under milestones about it either, just passing mentions.

josh-hemphill avatar Oct 30 '21 22:10 josh-hemphill