GithubHelp home page GithubHelp logo

nervjs / nerv Goto Github PK

View Code? Open in Web Editor NEW
5.4K 5.4K 267.0 1.76 MB

A blazing fast React alternative, compatible with IE8 and React 16.

Home Page: https://nerv.aotu.io

License: MIT License

JavaScript 75.06% HTML 0.19% TypeScript 24.33% CSS 0.41%
framework frontend inferno javascript jsx nerv nervjs preact react reactjs typescript vdom virutal-dom

nerv's People

Contributors

abdullah avatar bless-l avatar coffeehc avatar danielruf avatar dawsbot avatar dependabot[bot] avatar diamondyuan avatar littly avatar luckyadam avatar michaelbenin avatar sebring avatar spacemeowx2 avatar tombyrer avatar yaodingyd avatar yoyo837 avatar yuche 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  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

nerv's Issues

关于使用nerv前的些许小疑问

各位nerv开发大佬你们好。

SSR

我看到有提供nerv-server包,提供了字符串模板输出(包括Prefetching这些?)。
但如果用next.js也没问题吧。

路由

路由是沿用社区react-router,还是说后期你们会出一个官方nerv-router?

性能

目前nerv应用在了jd.com,我看源码是服务端渲染+客户端交互渲染?
需要写两份代码吗,server/clinet各一份?
还是说nerv ssr方案自带组件反解?

希望大佬能百忙之中抽空解答,不胜感激。

与react-router配合使用, hashchange时页面无反应

表现为 点链接 hashchange 了, 但页面没变化; 但此时F5刷新,能渲染指定路由

另开issue放代码. 代码是常见的 react 结构: index 是entry, 它引入 app 并渲染; app引入了router和两个组件 hello和about, 组合后导出

Hello.jsx

import Nerv from 'nervjs'

class Hello extends Nerv.Component {
    constructor() {
        super(...arguments);
        this.state = {
            message: 'world'
        }
    }
    render() {
        return (
            <div>
                Hello, {this.state.message}
            </div>
        )
    }
}

export default Hello

About.jsx

import Nerv from 'nervjs'

export default function About() {
    return <div>me, <span className="red" style={{'color':'red'}}>red</span></div>
}

App.jsx

import Nerv from 'nervjs'
import { HashRouter as Router, Route, Link } from 'react-router-dom';

import Hello from './Hello';
import About from './About';
// import Topics from './Topics';

const App = () => (
    <Router>
        <div>
            <div className="header">
                <nav>
                    <ul>
                        <li><Link to="/">Home</Link></li>
                        <li><Link to="/about">About</Link></li>
                        <li><Link to="/topics">Topics</Link></li>
                    </ul>
                </nav>
            </div>
            <hr />
            <Route exact path="/" component={Hello} />
            <Route path="/about" component={About} />
            {/* <Route path="/topics" component={Topics} /> */}
        </div>
    </Router>
);

export default App

index.jsx

// require('es5-polyfill')
import Nerv from 'nervjs'
import App from './App'

Nerv.render(<App />, document.getElementById('app'))

如有需要, 我再提供 webpack.config.js , 也是初级代码. 对了, 我用的 webpack最新版:
"webpack": "^4.4.1",
"webpack-cli": "^2.0.13",
"webpack-dev-server": "^3.1.1"

How does Nerv's server side rendering performance compare to React & Next.js?

Hi,

In Nerv's website there are a few benchmarks comparing its performance to that of React & a few other frameworks. Looks like those are all benchmarks for client-side rendering.

What is Nerv's performance in server-side rendering? Especially when compared to React & Next.js? Any benchmarks available?

Thanks.

Website appears broken

When visiting:

https://nerv.aotu.io/

with:

FF 57.0.3 (macOS High Sierra)
Chrome 63.0.3239.84 (macOS High Sierra)

Marker texts such as 'size_desc' where one would expect actual text to be present.

No errors in console.

If I click on the paging dot of the examples carousel I get:

ReferenceError: event is not defined
index.js:1:775917
t/e.switchCode      https://nerv.aotu.io/js/index.js:1:775917
onClick                   https://nerv.aotu.io/js/index.js:1:780157
e                             https://nerv.aotu.io/js/index.js:1:40029
i                              https://nerv.aotu.io/js/index.js:1:39903

