V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
bramblex

手撸了一个简单 web 框架,拿来做博客

  •  
  •   bramblex · Feb 24, 2016 · 7750 views
    This topic created in 3724 days ago, the information mentioned may be changed or developed.

    手撸了一个简单 web 框架,拿来做博客

    这两个半个月自己简单手撸了个 web 框架。用得是 PureScript 撸的, PureScript 跟 CoffeeScript 一样是一门 target 到 JavaScript 的语言,虽然 PureScript 从语言本身的设计角度来说比 CoffeeScript 不知道高到哪里去了……但那也架不住 CoffeeScript 简单方便易学大众有生态。

    其实拿 PureScript 手撸这个 web 框架是用来炫技的, PureScript 的强类型纯函数式的特性我觉得真的不太适合应用场景,把本身很简单的事情变复杂了。用 JavaScript / Ruby / Python / PHP 我实现这些东西顶多就两三天。

    》》Github 传送门
    》》LoveAria.Me 博客主站

    下面讲讲我主要做的事情:

    1.SQLite3 的 PureScript Binding ,以及一个简单的 ORM (还是半残状态,连 JOIN 我都没实现好,强类型面对这种场景只能日狗)。

    虽然是自己手撸的……但是放心,注入不了的,本宝宝做了防注入的。

    可以用下面哪种好看的方式做查询了,例如:

    insert "article" [ "title" .= title
                    , "category_id" .= category_id
                    , "raw_content" .= content
                    , "content" .= Markdown content ]
    
    update "article" [ "title" .= title
                    , "category_id" .= category_id
                    , "raw_content" .= content
                    , "content" .= Markdown content] ("id" .== id)
    
    first "article" ("id" .== id .&& "user_id" .== user_id) (Asc "id")
    
    findall "article" ("category_id" .<- [cid1, cid2, cid3]) (Desc "id")
    

    2.一门 HTML 模板 DSL 。因为是 PureScript 的 DSL ,所以其实还是 PureScript 本身。只是语法看上去像一门单独的语言而已, 并且还是有些丑的。

    list :: Array Category.RichArticle -> Template
    list articles = do
      base
      title "Article"
      extend "body" $ do
    
        ifLogined $ \_ ->
          t_a [a_href := "/article/create"] $ text "Create"
    
        article_list articles
    
    article_list :: Array Category.RichArticle -> Template
    article_list articles = do
      t_table [] do
        t_tr [] do
          t_th [] $ text "Id"
          t_th [] $ text "Title"
          t_th [] $ text "Category"
          t_th [] $ text "Create At"
          t_th [] $ text "Update At"
    
          forT articles $ \article -> do
            t_tr [] do
              t_td [] $ text $ show article.id
              t_td [] do
                t_a [a_href := "/article/show/" ++ show article.id]
                  $ text article.title
              t_td []  do
                t_a [a_href := "/article/category/" ++ show article.category.id]
                  $ text article.category.name
              t_td [] $ text article.create_at
              t_td [] $ text article.update_at
    

    3.基础的框架是在 PureScript-Express 上面建立的。所以基本的 handler 处理还是沿用 Express 。

    main :: forall e. ModelApp (console :: CONSOLE | e)
    main = do
      liftEff $ log "Setting up"
      setProp "json spaces" 4.0
    
      useExternal $ MW.bodyParser {extended: false}
      static_path <- liftEff $ Config.static_path
      useExternalAt "/static" $ MW.static static_path
    
      useExternal $ cookieSession {secret: Config.security_key}
      useExternal $ MW.setCookiesMaxAge (3600 * 24 * 30)
    
      use CacheHandler.logger
      use CacheHandler.cacheMiddleware
    
      mount "/" HomeHandler.main
    
      mount "/user" UserHandler.main
      mount "/article" ArticleHandler.main
      mount "/category" CategoryHandler.main
      mount "/cache" CacheHandler.main
    

    4.现在博客的功能基本完善。讲一下框架之上博客的功能:

    1. 文章的增删改,搜索功能还没做,感觉没什么必要做。在下一条讲
    2. 不限制层次的分类。对的,分类就是树状递归结构,不限制层数。你爱几层就几层,跟文件系统的目录类似。用这样的分类来整理文章,我觉得根本没必要搜索了吧。而且我这一辈子能写一千篇高质量的博客不?
    3. 页面缓存。因为 ORM 设计的问题和分类目录递归查询量很大,所以我干脆就直接给他们做了一个 10 分钟的页面缓存。登录成功的用户忽略缓存。成功发布或者修改 文章和分类 会简单全部刷新缓存。

    5.关于前端

    前端方面我准备使用 PureCSS 来做基本的 CSS 框架,然后做一个简洁好看的 UI 。 /w\ 没错,本宝宝就是那么纯( Pure ) 。 JavaScript 部分依旧还是用 PureScript 来做。当然 PureScript 写前端也有些蛋疼,不过我能折腾 /w\。

    啊~ 终于能够好好写东西并且实验奇怪小东西的地方啊啦~

    》》Github 传送门
    》》LoveAria.Me 博客主站

    55 replies    2016-03-01 12:22:42 +08:00
    bramblex
        1
    bramblex  
    OP
       Feb 24, 2016
    估计也没几个人能看懂,太小众的东西哎。 ╮(╯▽╰)╭
    brucefeng
        2
    brucefeng  
       Feb 24, 2016
    说句心里话,不喜欢框架,要造轮子就造个工具吧,框架这种东西限制太多,用起来束手束脚。
    bramblex
        3
    bramblex  
    OP
       Feb 24, 2016
    @brucefeng

    要看您喜欢什么工具咯~
    jarlyyn
        4
    jarlyyn  
       Feb 24, 2016
    说实话,不是看不懂,是不敢回,呵呵呵。
    vagarlee
        5
    vagarlee  
       Feb 24, 2016
    表示小白完全不懂。。。
    flowerains
        6
    flowerains  
       Feb 24, 2016
    看不懂,好厉害的样子( ⊙o⊙?)不懂
    bramblex
        7
    bramblex  
    OP
       Feb 24, 2016
    @jarlyyn

    语言太小众了……
    几乎都没人听过……
    只在 Haskell 圈里面小范围有人知道
    jarlyyn
        8
    jarlyyn  
       Feb 24, 2016
    @bramblex

    语言这东西又不重要。一般的代码要说写可能写不出,看不懂的还是比较少的。

    更何况还是博客这种烂大街的系统。

    首先作为一个框架来说,没有 test 基本属于不可饶恕的。

    其次缓存明显不该强制……

    然后 role 字段放在 user Model 里我个人不是很认同。

    大概看了一圈代码,大概是这些问题吧。
    jarlyyn
        9
    jarlyyn  
       Feb 24, 2016
    @bramblex

    还有

    getHomePage = findArticleById 0

    这个也太脏了吧?

    至少放在 config 里吧……

    或者是我理解错了?
    bramblex
        10
    bramblex  
    OP
       Feb 24, 2016
    @jarlyyn

    您说这些问题确实存在:

    1. 因为自用,所以根本没写 test 。不过 test 可以用 purescript 项目的 test ……虽然麻烦点。
    2. 缓存问题吗……我自己强制的,还是因为自用,没考虑给别人用。
    3. role 字段放在 userModel 里面是不应该的,然而……我这里 role 字段根本没起过作用,只是放在里面看的。
    4. home page 和 一般文章有什么区别吗? /w\ 既然没有,那我就直接扔给 aritcle 处理了,一切以方便出发~
    ChiChou
        11
    ChiChou  
       Feb 24, 2016
    写了框架居然不发红包?
    bramblex
        12
    bramblex  
    OP
       Feb 24, 2016
    @ChiChou 玛德智障
    jsyangwenjie
        13
    jsyangwenjie  
       Feb 24, 2016
    你用纯函数式语言撸这种框架真是蛋疼。。。刚在群里看到。。
    bramblex
        14
    bramblex  
    OP
       Feb 24, 2016
    @jsyangwenjie 对啊……真是蛋疼……不过终于能用了
    learnshare
        15
    learnshare  
       Feb 24, 2016
    特地去搜了一下 PureScript ,看来是 Python style 。
    tabris17
        16
    tabris17  
       Feb 24, 2016
    @learnshare 是函数式吧,老实说,真是继承了函数式语言的最大特性——完全没有阅读性
    bramblex
        17
    bramblex  
    OP
       Feb 24, 2016
    @tabris17

    不能因为看不懂就说没有阅读性啊……
    bramblex
        18
    bramblex  
    OP
       Feb 24, 2016
    @learnshare

    Python sytle 是什么鬼…

    应该说 Haskell sytle , python 是抄 haskell 的,而且还抄得很烂。
    bramblex
        19
    bramblex  
    OP
       Feb 24, 2016
    @tabris17

    我写得不好看只是单纯因为我写得烂而已……
    yuriko
        20
    yuriko  
       Feb 24, 2016
    曾经写过一阵子 haskell ,语言写起来实在麻烦
    bramblex
        21
    bramblex  
    OP
       Feb 24, 2016
    @yuriko

    写起来很爽啊,就是处理这种不知道具体类型的东西要蛋疼一些。不过其实也是可以很简单解决的。比如 Template Haskell ,或者自己造一个语言来生成 Haskell 代码。这些都是很简单的解决方案
    minsheng
        22
    minsheng  
       Feb 24, 2016
    楼主你是 C 写多了还是 C 写多了还是 C 写多了下划线是什么鬼?????
    edsgerlin
        23
    edsgerlin  
       Feb 24, 2016
    好像在知乎看到过 OP 安利 PureScript ……过几年 WebAssembly 普及,只要 GHC 有 LLVM 后端就能直接拿 Haskell 写啦。
    minsheng
        24
    minsheng  
       Feb 24, 2016
    Lib.Utils 是什么鬼东西啊,我虽然不用 PureScript 但是这些东西拿出来专门实现一遍也太鬼畜了吧?

    还有为什么 .js 和 .purs 放在同一个目录下,不是有 pulp 吗?
    minsheng
        25
    minsheng  
       Feb 24, 2016
    @edsgerlin GHC 本来就有 LLVM 后端, GHCJS 也早就理论上可以用了,但是生成文件的体积惨不忍睹
    bramblex
        26
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    是这样的,我自己曾经的语言风格是:
    类——首字母大写驼峰,
    函数 /方法——首字母小写驼峰
    变量——首字母小写下划线

    放在这里面好像不对劲……
    minsheng
        27
    minsheng  
       Feb 24, 2016
    然后楼主打算 type Sql = String 吗?你这是写 Python/NodeJS 呢……
    bramblex
        28
    bramblex  
    OP
       Feb 24, 2016
    @edsgerlin

    那就等普及吧~
    不过即便普及,我觉得 JavaScript 还能作为 target 语言活着。毕竟,你见过范式那么全的大杂烩吗? /w\
    minsheng
        29
    minsheng  
       Feb 24, 2016
    哦,楼上我好像看错了,无视我对 Sql 的吐槽,我来研究一下 Model
    bramblex
        30
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    purescript pures/ js 放在同一目录有问题?我不知道, purescript 的作者就是这样写的。我跟着他做的
    minsheng
        31
    minsheng  
       Feb 24, 2016
    @bramblex 入乡随俗,变量名请统一使用希腊字母,

    cata phi = In . fmap (cata phi) . out

    其它的统一驼峰法咯(逃
    bramblex
        32
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    炫技 / 练手 。至于有没有?

    当然是没什么卵用啊 !
    minsheng
        33
    minsheng  
       Feb 24, 2016
    @bramblex 我又傻逼了,我看成了你生成的 JS ……我就想怎么会犯这么低级的错误。 PureScript 的包我一点都不熟悉还是不看了,我们聊聊为什么不用 Haskell 吧?
    bramblex
        34
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    /w\ 还真可以……

    ```Haskell
    搞 = id
    比利 = id
    (♂) = id

    搞 ♂ 比利
    ```
    minsheng
        35
    minsheng  
       Feb 24, 2016
    @bramblex 来点严肃的吐槽,既然是炫技,你 SQL 还要手工定义 Schema 是不是太麻烦了?我记得最近 PureScript 似乎是支持 Generics 了——虽然 Template PureScript 还是坑,希望今年 GSoC 能加进去——搞个什么根据数据类型自动生成 SQL 操作代码岂不美哉?
    bramblex
        36
    bramblex  
    OP
       Feb 24, 2016
    @minsheng 因为我的 vps 装不进 ghc 。并且我不想折腾交叉编译
    bramblex
        37
    bramblex  
    OP
       Feb 24, 2016
    @minsheng 今年的 GSoc 还真有 Template PureScript 项目……
    learnshare
        38
    learnshare  
       Feb 24, 2016
    @bramblex 因为只见过 Python
    bramblex
        39
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    我想想怎么实现
    minsheng
        40
    minsheng  
       Feb 24, 2016
    @bramblex 好像用不上, PureScript 的 record syntax 比较神奇我不是很熟悉,但看你用得好开心啊。

    GHC 装不进 VPS 是嘛,这个确实是比较严肃的问题,我前段时间真是日了狗了 pandoc 编译 VPS 上死活不成功,结果查了一下 aeson 出了问题,那个版本需要 7GB RAM 才能编译,但是我所有的 Mac 都有这么多内存一点问题都没有……

    对啊对啊,你要不要试试, 5500 刀呢。
    reverland
        41
    reverland  
       Feb 24, 2016
    膜,楼主不是 haskell 大法好嘛
    4679kun
        42
    4679kun  
       Feb 24, 2016
    大神(´゚Д゚`)
    bramblex
        43
    bramblex  
    OP
       Feb 24, 2016
    @minsheng

    我那个 vps 一年 99 RMB ,你指望我能装上 ghc 吗?连硬盘都只有 3G ,装个系统就差不多了,哪里有地方给我装 ghc 嘛 TnT
    bramblex
        44
    bramblex  
    OP
       Feb 24, 2016
    @reverland 这个跟 Haskell 长得差不多
    bramblex
        45
    bramblex  
    OP
       Feb 24, 2016
    @4679kun 活捉~
    scarlex
        46
    scarlex  
       Feb 24, 2016
    下一步就是整合 elm 来写前端了么?
    bramblex
        47
    bramblex  
    OP
       Feb 24, 2016
    @scarlex 正在用 purescript 写前端中 虽然麻烦
    edsgerlin
        48
    edsgerlin  
       Feb 24, 2016
    另外,写后端直接用 Haskell 不好吗……
    bramblex
        49
    bramblex  
    OP
       Feb 24, 2016
    @edsgerlin 我的 vps 只有 3G 硬盘…… ghc 装都装不上。而且我不想折腾交叉编译
    reverland
        50
    reverland  
       Feb 24, 2016 via Android
    @bramblex 我还觉得 js 和 scheme 差不多,真的
    reverland
        51
    reverland  
       Feb 24, 2016 via Android
    @bramblex 你们不去贴吧了么。。
    scarlex
        52
    scarlex  
       Feb 25, 2016
    @bramblex
    我也学过 haskell ,也看过类似 yesod 之类的 web 框架,但在 vps 上面 build 的时候直接报内存不足了。
    不知道在服务器上跑 haskell 的东东最起码要多少内存?
    bramblex
        53
    bramblex  
    OP
       Feb 25, 2016
    @scarlex

    我没有具体了解要多少。据说 8G 够用……
    qqjt
        54
    qqjt  
       Feb 25, 2016
    打不开呀
    bramblex
        55
    bramblex  
    OP
       Mar 1, 2016
    @qqjt 哎,一直都好好的啊?可能是你打开的时候刚好遇到我在升级
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   1072 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 102ms · UTC 18:21 · PVG 02:21 · LAX 11:21 · JFK 14:21
    ♥ Do have faith in what you're doing.