GithubHelp home page GithubHelp logo

bikeshaving / shovel Goto Github PK

View Code? Open in Web Editor NEW
5.0 2.0 0.0 289 KB

Dig for treasure šŸš§ Under Construction šŸš§

License: MIT License

JavaScript 92.66% TypeScript 7.34%
crank development-server esbuild single-page-app static-site-generation multi-page-app

shovel's People

Contributors

brainkim avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

shovel's Issues

Router

See #3 for context about the broader project.

I want a router. Here are some popular styles for routers out there. We will not be considering file-system based routing options.

Express.js

const express = require('express');
const app = express();

const router = express.Router();

router.get('/:id', (req, res) => {
  res.send(`This is the page for item ${req.params.id}`);
});

router.post('/', (req, res) => {
  // do something with the POST data
  res.send('POST request received');
});

app.use('/items', router);

Things I like:

  • Callback code is in the second-level scope. Fewer indents good.
  • path-to-regexp
  • Callback is the same style as the middleware system (minus the next()).

Things I donā€™t like:

  • HTTP verbs as methods is whack. If youā€™re RESTful or whatever, you gotta duplicate path definitions. Also I donā€™t like using get() for responses which do HTML. That feels like it should be separate.
  • FETCH PLEASE

Vue Router

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from './components/Home.vue'
import About from './components/About.vue'

Vue.use(VueRouter)

const router = new VueRouter({
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
})

Vue Router seems to inject params and other routing data with a special $route. Child routing, with automatic component nesting. Could be nice but again is pretty framework specific.

const routes = [
  {
    path: '/user/:id',
    component: User,
    children: [
      {
        // UserProfile will be rendered inside User's <router-view>
        // when /user/:id/profile is matched
        path: 'profile',
        component: UserProfile,
      },
      {
        // UserPosts will be rendered inside User's <router-view>
        // when /user/:id/posts is matched
        path: 'posts',
        component: UserPosts,
      },
    ],
  },
]

Things I like.

  • Data representation of routes with names.
  • Component-level integration.
  • Components can nest.
  • Client-side routing.

Things I donā€™t like

  • FETCH PLEASE
  • do I want to make the router frontend framework agnostic?
  • Components can nest.

Django

from django.urls import path, re_path
from django.views.generic import TemplateView
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('about/', views.about, name='about'),
    path('contact/', views.contact, name='contact'),
    path('blog/', views.blog_list, name='blog_list'),
    path('blog/<int:year>/<int:month>/<slug:slug>/', views.blog_post, name='blog_post'),
    path('products/', views.product_list, name='product_list'),
    path('products/<slug:category>/', views.product_list, name='product_list_category'),
    path('products/<slug:category>/<slug:product>/', views.product_detail, name='product_detail'),
    re_path(r'^search/(?P<query>\w+)/$', views.search, name='search'),
    path('signup/', views.signup, name='signup'),
    path('login/', views.login, name='login'),
    path('logout/', views.logout, name='logout'),
    path('profile/', views.profile, name='profile'),
    path('profile/edit/', views.edit_profile, name='edit_profile'),
    path('password/change/', views.change_password, name='change_password'),
    path('terms/', TemplateView.as_view(template_name='terms.html'), name='terms'),
    path('privacy/', TemplateView.as_view(template_name='privacy.html'), name='privacy'),
]

Hereā€™s the nesting concept:

from django.urls import path, include
from . import views

urlpatterns = [
    path('accounts/', include('accounts.urls')),
    path('blog/', include('blog.urls')),
    path('shop/', include('shop.urls')),
    path('', views.index, name='index'),
]

Where it all started for me. Honestly, I just want to port this.

I like:

  • Explicit fn call. Prioritizes the path.
  • Linear path matching. No fancy route selection method. Deterministic. Easy to preserve legacy routes.
  • The view type is flexible. Thereā€™s a function and class based view abstraction which lets you define html templates and stuff. You can import url patterns from other ā€œappsā€ or ā€œlibrariesā€ to implement RESTful APIs.
  • Labeled matches and path converters. Maybe path-to-regexp has an alternative.
  • The views donā€™t nest. Nesting is done by templates.

I donā€™t like:

  • Too many view classes. Probably could reduce it to a function or an interface.
  • No component knowledge. The nested urls include() is for managing a lot of paths for a larger application.
  • The views donā€™t nest. The nesting patterns are done via templates.

CLEARLY, I am ambivalent about nested routing patterns.

Copy over code from `bikeshaving/crank/website`?

I need to figure out what runtime code I want to allow users to import.

Thinking out loud.
The Crank.js documentation website is where I am dog-fooding shovel. But thereā€™s also a lot of code there that would be nice have immediately available, e.g. the router and the code for creating front-end builds.

I need to decide: should I make this tool itself front-end framework agnostic? Firewalling specific Crank concerns is an interesting design choice that I have not considered fully for selfish reasons (I want a no-config experience for Crank).

One downside is that I need another layer to create the perfect create-crank-app experience. Naming more things! But the best train to good abstraction is the local.

I think the hardest part to figure out is the router. I feel like routing is important for whatever this tool actually ends up being, and I donā€™t really know if I want that part to be framework agnostic. Concretely, how do we associate paths with view components? I also have to figure out how middleware will work. Maybe that is the solution to this dilemma.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    šŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. šŸ“ŠšŸ“ˆšŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ā¤ļø Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.