Missing `react-dom/server`

I believe for nerv to be a true drop-in replacement it would have to implement the equivalent of react-dom/server:

image

unkeyed children diffing error causes component lifecycle event to fire unexpectedly

test case

Click two buttons
Expected: console log should only has "updated"
Results: Console log gets "mounted" and "unmounted".

Basically, if parent component B has unkeyed children, and there are children add/remove before child component A, even though the changed child is not a component A, A still gets mounted/unmounted, because unkeyed children are diffed in sequential order.

In the Inferno way, it has normalized VNode so if key is not set, it might use children order and null is considered a child too, so child component always has the same normalized key, thus gets the correct diffing results.

Make this independent from NPM, webpack and bundlers

I have been trying to build a react development environment with zero NPM and bundler dependency.
So far I was able to use nerv source code with minimal changes. It only needs TypeScript to transpile tsx files to js. The goal is to use browser's ES2015 modules support, at least for development time.

This repo works in Chrome 63:
https://github.com/malekpour/nopack

I copied nerv source files in the src/external folder and the only thing I had to change was adding .js extension to import statements.

// import { render } from './render'
import { render } from './render.js'

Ideally we should be able to reference ES2015 libraries from CDN's just like what we used to do for jQuery or Angular 1.

直接切换react项目会报错

只需要在 alias 把 nervjs 和 react、react-dom 关联起来即可:

{
  resolve: {
    alias: {
      'react': 'nervjs',
      'react-dom': 'nervjs'
    }
  }
}

报错
image

Incompatible with React bootstrap 3

When we launch a React web app with react bootstrap, it doesn't works because react-bootstrap can't get the react version.

Console return this error "TypeError: Cannot read property 'split' of undefined" and debug tool show error in utils.js:50 of uncontrallable dependency of react-bootstrap.

Thanks

How to switch Typescript based React project to Nerv

Not just switch, the question starts when creating a new project based on Typescript.

If the original project use libraries like react-router, it will depends on .d.ts file from React. In javascript world this won't be a problem cause there's no strong typed definition force you to follow the right type, but Typescript will not work.

Is there any way to get around this in practice? To gain the benefit both from strong typed language(with better Intellisense and much more) and performance from Nerv.

Thought you guys may have encountered this problem when actually working on Nerv because the source codes are written in Typescript.

Global detection hurts isomorphic rendering

require('nervjs') throws in Node.js:

Error: unable to locate global object
    at /Users/rauchg/Projects/next-news/node_modules/nervjs/dist/index.js:17:11
    at Object.<anonymous> (/Users/rauchg/Projects/next-news/node_modules/nervjs/dist/index.js:18:2)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Module.require (module.js:604:17)
    at require (internal/module.js:11:18)

I had to work around it by manually setting self = this.

is there a better way? making it work with cerebral

I perf Nerv with the other frameworks using it on top of Cordova and i really like what I see.
I also use Cerebral for my state management, which took me sometime to get it to work. After a while I got it to work with this hack.

https://github.com/andrewvmail/momoboiler/blob/master/src/entry.js#L58

The cerebral/react binding code is here
https://github.com/cerebral/cerebral/blob/next/packages/node_modules/%40cerebral/react/src/Hoc.js#L76

Nerv reactcreate element output signature is slightly different than the react counterpart. props is inside the vnode.props so i use the hack to make that work.

just wondering if the Nerv team have any thoughts on this, perhaps a less hacky way of getting this to work?

Thanks!

做了个简单demo,nerv+nextjs跑不起来

//.babelrc配置
"plugins": [
    [
      "transform-react-jsx",
      {
        "pragma": "Nerv.createElement"
      }
    ],
    [
      "module-resolver", 
      {
      "root": ["."],
      "alias": {
          "react": "nervjs",
          "react-dom": "nervjs",
          "create-react-class": "nerv-create-class"
      }
    }]
  ]

// page/index.js
import React from 'react'

export default () => <div>Welcome to next.js!</div>

1516986826288

Missing createFactory API

Although nervjs explicitly stated that createFactory is not supported currently, it is quite an important top level API which is required by recompose which is further required by many hoc libraries

