Coder Social home page Coder Social logo

fard2's Introduction

fard logo

fard NPM version NPM downloads QQ

fre 转小程序的新思路 ♂ learn once, write anywhere.

工作日只处理 issue,节假日迭代~

Package Version About
Fard npm fard core
fard-webpack-plugin npm webpack plugin

Usage

import { useState } from 'fre'
import { h, render } from 'fard'
import './index.styl'

function App() {
  const [count, setCount] = useState(0)
  return (
    <view>
      <text>{count}</text>
      <button onClick={() => setCount(count + 1)}>+</button>
    </view>
  )
}

render(<App />)

以上,由于小程序不支持 babel 和 stylus,所以仍然需要借助 webpack

完整的 demo 用例在这里:webpack-demo

hooks

所有 fre 的 hooks API 都是支持的

hooks 相关行为都发生在 fre 层,和小程序无关,不做赘述,请移步:fre readme

api & context

fard 提供 api 对象,用来抹平各个端的差异

import { h, render, api, context } from 'fard'

function App() {
  const toJack = () => {
    api.navigateTo({
      url: '../user/user?name=jack',
    })
    console.log(context)
  }
  return (
    <view>
      <button onClick={toJack}>+</button>
    </view>
  )
}

render(<App />)

如上,api 等同于 wx、my、tt、swan,会根据环境自行更换命名空间

context 是 this 实例

setup

有时候,我们需要自定义一些方法,比如生命周期,和小程序的默认事件

此时需要用到 render 的第二个参数

const setup = {
  onReady() {
    //生命周期
    console.log('onReady……')
  },
  onShareAppMessage(res) {
    //微信自带的方法
    return {
      title: '转发',
      path: '/pages/index/index',
      success(res) {
        console.log('成功', res)
      },
    }
  },
}

render(<App />, setup)

注意,只有根组件和原生组件拥有生命周期,而内置的 fre 组件,请使用 useEffect

fard-webpack-plugin

借助 webpack,还可以顺便做一些构建的工作,如 生成 template bridge复制小程序的配置文件

fard-webpack-plugin 是 fard 唯一一个额外的插件,用来包办 webpack 相关

const FardWebpackPlugin = require('fard-webpack-plugin')

plugins: [
  new FardWebpackPlugin(),
]

template bridge

经过 fard-webpack-plugin 声称的 bridge.wxml 是用来桥接的文件,无需关注其内容

我们只需要在我们每个 page 的 wxml 引用它即可:

<fard vdom="{{vdom}}">

写死的,不用修改

原理

fard 之所以称之为新思路,是因为它不同于其他编译型框架,它的原理和 RN 类似,是比较好的跨端方案

如图:

它通过 bridge 来桥接 fre 和小程序的 vdom,是在小程序里跑 fre 而不是将 fre 编译成小程序

另外,fard 还在 setData 之前做了一层 diff/防抖/压缩 三连,性能靠谱

这里有一篇详细的文章:fard:fre 转小程序的新思路

How to contribute

Since fard use monorepo managed by lerna you should install lerna at first.

npm i -g lerna

Then install all dependencies:

lerna bootstrap

For example run these commands if you'd like to run fard-demo with Webpack:

cd packages/demo-webpack
yarn start

Contributors

License

MIT

fard2's People

Contributors

malash avatar yisar avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

fard2's Issues

使用生命周期替代 useEffect

由于 fre 的 useEffect 是发生在 dom 操作后,而小程序是没有 dom 操作的
从语意上讲,也不适合使用 effect 关键词

但是 fard 的每一个节点都是一个 fard 组件,小程序的组件是有生命周期的,它可以用来替代 useEffect

小程序自定义组件的生命周期主要有两个方法

lifetimes: {
    attached: function() {
      // 在组件实例进入页面节点树时执行
    },
    detached: function() {
      // 在组件实例被从页面节点树移除时执行
    }
  }

在 fard 中,通过 props 进行传递:

const attach = ()=> console.log('load...')
<Header onAttach={attach} />

这周需要搞的

  1. fardwp : 增加自动入口和自定打包name.wxml
  2. bridge 更换为自定义组件实现

在小程序中使用 htm 替代 jsx 的思路

如题,htm 是一个 jsx-like 的小库,目标是脱离 webpack 编译,直接用于浏览器环境

https://github.com/132yse/fre/blob/v0.1/src/html.js

很久以前我抄过一个版本,从源码来看,是使用 tmplate + innerHtml + replace 进行 AST 转译

这在浏览器环境仿佛不是刚需,但是!

对于小程序而言,就是救命……

目前的小程序开发工具不支持热更新,只会自动重载,如果这个时候再去加一层 webpack 的话

不仅仅重载慢,调试还非常困难,毕竟小程序这玩意,不是纯 js 的

所以我在想办法将 htm 移植到小程序环境,从而脱离编译

目前想到的方案:使用 rich-text 组件

<block>
    <rich-text nodes="{{content}}" type='text'></rich-text>
</block>
this.setData({
     content: content.replace('...', '...')
}

如上,rich-text 相当于 template,setData 相当于 innerHtml

最新的 block tree 方案

之前停更的原因:自定义组件递归的一些坑
我给微信小程序社区提了需求,要求支持递归,然后他们没能采纳

然后发布了他们的类似思路的框架:kbone

仍然没能突破限制,这很绝望

这个问题暂时来说是无解的

03

他们的方案是,限制死了一个层级数,然后超过这个层级数会包一层 自定义组件
这就好像是 fard 第一个版本和第二个版本的结合体

说实话,仍然不是个好的方案,因为还是有限制的
我仍然期待着他们支持递归

使用自定义组件作为 bridge 的坑

由于微信不支持 view 的递归,以及 template 可能存在的性能问题
决定改为自定义组件

但是现在有两个问题:

  1. 样式穿透问题
    不知道为什么,addGlobalClass 无效,考虑是 web-component 的样式执行顺序导致
    暂时没找到问题所在

  2. 函数传递
    fard 是将 onClick 这种事件,挂到 page 上的,但是现在使用自定义组件,要求必须是挂到 component 上

所以考虑王全局上挂

bug 收集

  1. hook 会执行两次
  2. useEffect 没有执行时机
  3. 字符串的 diff

fard 性能提升的思路

当前版本的 fard 的某个环节是将整个 vdom 树进行更新的,这样性能堪忧
后来得知 mpvue 也有这个问题

目前能想到的解决方案,就是在更新之前先做一层 diff,寻找到最小更新的数据和最少更新的次数
比如

let oldVdom = {
  type: 'view',
  props: {
    class: 'item'
  },
  children: [
    {
      type: 'text',
      props: {},
      children: []
    }
  ]
}

let newVdom = {
  type: 'view',
  props: {
    class: 'wrap'
  },
  children: [
    {
      type: 'view',
      props: {},
      children: []
    }
  ]
}

const out = diff(oldVdom, newVdom)

很幸运的是,setData 支持传递 json,所以 out 产生的结果是一个 json 对象

{
  "props.class": "wrap",
  "children[0].type": "view"
}

生成 diff 结果的同时,还应该对 vdom 进行改造,由于小程序的 template 不支持同标签的递归,所以只好手动打上层级标记

newVdom =  {
  type: 'view0',
  props: {
    class: 'wrap'
  },
  children: [
    {
      type: 'view1',
      props: {},
      children: []
    }
  ]
}

以上,就是目前方案对于性能提升的思路,同时利用好这次遍历,做更多事情

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.