Material ui components - Unsupported VNode

Using Material ui components does not work with nervjs.

Steps to reproduce:

  • Create an app with create-react-app
  • Replace any calls to react with nervjs
  • Install the material-ui package
  • Try to use any component like:
import React, { Component } from 'nervjs'
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider'
import ActionHome from 'material-ui/svg-icons/action/home'

const App = () => (
  <MuiThemeProvider>
    <ActionHome />
  </MuiThemeProvider>
)

The error will be like:

Error: Unsupported VNode.
▶ 15 stack frames were collapsed.
./src/index.js
src/index.js:8
   5 | import registerServiceWorker from './registerServiceWorker'
   6 | import './index.css'
   7 | 
>  8 | render(<App />, document.getElementById('root'))
   9 | registerServiceWorker()
  10 | 
  11 | 
View compiled
▶ 6 stack frames were collapsed.

I tried to debug this but got nowhere...

Messing with my code I got it to render but the test in jest fails and it does not render the paths for the SvgIcon.
It renders:

<svg __source="[object Object]" __self="[object Object]" viewBox="0 0 24 24" style="display: inline-block; color: rgba(0, 0, 0, 0.87); fill: currentcolor; height: 24px; width: 24px; user-select: none; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;"></svg>

Instead of:

<svg viewBox="0 0 24 24" style="display: inline-block; color: rgba(0, 0, 0, 0.87); fill: currentcolor; height: 24px; width: 24px; user-select: none; transition: all 450ms cubic-bezier(0.23, 1, 0.32, 1) 0ms;"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"></path></svg>

as react does.

Hydration Removing All Children

The hydrate function seems to be removing all children indiscriminately.

hydrate.ts#L4-L16

The ReactDOM version of hydrate works by hydrating the existing markup, attempts to attach event listeners to the existing markup and fixes mismatched text content where appropriate.

ReferenceError: global is not defined when trying to do server render

So I have a small preact application and I wanted to replace preact with nerv. After aliasing react and react-dom I replaced render import from preact-render-to-string to nerv-server and started bundled application (I am bundling server code as well, so my file loaders works as expected)... and the server crashed on this:

const global = (function () {
    // the only reliable means to get the global object is
    // `Function('return this')()`
    // However, this causes CSP violations in Chrome apps.
    if (typeof self !== 'undefined') {
        return self;
    }
    if (typeof window !== 'undefined') {
        return window;
    }
    if (typeof global !== 'undefined') {
        return global;
    }
    throw new Error('unable to locate global object');
})();

with

if (typeof global !== 'undefined') {
    ^

ReferenceError: global is not defined

The code is from installed nerv-server/dist/index.js

I was surprised at first (crashing on typeof), but well, look at this:

const a = (() => {
   console.log(typeof a)
})();

If you paste this into browser console it will always fail, because you're trying to get value of a while evaluating its value.

I have no idea how this can work anywhere and get to the "unable to locate ..." error, however I saw an closed Issue that was just about unable to locale being thrown.

Do you have any example repos with server-side rendering, so I can look closer how to do that properly. As my typical React/preact configuration seems not to work here.

Document build process

I see that there is documentation on various webpack/babel configuration but the building process is missing from documentation. Wouldn't it be better if there's a couple of paragraphs added to the docs to go over the build process?

根据快速开始和github的readme一路走来,发现的一些问题

第一时间 star 了 nerv, 然后近两天有空, 打算试用一下.

快速开始的一些问题

1.在.babelrc配置了"pragma": "Nerv.createElement"后

则每个Component.jsx需要引入 Nerv, 否则编译时会报 Nerv is not defined. 比如以下纯文字组件:

import Nerv from 'nervjs' //必须, 因为 return 后的语句实际上转成了 Nerv.createElement(xxx)
export default function About() {
    return <div>me, <span className="red" style={{'color':'red'}}>red</span></div>
}

按正常逻辑, 其实上面这个组件完全用不着 import 什么

readme 中的一些问题

1. es5-polyfill无用

install后, require('es5-polifill')报找不到, 查看一下 es5-polyfill 包, 发现其根目录下没有任何JS文件(而是放在了dist下),导致其无法被 require

这就让readme里提到的兼容IE8的路断了(当然, 改一下 es5-polyfill包可以解决)

2. .babelrc 配置 preset-es3报错

配置后编译会报 Error: Plugin/Preset files are not allowed to export objects, only functions. 初步估计是 babel 8.0 beta版与preset-es3的兼容问题 (话说我也不知道为什么快速开始里要使用 babel beta版)

使用过程中

1, 配合 react-router

出现奇怪问题: 点击链接路由跳转 (hash变了),但页面并没有加载出对应路由的内容; 此时按f5刷个新, 能正常载入对应路由

将组件完全复制到 react 项目, 只是替换 Nerv 为 react, 则页面完全正常

以上问题最严重的是 react-router 问题, 没法继续开发了 💥

希望更新下文档, 在IE8 兼容方面详细准确一些

nerv-test-utils package is missing files

I tried to install nerv-test-utils to replace react-dom/test-utils but it seems that the package does not contain all of the source files. The index.js tried to require ./src/index.js but the entire src folder is excluded from packaging in .npmignore.

关于对ie8下面 onpropertyChangeEvent全局性处理的疑问

先贴下代码:

function processOnPropertyChangeEvent (node, handler) {
propertyChangeActiveHandler = handler
if (!bindFocus) {
bindFocus = true
doc.addEventListener(
'focusin',
() => {
unbindOnPropertyChange()
bindOnPropertyChange(node)
},
false
)
doc.addEventListener('focusout', unbindOnPropertyChange, false)
}
}

  1. 为什么190行需要把单个input的onchange事件绑定到一个全局的propertyChangeActiveHandler上面去?
  2. 191-192行 ,为什么用bindFocus这个变量让onchange事件只能绑定一次,这个样在一个表单里面,有多个input的时候,只有一个input的onchange是生效的.

不太明白为什么要做这个样的处理,这个明显会导致form在ie8下面失效,想不明白,
望解答

有支持ie8的路由吗

nerv支持ie8,使用的react16,与之配套的react-router4 ,不支持ie8
如果使用react-router3,由于使用的是react16,又不与之兼容
这样就开发不了多页面应用啦~

有支持ie8与之配套的前端路由推荐吗

diff 算法原理概述

  1. 找到相同的前置元素和后置元素
     *
     *  A: -> [a b c d] <-
     *  B: -> [a b d] <-
     *

这里我们可以发现前置元素 a, b 和 后置元素 d 都是相同的。所以我们可以将这样的 diff 情况转变为:


     *
     *  A: -> [c] <-
     *  B: -> [] <-
     *

这里我们可以发现 A 和 B 的不同就是多了一个 c 元素,所以只要进行把 c 元素移除这一步可以完成 diff。相反地,如果这步操作 A 为空,B 有多余元素,那么我们就将多余元素插入即可。
这一步 diff 优化最早由 Neil Fraser 提出,实现非常简单(在 Neil 的文章里他提供了 JavaScript,Java,Python 三种实现),优化的力度也非常大,但真正首次应用到前端框架却是十年后的 Bobril,后来号称性能最强的 Inferno 也使用了这一优化。

再来看下一种情况:


     *
     *  A: -> [a b c d e f g] <-
     *  B: -> [a c b h f e g] <-
     *

在这个情况的 diff 中,我们可以应用之前的优化策略把他简化为:

     *
     *  A: -> [b c d e f] <-
     *  B: -> [c b h f e] <-
     *
  1. 这时候我们就需要进行第二步:找到需要被删除、插入或移动的元素:

首先我们创造一个数组 P,它代表新数组应该被插入的位置。

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *  P: [. . . . .] // . == -1
     *

接下来我们再创建一个索引 I,作为新数组位置的映射(如果新旧数组都很小的话,那我们直接遍历数组即可,反之我们需要一个索引):

     *
     *  A: [b c d e f]
     *  B: [c b h f e]
     *  P: [. . . . .] // . == -1
     *  I: {
     *    c: 0,
     *    b: 1,
     *    h: 2,
     *    f: 3,
     *    e: 4,
     *  }
     *  last = 0
     *

有了数组 P 和 索引 I 之后,现在我们可以开始遍历旧数组

 *
 *  A: [b c d e f]
 * 	^
 *  B: [c b h f e]
 *  P: [. 0 . . .] // . == -1
 *  I: {
 *    c: 0,
 *    b: 1, <-
 *    h: 2,
 *    f: 3,
 *    e: 4,
 *  }
 *  last = 1
 *

第一步遍历我们可以发现旧数组的 b 元素也在新数组上,所以我们把他在旧数组的位置 0 放到他在数组 P 相对应的位置上。

这里我们同时还要维护一个变量 last,它代表访问过的节点在新集合中最右的位置(即最大的位置)。如果新集合中当前访问的节点比 last 大,说明当前访问节点在旧集合中就比上一个节点位置靠后,则该节点不会影响其他节点的位置,因此不必执行移动操作。只有当访问的节点比 last 小时,才需要进行移动操作。

 *
 *  A: [b c d e f]
 * 	  ^
 *  B: [c b h f e]
 *  P: [1 0 . . .] // . == -1
 *  I: {
 *    c: 0, <-
 *    b: 1,
 *    h: 2,
 *    f: 3,
 *    e: 4,
 *  }
 *  last = 1 // last > 0; moved = true
 *

这里我们访问元素 c 的位置为 0,而 last 为 1,所以我们需要进行移动操作。

这一步实际上也是 React Stack Reconciler(React 16 以下)的核心算法:每次遍历的时候把当前节点在旧集合的位置和 last 进行对比,如果 mountIndex 大于 last,那么就把他添加到差异队列,然后更新 last,全部遍历完毕之后再遍历差异队列,一步一步进行 patch。

(这里如果理解有障碍的话建议把常规的排序算法都撸一遍,可以重点看选择排序和插入排序)

 *
 *  A: [b c d e f]
 *          ^
 *  B: [c b h f e]
 *  P: [1 0 . . .] // . == -1
 *  I: {
 *    c: 0,
 *    b: 1,
 *    h: 2,
 *    f: 3,
 *    e: 4,
 *  }
 *  moved = true
 *

这里元素 d 在新数组当中并不存在,所以它应该被移除掉。

 *
 *  A: [b c d e f]
 *            ^
 *  B: [c b h f e]
 *  P: [1 0 . . 3] // . == -1
 *  I: {
 *    c: 0,
 *    b: 1,
 *    h: 2,
 *    f: 3,
 *    e: 4, <-
 *  }
 *  moved = true

这里把元素 e 在旧数组的位置(3)放到数组 P 上。

 *
 *  A: [b c d e f]
 * 	        ^
 *  B: [c b h f e]
 *  P: [1 0 . 4 3] // . == -1
 *  I: {
 *    c: 0,
 *    b: 1,
 *    h: 2,
 *    f: 3, <-
 *    e: 4,
 *  }
 *  moved = true
 *

这里把元素 f 在旧数组的位置(4)放到数组 P 上。

到了这一步,如果是 React 的算法已经走完了。但不妨思考以下的 diff 情况:

 *
 * A: [a b c d]
 * B: [d a b c]
 *

这里肉眼一看就知道,把旧集合的 d 元素移动到 0 这一步操作就可以完成 diff。但根据前文所述的逻辑走一次,实际上 React 会先把 a, b, c 移动到他们的相应的位置 + 1,一共三步操作。

移动操作也并不是没有副作用,仍然可能会重启动画,focus 丢失,重置滚动条位置等。所以我们还可以进行下一步优化:

  1. 找到最小的移动次数。

这里我们需要找到 P 数组的[最长递增子序列(longest increasing subsequence)] 来做动态规划,新集合中不属于这个序列的将会被移动。

还是用我们之前的例子:

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *  P: [1 0 . 4 3] // . == -1
 *  LIS:     [1 4]
 *  moved = true
 *

这里我们同时尾部遍历新数组和 LIS 序列,查看元素的位置是否能与 LIS 序列的任何一个值匹配。

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *              ^  // new_pos == 4
 *  P: [1 0 . 4 3] // . == -1
 *  LIS:     [1 4]
 *              ^  // new_pos == 4
 *  moved = true
 *

这一步能匹配,e 可以呆在它原来的位置上。

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *            ^    // new_pos == 3
 *  P: [1 0 . 4 3] // . == -1
 *  LIS:     [1 4]
 *            ^    // new_pos != 1
 *  moved = true
 *

f 的位置不能匹配,把他移动到 e 之前。

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *          ^      // new_pos == 2
 *  P: [1 0 . 4 3] // . == -1
 *          ^      // old_pos == -1
 *  LIS:     [1 4]
 *            ^
 *  moved = true
 *

h 的位置为 -1,把他插入。

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *        ^        // new_pos == 1
 *  P: [1 0 . 4 3] // . == -1
 *  LIS:     [1 4]
 *            ^    // new_pos == 1
 *  moved = true
 *

b 能匹配 LIS,可以老老实实呆着。

 *
 *  A: [b c d e f]
 *  B: [c b h f e]
 *      ^          // new_pos == 0
 *  P: [1 0 . 4 3] // . == -1
 *  LIS:     [1 4]
 *          ^      // new_pos != undefined
 *  moved = true
 *

c 不能匹配,把它移动到 b 之前。

走完这一步我们的 diff 算法就完毕了。

这时回头再来看看之前把尾部元素插入到头部的情况,React 需要经过 3 次操作,而经过我们动态规划之后:

 *
 - A: [a b c d]
 - B: [d a b c]
 - P: [3 0 1 2]
 - LIS: [0 1 2]
 *

可以发现 a, b, c 能匹配 LIS,可以呆到天荒地老,我们只要把 d 移动到头部的位置就可以完成 diff。Perfect!

详细代码:
https://github.com/NervJS/nerv/blob/patch/packages/nerv/src/vdom/patch.ts

maybe a React compatibility problem

image
I want to replace React to nerv i clojurescript react binding regent, but with errors

{:source-paths ["src"]

 :dependencies [[reagent "0.8.0-alpha2"]]

 :builds {:app {:target :browser
                :js-options
                {:resolve
                 {"react" {:target :npm
                           :require "nervjs"}}
                 {"react-dom" {:target :npm
                               :require "nervjs"}}
                 {"create-react-class" {:target :npm
                                        :require "nerv-create-class"}}}
                :output-dir "public/js"
                :asset-path "js"
                :modules {:main {:entries [starter.core]}}
                :devtools {:before-load starter.core/stop
                           :after-load starter.core/start
                           :http-root "public"
                           :http-port 8020}}}}

if need more info, please comment

[RFC]: 使用 lerna 重构组织项目结构

现在 Nerv 和 preact 一样,compat, ssr, redux, test-utils 等分开在不同的仓库。这些天的开发目前有几个痛点:

  1. 有时候多个组件同时依赖一些内部方法,例如 isWidget(),导致每个仓库都要维护一份这个方法。同时打包出来也每个包都有一个;
  2. 当 Nerv 更新时不能确定其他下属包还能不能兼容;
  3. 同时开几个项目时编辑器转来转去太麻烦;
  4. 各个包依赖基本都是相同的,有时候依赖包出问题或者要更新(例如修改.babelrc)又要几个包分开更新

Lerna 就能很好地解决这些问题,除上述问题之外还提供 change log 自动生成的功能和统一管理 semver,这样多人维护和解决历史 bug 就可以少翻 commit history 和 git blame 了。

现在三大框架 react, angular, vue 和一些大型前端项目例如 babel 也都在用,至少看起来也专业不少。另外这样也能 star 聚拢起来而不是分散到各个 repo,万一我们火了呢 :)

Adds node instead of replacing

I found a weird bug and I'm not sure what the cause is.

I have the following code:

<div id="app">
	<Header location={this.state.location} />
	<main className="d-flex justify-content-center">
		<HashRouter onLocationChanged={this.handleLocationChanged}>
			<Route key="liked" hash="#/">
				<Liked />
			</Route>
			<Route key="saved" hash="#/saved">
				<Saved />
			</Route>
			<Route key="about" hash="#/about">
				<About />
			</Route>
		</HashRouter>
	</main>
</div>

HashRouter render function:

return this.state.render

In the state, only one child is saved (double checked with console.log and dev tools). However, when I render a different component (so to say, a route change is happening), this happens:
screenshot_6

So it seems Nerv is adding the component/a Node to the DOM instead of replacing it. Both <Liked /> and <About /> render a <div>, the latter one with className="...".

Code is here: https://github.com/kurtextrem/Improved-for-Instagram/blob/master/src/components/HashRouter.js#L152 / https://github.com/kurtextrem/Improved-for-Instagram/blob/master/src/components/app.js#L44

What's the tradeoff?

The readme and website make a bunch of extraordinary claims ("same api, much faster, better browser compat, smaller bundle size"), but what are the tradeoffs of choosing Nerv vs vanilla React? What do I miss when I choose Nerv?

Note: Not trying to be a pain in the butt here, genuinely curious why React wouldn't just take this code base and make it their own

nerv-devtools error!!!

nerv-devtools always works well ,but when add the react-router-dom , it is error !

TypeError: Cannot read property 'type' of null
createReactDOMComponent
E:/demos/ReactApp/nerv-app/node_modules/nerv-devtools/dist/index.esm.js:74

71 | _currentElement: isText
72 | ? vnode.text
73 | : {
74 | type: vnode.type,
75 | props: normalizeProps(vnode.props)
76 | },
77 | _renderedChildren: normalizeChildren(vnode.children),

Testing framework

Hi there,

I've just started playing around with Nerv and I wanted to implement Jest as the testing framework but I'm running into some issues: The webpack dev server running into a compilation error.

My package.json looks like this:

"scripts": {
    "dev": "webpack-dev-server --config webpack.config.js --mode development --port 8888",
    "test": "jest",
    "test:watch": "jest --watch"
  },
  "dependencies": {
    "nervjs": "^1.2.15"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.42",
    "@babel/plugin-transform-react-jsx": "^7.0.0-beta.42",
    "@babel/preset-env": "^7.0.0-beta.42",
    "babel-core": "^6.26.0",
    "babel-jest": "^22.4.3",
    "babel-loader": "8.0.0-beta.0",
    "babel-plugin-transform-react-jsx": "^6.24.1",
    "babel-preset-env": "^1.6.1",
    "babel-preset-react": "^6.24.1",
    "html-webpack-plugin": "^3.0.7",
    "jest": "^22.4.3",
    "nerv-devtools": "^1.2.15",
    "react-test-renderer": "^16.2.0",
    "regenerator-runtime": "^0.11.1",
    "webpack": "^4.2.0",
    "webpack-cli": "^2.0.12",
    "webpack-dev-server": "^3.1.1"
  }

My babelrc is:

{
  "presets": [
    [
      "env",
      {
        "spec": true,
        "useBuiltIns": false
      }
    ]
  ],
  "plugins": [
    [
      "transform-react-jsx",
      {
        "pragma": "Nerv.createElement"
      }
    ]
  ]
}

And my webpack.config.js is:

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: './index.html'
    })
  ]
}

After I finished the getting started guide on Jest, by installing a couple of dependencies, yarn add --dev babel-jest babel-core regenerator-runtime, the webpack dev server started to error: ERROR in ./src/App.js Module build failed: TypeError: Cannot read property 'bindings' of null

image

Bug: as per React it should be possible to change roots

NervJS:
https://codesandbox.io/s/m31owy1wvj (link fixed)

React: ( See console logs )
https://jsfiddle.net/a2ay2fh6/

expected result: Nerv should be able to change root nodes.
For more tests on similar manner see Inferno test cases here:
https://github.com/infernojs/inferno/blob/master/packages/inferno-create-element/__tests__/components.spec.jsx#L2528-L3219

Hopefully you find good way to fix this :) So we can improve inferno too. Inferno currently updates vNode parents after setState to have this working + cloning vNodes before patching.. Which has obvious effect in performance

Server-side rendering is crashing with react-inform

I am using 1.2.4-beta.1

When I am using react-inform and nerv-server - it crashes the render.

state.values seems to be undefined, so values[name] is crashing in this file: https://github.com/theadam/react-inform/blob/master/src/form.js

However when I render this in browser - everything is working as expected.

I'm not using anything fancy with react-inform so you should be able to reproduce this with basic example, but if not - I may try to isolate the issue out of my project and make a repo out of it.

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.