Giter Site home page Giter Site logo

infernojs / inferno Goto Github PK

View Code? Open in Web Editor NEW
16.0K 16.0K 635.0 41.61 MB

:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Home Page: https://infernojs.org

License: MIT License

JavaScript 99.50% HTML 0.46% CSS 0.04%
inferno inferno-component inferno-js javascript-library jsx performance react vdom

inferno's People

Contributors

abazhenov avatar aretecode avatar craigmichaelmartin avatar davedbase avatar deamme avatar doytch avatar greenkeeperio-bot avatar gwenio avatar havunen avatar hbstone avatar jhsware avatar kanzelm3 avatar longlho avatar lucasavila00 avatar lukeed avatar lukesheard avatar marudor avatar marvinhagemeister avatar mciparelli avatar mstijak avatar nightwolfz avatar nykula avatar rtsao avatar schnueggel avatar srolel avatar tejacques avatar terinjokes avatar trueadm avatar wagerfield avatar wasd171 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

inferno's Issues

[Q] License

One of the issues my employers always have with React is the license issue and Facebook seems unwilling to go back to Apache. To date, I've used open source virtual-dom libraries to build apps where React would have worked.

Inferno looks like a great alternative (and possibly a better one) but you have a default "ISC" mentioned in the package.json and no license file. Is your intention to open source this?

state change in parent component will not reflect props value change in children's JSX template

hello,

can some one help to clarify, why this will not return this expected output:

isok=true
ab

but instead returns this:

isok=true

code:

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';
import InfernoComponent from 'inferno-component';

class MyComponent98 extends InfernoComponent.Component {
  constructor(props) {
    super(props);
    this.state = {
        isok: false,
    };
  };
  componentDidMount() { 
    this.setState({isok: true});
  };
  render() {
    return (
      <MyComponent99
            isok={this.state.isok} />
    )
  };
}

class MyComponent99 extends InfernoComponent.Component {
  constructor(props) {
    super(props);
  };
  render() {
    console.log("isok="+this.props.isok);
    return (
      <div>
        isok={this.props.isok?'true':'false'}

        <div>
            {this.props.isok &&
                ['a', 'b'].map( (x) => {
                    return (
                        <span>{x}</span>
                    );
            })}
        </div>
      </div>
    )
  };
}

InfernoDOM.render(
  <MyComponent98 />,
  document.getElementById("app"));

regards,

JSX rendering issue

hello,

  • expected output is:
a
  • however returned output is:
b

code:

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';
import InfernoComponent from 'inferno-component';

class MyComponent98 extends InfernoComponent.Component {
  constructor(props) {
    super(props);
    this.state = {
        isok: false,
    };
  };
  componentDidMount() { 
    this.setState({isok: true});
  };
  render() {
    return (
      <MyComponent99
            isok={this.state.isok} />
    )
  };
}

class MyComponent99 extends InfernoComponent.Component {
  constructor(props) {
    super(props);
  };
  render() {
    console.log("isok="+this.props.isok);

    var z = function(v) {
        if (v) {
            return (
                <span>a</span>
            );
        } else {
            return (
                <span>b</span>
            );
        };
    };

    return (
      <div>
          <div>
            {z(this.props.isok)}
          </div>
      </div>
    )
  };
}

InfernoDOM.render(
  <MyComponent98 />,
  document.getElementById("app"));

  • note that if you modify the return () block in MyComponent99 from:
    return (
      <div>
          <div>
            {z(this.props.isok)}
          </div>
      </div>
    )
  • to:
    return (
      <div>
            {z(this.props.isok)}
      </div>
    )
  • real DOM render will return expected output correctly, thus in this case:
a

regards,

Uncaught TypeError: Cannot read property 'nextSibling' of undefined

hello,

in relation to the example case here on line #50:
https://github.com/trueadm/inferno/blob/master/examples/playground/playground.js#L50

i'm wondering if throwing of exception below:
Uncaught TypeError: Cannot read property 'nextSibling' of undefined

is valid or not in case that you provide empty array to the map() call.

specifically, instead of currently provided list of items:
[ 'Volvo', 'BMW', 'Mercedes' ].map()
you would provide empty array:
[].map()
which is now throwing the exc mentioned above.

regards,

Any way to implement React's context?

I'm currently implementing a basic app using Inferno + Redux.
All of my components in the tree need to have access to my store.

I could implement a top-level StoreComponent class that imports the Store from which all of my components would inherit but I'd prefer using something more transparent.

Any plans or ideas on how I could implement React's context in Inferno?

Efficient Subtree Patching Proposal (for Inferno)?

I'm not sure if the following proposal makes sense for Inferno.
Maybe it's already supported. (See: Matt-Esch/virtual-dom#343 )

  • tl;dr: A component should be able to listen to data changes and then update itself.

I want to combine:

  • virtual-dom
  • level-js (=leveldb in the browser),
  • visual components as stream modules

Concept:

  • After initial rendering of the DOM, each "user interaction" or "server side update" updates the db
  • Visual components (=stream modules) track certain parts of the database for "data updates"
  • "data updates" stream into visual component which use it to render themselves and pipe their updated "vtree" into their DOM node
  var db = require('./level-tracker.js')(require('level-js')("data.db"))
  var engine$ = require('./inferno-engine.js') || require('./virtual-dom-engine.js')
  var componentStream = require('./component-stream.js')


  function ListComponent (db) { // "db" can also be "memdb" and holds all "state"
    var state$ = db.trackable()
    state$.track('autocomplete/')
    state$.track('help/')

    var TMP = { 'autocomplete/': [ ], 'help/': "" }
    var list$ = componentStream(function (chunk, encoding, next) {
      TMP[chunk.key].push(chunk.value)
      this.push(h('div', [
        h('li', TMP['autocomplete/'].map(function (item) {
          h('ul', item)
        })),
        h('div', TMP['help/'])
    )})

    return state$.pipe(list$)
  }

  var list$ = ListComponent(db)
  list$.pipe(engine$)

I tried to hack together something using vThunks and vHooks, see:
http://requirebin.com/?gist=003ebd0d11a7f248c210

I haven't read a lot about inferno yet, but saw the discussion about it's awesome performance.

Question:
Do you have any suggestions how to port that to inferno (if possible)?

Child component focus / blur events and state are messed up in the latest Dev branch.

There is issue that focus / blur trigger immediately. Expected result focus should happen when item is focused changing the text to True CarModel, and when moving out it should change False CarModel.

However those trigger immediately now.

latest Dev of inferno, including @KFlash 's workflow fix.
Inferno-babel-plugin: v0.2.9

Source:

import Inferno from './../../../../node_modules/inferno/dist/inferno.js';
import InfernoDOM from './../../../../node_modules/inferno/dist/inferno-dom.js';



    class FocusInput extends Inferno.Component {
        constructor(props) {
            super(props);

            this.state = {
                isEditMode: false
            };

            this.blur = this.blur.bind(this);
            this.focus = this.focus.bind(this);
        }

        blur() {
            console.log("BLUR");
            this.setState({
                isEditMode: false
            });
        }

        focus() {
            console.log("FOCUS");
            this.setState({
                isEditMode: true
            });
        }

        render(props) {
            return (
                <div>
                    <div contenteditable="true" class={this.state.isEditMode+''} onBlur={this.blur} onFocus={this.focus}>{this.state.isEditMode + this.props.value}</div>
                </div>
            )
        }
    }

    class Looper extends Inferno.Component {
        constructor(props) {
            super(props);
        }

        render() {
            return (
                <div class="loop">
                    {['Volvo', 'BMW', 'Mercedes'].map((car) => {
                        return (
                            <FocusInput value={car} />
                        )
                    })}
                </div>
            )
        }
    }

    InfernoDOM.render(<Looper />, APP_ELEMENT);

compiled output:

var tpl2011289543 = _inferno2.default.createTemplate(function (v0, v1, v2, v3) {
    return {
        tag: 'div',
        children: {
            tag: 'div',
            attrs: {
                contenteditable: 'true',
                class: v0,
                onBlur: v1,
                onFocus: v2
            },
            children: v3
        }
    };
});

var tpl1190498794 = _inferno2.default.createTemplate(function (v0) {
    return {
        tag: 'div',
        attrs: {
            class: 'loop'
        },
        children: v0
    };
});

var tpl3232491342 = _inferno2.default.createTemplate(function (v0, v1) {
    return {
        tag: v0,
        attrs: {
            value: v1
        }
    };
});

var tpl2014586923 = _inferno2.default.createTemplate(function (v0) {
    return {
        tag: v0
    };
});

    var FocusInput = (function (_Inferno$Component) {
        _inherits(FocusInput, _Inferno$Component);

        function FocusInput(props) {
            _classCallCheck(this, FocusInput);

            var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(FocusInput).call(this, props));

            _this.state = {
                isEditMode: false
            };

            _this.blur = _this.blur.bind(_this);
            _this.focus = _this.focus.bind(_this);
            return _this;
        }

        _createClass(FocusInput, [{
            key: 'blur',
            value: function blur() {
                console.log("BLUR");
                this.setState({
                    isEditMode: false
                });
            }
        }, {
            key: 'focus',
            value: function focus() {
                console.log("FOCUS");
                this.setState({
                    isEditMode: true
                });
            }
        }, {
            key: 'render',
            value: function render(props) {
                return tpl2011289543(this.state.isEditMode + '', this.blur, this.focus, this.state.isEditMode + this.props.value);
            }
        }]);

        return FocusInput;
    })(_inferno2.default.Component);

    var Looper = (function (_Inferno$Component2) {
        _inherits(Looper, _Inferno$Component2);

        function Looper(props) {
            _classCallCheck(this, Looper);

            return _possibleConstructorReturn(this, Object.getPrototypeOf(Looper).call(this, props));
        }

        _createClass(Looper, [{
            key: 'render',
            value: function render() {
                return tpl1190498794(['Volvo', 'BMW', 'Mercedes'].map(function (car) {
                    return tpl3232491342(FocusInput, car);
                }));
            }
        }]);

        return Looper;
    })(_inferno2.default.Component);

    _infernoDom2.default.render(tpl2014586923(Looper), _dom.APP_ELEMENT);

Removing listitems causes exception

When removing listitems in state list it causes exception:

Uncaught NotFoundError: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node.

class ChangeChildrenCount extends Component {
    constructor(props) {
        super(props);

        this.state = {
            list: ['1', '2', '3', '4']
        };

        // Bindings
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState({
            list: ['1']
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>1</button>
                {this.state.list.map(function (x, i) {
                    return <div>{i}</div>
                })}
            </div>
        );
    }
}
InfernoDOM.render(<ChangeChildrenCount />, document.body);

Clicking button (changing state to smaller list) causes the exception.

Expected result there should be four elements (0,1,2,3) at the beginning and when clicking button there should be one element (0).

Babel plugin / Inferno fails with rendering SVG

Inferno babel plugin 0.2.5 or Inferno 0.4.0 is failing when there is component with SVG inside.

class Component extends Inferno.Component {
        constructor(props) {
            super(props);
         }
         render() {
            return (
               <svg class="alert-icon">
                    <use xlink:href="#error"></use> // This should link to inline svg with ID error
                </svg>
            )
         }
}

 Inferno.render(<Component />, APP_ELEMENT);

Exception is thrown:

 ModuleParseError: Module parse failed: ****\node_modules\babel-loader\index.js?{"presets":["es2015"],"plugins":["babel-plugin-syntax-jsx","babel-pl
You may need an appropriate loader to handle this file type.
|             tag: 'use',
|             attrs: {
|                 [object Object]: '#error'
|             }
|         }, '            ']

Expected result:
It should render SVG element with use element refering to error id.

React has solved it this way: http://stackoverflow.com/questions/26815738/svg-use-tag-and-reactjs

Havunen

simple if statement inside component DOM

Hey,

This might be silly question, but I couldn't get it working so I decided to post it here. I'm not able to render component DOM based on boolean condition. For example if I want to hide or show different DOM nodes based on some logic.

versions:
-infernoJs dev
-babel-plugin-inferno: ^0.2.5,

I have tried following:

    class Component extends Inferno.Component {
        constructor(props) {
            super(props);
            this.state = {
                counter: 0
            }
        }
        render() {
            let condition = true; // some logic
            return (
                <div>
                    {condition ? <h1>BIG</h1> : <h2>small</h2>}
                    <p>test</p>
                </div>
            )
        }
    }

    Inferno.render(<Component />, APP_ELEMENT);

output:

var tpl4282471407 = _inferno2.default.createTemplate(function (v0) {
        return {
            tag: 'div',
            children: ['                    ', v0, '                    ', {
                tag: 'p',
                children: 'test'
            }, '                ']
        };
    });

    var tpl3625453295 = _inferno2.default.createTemplate(function () {
        return {
            tag: 'h1',
            children: 'BIG'
        };
    });

    var tpl4021787591 = _inferno2.default.createTemplate(function () {
        return {
            tag: 'h2',
            children: 'small'
        };
    });

    var tpl1546018623 = _inferno2.default.createTemplate(function (v0) {
        return {
            tag: v0
        };
    });
// this function gets called runtime
    function loginPresenter() {

        var Component = (function (_Inferno$Component) {
            _inherits(Component, _Inferno$Component);

            function Component(props) {
                _classCallCheck(this, Component);

                var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Component).call(this, props));

                _this.state = {
                    counter: 0
                };
                return _this;
            }

            _createClass(Component, [{
                key: 'render',
                value: function render() {
                    var condition = true; // some logic
                    return tpl4282471407(condition ? tpl3625453295(null) : tpl4021787591(null));
                }
            }]);

            return Component;
        })(_inferno2.default.Component);

        _inferno2.default.render(tpl1546018623(Component), _dom.APP_ELEMENT);
    }

fails with runtime exception:
Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.

Also tried following:

    class Component extends Inferno.Component {
        constructor(props) {
            super(props);
            this.state = {
                counter: 0
            }
        }
        render() {
            let condition = true; // some logic
            return (
                <div>
                    {function(){
                        if (condition) {
                            return <h1>BIG</h1>
                        } else {
                            return <h2>small</h2>
                        }
                    }.call(this)}
                    <p>test</p>
                </div>
            )
        }
    }

    Inferno.render(<Component />, APP_ELEMENT);

output:

    var tpl4282471407 = _inferno2.default.createTemplate(function (v0) {
        return {
            tag: 'div',
            children: ['                    ', v0, '                    ', {
                tag: 'p',
                children: 'test'
            }, '                ']
        };
    });

    var tpl3625453295 = _inferno2.default.createTemplate(function () {
        return {
            tag: 'h1',
            children: 'BIG'
        };
    });

    var tpl4021787591 = _inferno2.default.createTemplate(function () {
        return {
            tag: 'h2',
            children: 'small'
        };
    });

    var tpl1546018623 = _inferno2.default.createTemplate(function (v0) {
        return {
            tag: v0
        };
    });

// this function gets called runtime
    function loginPresenter() {

        var Component = (function (_Inferno$Component) {
            _inherits(Component, _Inferno$Component);

            function Component(props) {
                _classCallCheck(this, Component);

                var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(Component).call(this, props));

                _this.state = {
                    counter: 0
                };
                return _this;
            }

            _createClass(Component, [{
                key: 'render',
                value: function render() {
                    var condition = true; // some logic
                    return tpl4282471407((function () {
                        if (condition) {
                            return tpl3625453295(null);
                        } else {
                            return tpl4021787591(null);
                        }
                    }).call(this));
                }
            }]);

            return Component;
        })(_inferno2.default.Component);

        _inferno2.default.render(tpl1546018623(Component), _dom.APP_ELEMENT);
    }

and it also fails runtime with following exception:
Chrome: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
Firefox: TypeError: Argument 1 of Node.appendChild is not an object.

tested on Chrome 47.0.2526.106 m and Firefox 43.0.2

What am I doing wrong here... ?

Havunen

why cito?

Hi @trueadm,
English is not my language, hope you understand me :)
I'm curious. Why you changed from Bobril to cito?
Seems to me that Bobril is superior code.
I think virtual-dom is another good alternative, because of its current penetration in the community.

Build system and code revamp

I love the design and concept behind Inferno -- it fascinates me and I'm just raring to switch from React. But before we get there, there are a few things Inferno needs to address. I'm a bit busy right now, so I'll just outline my main concerns:

  • Grunt is outdated. Gulp is a much better and faster build system.
  • Same with Closure. UglifyJS is a much more capable and supported utility.
  • Since you're using babel, it would be nice to use the new syntax. (let, import, etc.)
  • Inferno should be more modularized. Unless a library is really small, a single module is usually a bad sign.
  • Babel, Uglify, and more all come with webpack, which is what most new libraries (especially React era!) are using to build nowadays. With webpack, you can also get rid of bootstrap.js which nobody should be writing these days.

These changes should eventually reflect in t7, as well (modularizing; people would also love if the t7-precompiler were written as a babel plugin).

I'd be more than happy to submit a PR in a bit that works out all of these issues; you'll love the end result.

Documentation

Good day, @trueadm !

We have // TODO in README.md in API section.
Could you finish this section, please?

Thanks!

Strange bug with computed children

I'm playing with Inferno and it's really fast. Great work!
I encountered a strange problem with component updates. I don't know how to setup jsfiddle with babel-plugin-inferno and jsx so I'm going to paste here the code to repreduce the bug.

import Inferno from 'inferno';
import {Component} from 'inferno-component';
import InfernoDOM from 'inferno-dom';

var id = 0;

class Value extends Component {

    constructor(props){
        super(props);
        this.id = ++id;
    }

    render() {
        //console.log(this.id);
        return <div>{this.props.value}</div>
    }
}

class Repeater extends Component {

    render() {

        //this doesn't work - only the last value is updated

        var children = [];
        for (var i = 0; i < 3; i++)
            children.push(<Value key={i} value={this.props.value}/>);

        return <div>
            {children}
        </div>

        //this works - all values are updated

        //return <div>
        //    <Value value={this.props.value}/>
        //    <Value value={this.props.value}/>
        //    <Value value={this.props.value}/>
        //</div>
    }

function render(value) {
    return InfernoDOM.render(<Repeater value={value}/>, document.getElementById('root'));
}

var value = 0;

setInterval(function() {
    render(++value);
}, 100)

Basically it's a counter repeated three times. For some reason only the last instance is updated.
If you uncomment console.log statement in render method, you'll see that it reports id: 3 all the time, which is very strange :) Any explanation would be very welcome.

Wrapper components throw error

I'm building a Provider component for our inferno-reduxbindings.
Unfortunately, the following always throws the same error: Uncaught TypeError: Cannot read property 'create' of undefined

Here is the (minimal code):

class Provider extends Inferno.Component {
    render(){
        return <div>
            {this.props.children}
        </div>
    }
}

Inferno.render(
        <Provider>
            <h1>Hello World</h1>
        </Provider>
        , App.node
    )

Returning this.props.children does not work either, it gives me Uncaught Error: Inferno Error: A valid template node must be returned. You may have returned undefined, an array or some other invalid object.

Thanks!

focus are lost!

You can't maintain focus in Inferno. You have no support for document.activeElement().

new toggle issue in latest dev

There is new issue with toggling components / elements.

var tpl3578458729 = Inferno.createTemplate(function (v0) {
    return {
        tag: 'div',
        attrs: {
            className: 'login-view bg-visma'
        },
        children: v0
    };
});

var tpl188998005 = Inferno.createTemplate(function () {
    return {
        tag: 'div',
        children: 'VISIBLE'
    };
});

var tpl3754840163 = Inferno.createTemplate(function (v0) {
    return {
        tag: 'div',
        children: {
            tag: 'button',
            attrs: {
                onClick: v0
            },
            children: 'Make visible'
        }
    };
});

var TEST = function() {
    this.state = {
        show: false
    };

    this.makeVisible = function() {
        this.setState({
            show: true
        });
    }.bind(this);


    this.render = function() {
        return tpl3578458729((function () {
            if (this.state.show === true) {
                return tpl188998005(null);
            } else {
                return tpl3754840163(this.makeVisible);
            }
        }).call(this));
    };
};
TEST.prototype = new Inferno.Component(null);
TEST.constructor = TEST;

var tpl79713834 = Inferno.createTemplate(function (v0) {
    return {
        tag: v0
    };
});

InfernoDOM.render(tpl79713834(TEST), document.body);

I think it has something to do with children types as it works with other types / combinations

What is the roadmap ?

Hi, @trueadm

Seems great this project, but comparing to the readme. A couple of missing pieces?

  • createElement(). Is this something coming soon? I think that will give you even more stars. I was looking into the code, and shouldn't be too hard to copy from your very great t7 script? Or maybe I'm wrong.
  • different things seems unfinished inside the code, any plans for finishing this?
  • any plans for hooks ala Snabbdom? Not lifecycle, but example when you create a fragment, you can trigger a callback, same when you remove or update a fragment.
  • Server side rendring, is this going to happen soon? It's more or lest a must have if I should convert to Inferno. I'm from React world!

Btw. Is there any benchmark for latest version, and what is the roadmap?

I will absolutly start to use this script soon as a createElement() are done. And I like your component part too 👍

Component Life Cycle Events not all firing?

Everything is rendering fine, so this is more me trying to explore/understand the Inferno render process.

I am not sure if I've done something wrong here but I am only getting componentWillMount and componentWillUnmount events on my components. Here is a link to the repo I am working on: https://github.com/andyrj/inferno-redux-starter-kit

I have refactored my components until they could almost all be pure functions instead of extending Inferno.Component but I wanted to test out shouldComponentUpdate functionality like React's pure render mixin, since I'm using redux I can short circuit with simple === checks on props.

Am I doing something wrong in how I call render on this project or is the current dev branch only firing off will mount and will unmount, or perhaps this is expected behavior? Is this because of the simple nature of my components and not using this.state in my component? Are the t7 templates smart enough to already see I have dumb components and do this type of optimization and which is why I don't see a call to shouldComponentUpdate?

Test sometimes fails

Error below -- the test fails about half the time, which seems VERY odd -- maybe there is a race condition or something?

DOM component tests (jsx)
should render a component with a list of children that dynamically update via setState
Second render (update) ‣

Error: Uncaught AssertionError: expected '<div><div class="my-component"><h1>Saab 0</h1><button type="button">Increment</button></div><div class="my-component"><h1>Volvo 0</h1><button type="button">Increment</button></div><div class="my-component"><h1>BMW 0</h1><button type="button">Increment</button></div></div>' to equal '<div><div class="my-component"><h1>Saab 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>Volvo 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>BMW 1</h1><button type="button">Increment</button></div></div>' (http://localhost:8080/setup/chai.js:206)Error: Uncaught AssertionError: expected '<div><div class="my-component"><h1>Saab 0</h1><button type="button">Increment</button></div><div class="my-component"><h1>Volvo 0</h1><button type="button">Increment</button></div><div class="my-component"><h1>BMW 0</h1><button type="button">Increment</button></div></div>' to equal '<div><div class="my-component"><h1>Saab 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>Volvo 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>BMW 1</h1><button type="button">Increment</button></div></div>' (setup/chai.js:206)
    at global.onerror (eval at <anonymous> (specs.js:8176:9), <anonymous>:12308:10)
_src2.default.render(tpl2280747625(Wrapper), container);
(0, _waits2.default)(30, function () {
    expect(container.innerHTML).to.equal('<div><div class="my-component"><h1>Saab 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>Volvo 1</h1><button type="button">Increment</button></div><div class="my-component"><h1>BMW 1</h1><button type="button">Increment</button></div></div>');
    done();
});

relative import of modules that were build from repo

hello,

can some one help, how to use the master/dev repo modules builds?
after npm run clean && npm run build, i'll get these build results in inferno/dist/ directory:

-rw-r--r-- 1 zst zst   6963 Jan 19 23:29 inferno-component.js
-rw-r--r-- 1 zst zst   3304 Jan 19 23:29 inferno-component.min.js
-rw-r--r-- 1 zst zst 123599 Jan 19 23:29 inferno-dom.js
-rw-r--r-- 1 zst zst  41078 Jan 19 23:29 inferno-dom.min.js
-rw-r--r-- 1 zst zst  19992 Jan 19 23:29 inferno-server.js
-rw-r--r-- 1 zst zst   8303 Jan 19 23:29 inferno-server.min.js
-rw-r--r-- 1 zst zst   9114 Jan 19 23:29 inferno.js
-rw-r--r-- 1 zst zst   3209 Jan 19 23:29 inferno.min.js

however when trying to import modules via relative path:

import Inferno from './static/vendor/inferno/dist/inferno.min.js';
import InfernoDOM from './static/vendor/inferno/dist/inferno-dom.min.js';
import InfernoComponent from './static/vendor/inferno/dist/inferno-component.min.js';

no errors are reported during bundle creation, but inferno component will not get mounted into DOM node specified via getElementByID.
i apologize if the issue is obvious. i am not familiar with front end dev processes.

these are imports specified when packages are installed via npm, which do work ok:

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';
import InfernoComponent from 'inferno-component';

note that i believe that i am doing something wrong rather than there is an issue/bug with the actual inferno package.

regards,

Fails on IE9/10 -- 'Map' is undefined

Comes from src/core/createTemplate.js:32

const dynamicNodeMap = new Map();

This issue is mostly just to document that a Map polyfill is currently necessary. One solution is to specify this in the README/documentation, another is to avoid using Map.

Children are not set correctly in createElement();

@trueadm @edge Children are not set correctly in createElement()

var template = Inferno.createTemplate(function(createElement) { 
var child = createElement('li', null, "I'm a li-tag");

var element = createElement('ul', { className: 'my-list' }, child);

// will show no child nodes -  NodeList[]
console.log(element.childNodes)

return element;
});

This will not create any children for the ul element as illustrated.

If we dig deeper into this, and use the console.log inside the createElement() function, we will see this:

 NodeList[<TextNode textContent="Text Content">]
<li>
NodeList[]

and if we look at the rendered HTML in the console.log, we will see this:

<ul class="my-list"></ul>

There are no children!

It seems that only the li-element get it's children - text node. This is not attached to the parent container.

This cause other issues as well when we are setting properties. Let us say we want to set select / select multiple.
This will not work, because it has no children. As proved above.

Further. it will try to set properties / attributes on each created node - included the child nodes.
Because in fact there are no child nodes - only rendered elements.

This API function doesn't take an array of children either it seems. So we can't create multiple li-elements.

var template = Inferno.createTemplate(function(createElement) { 
return createElement('ul', { className: 'my-list' }, [child1, child2, child3])  
});

There are no tests created for this either.

Roadmap 2016

Upcoming roadmap for Q1-Q2 2016.

  • Break inferno into separate packages, such as: inferno-dom, inferno-server, inferno-component
  • DOM node/component hooks
  • inferno-test-utilities
  • DOM node transitions
  • Server side rendering
  • Chrome dev tool extension
  • propTypes
  • Performance optimisations
  • When refs are strings, imply the same logic as React and add them to their component like this.refs.node
  • Documentation
  • External libraries that we deem essential: inferno-router and inferno-redux
  • Solve polyfill/legacy browser problems

Broken source or what?

I investigated a little and everything works just fine until this commit: ae21741

I also managed to get a benchmark working with this one. And also you may notice
https://github.com/trueadm/inferno/blob/ae217413b73757c483cdd3c59751144768444726/build/inferno.js#L323-L368

This is all iteration through arrays. Updatefragment doesn't.

However, I got the benchmark running with this modified code:

function template1(fragment) {
  var root = document.createElement("div");
  fragment.dom = root;
  fragment.$e0 = root;
  fragment.valuesLength = 1;
  fragment.$t0 = Inferno.Type.LIST;
}

function template2(fragment) {
  var root = document.createElement("span");
  root.textContent = fragment.$v0;
  fragment.dom = root;
  fragment.$e0 = root;
  fragment.$t0 = Inferno.Type.TEXT;
}

function renderTree(nodes) {
  var children = [];
  var i;
  var e;
  var n;

  for (i = 0; i < nodes.length; i++) {
    n = nodes[i];
    if (n.children !== null) {
      children.push({dom: null, next: null, template: template1, templateKey: 0, key: n.key, $e0: null, $t0: 0, $v0: renderTree(n.children)});
    } else {
      children.push({dom: null, next: null, template: template2, templateKey: 1, key: n.key, $e0: null, $t0: 0, $v0: n.key.toString()});
    }
  }

  return children;
}

In the latest updates starting from 29 days ago. This all breaks, and if you try to run the same code, you will get in console. NotFoundError: Node was not found

You may notice I didn't put an length in the template2 function. If I do so, we will run into another console error: TypeError: element is null. This happen because it can't find the element when trying to update two text nodes.

If I modify even more, a various console error messages are showing in the console.log.

However. This commit 3fa8c82 contains almost identical code, except that the updateFragment now also iterate through arrays. And here it seems to break!

For update from august 24, when I changed the variable names, I ran into this console.log error with the same code:
TypeError: Argument 1 of Node.appendChild is not an object.
And when I tried with the newest update the same, or I got messages telling me that the Node was not found and a whole lot of others.

Even if the newer updates have different names, but should have worked. But doesn't simply because all the newest updates include the same strange behaviour as mentioned.

I was investigating this because I was looking deeper into creating a createElement() function and PR. But figured out I will let you add that feature. I think it should be simple enough to add createElement() if you get everything sorted out first.

I also noticed that the performance seems to be worse with latest updates. However I couldn't test the latest commits because of the strange things I mentioned.

I tried to compare with t7 when I did this manually to see what did I do wrong. But as long as valueLength is there and set to 1, it should have found the first item in the array. Same as I see here in t7 code: https://github.com/trueadm/t7/blob/master/t7.js#L108-L199

A createElement() function shouldn't be harder then this, or what?

function createElement(root, container, parent) {

    // Array holding the value types
    var values = [];

    // Template function
    var frag = function(fragment) {

        var t = document.createElement(root.tag);

        var children = root.children;

        fragment.dom = t;
        fragment.templateElement = t;

    // Iterate through the children or values here?
    // Anyhow, the idea was to push the values to the value array, and then count the length on it.

        if (children != null) {

            if (root.children instanceof Array) {

                for (var i = 0; i < root.children.length; i++) {

                    var child = root.children[i];

                    if (typeof child === "string" && root.children.length === 1) {

                        if (typeof child === "string") {
                            if (!parent) {
                                fragment.templateElement.textContext = child;
                            } else {
                                parent.textContext = child;
                            }
                        }
                    } else if (typeof child === "string" && root.children.length > 1) {

                    } else if (child != null) {

                    }
                }
            }
        }
        if (values.length === 1) {
            fragment.templateValue = templateValues[0];
            fragment.templateElements = null;
            fragment.templateTypes = null;
        } else if (values.length > 1) {

            fragment.templateValues = [templateValues.join(", ")];
            fragment.templateElements = Array(templateValues.length);
            fragment.templateTypes = Array(templateValues.length);
        }
   }

    return {
        dom: null,
        templateElement: null,
        template: root.children.length > 0 ? frag : ""
    };
}

// How to:
createElement( { tag:"div", children:"hello, world!" }, document.body);

I didn't continue on this due to all the other mess, and you know the code best. So I guess you can handle it better then me 👍 I was thinking to get the same result as you do with t7. Then you could use your existing render function as before.

Anyhow. I really liked your script, I did. But I'm forced to abondon this now. Way to complicated for others I guess to contribute. Let's hope it will be better in the future!

And for now I remove my star.

Children not rendering properly

Simple test case, tested against latest dev branch.

class Counter extends Inferno.Component {
        constructor(props) {
            super(props);
            this.state = {
                count: 0
            };
            this.incrementCount = this.incrementCount.bind(this);
        }
        incrementCount(){
            this.setState({
                count: this.state.count + 1
            });
        }
        render(){
            return (
                <div class="my-component">
                    <h1>{this.props.car} {this.state.count}</h1>
                    <button type="button" onClick={this.incrementCount}>Increment</button>
                </div>
            );
        }
    }
    class Wrapper extends Inferno.Component {
        constructor(props) {
            super(props);
        }
        render() {
            return (
                <div>
                    {["Saab", "Volvo", "BMW"].map(function(c) {
                        return (<Counter car={c} />)
                    })}
                </div>
            )
        }
    }
    Inferno.render(<Wrapper />, APP_ELEMENT);

Inside incrementCount the correct this context exists with the prop.car set as well as state.count set but the only render() method called is with the this context for BMW.

I'll try to track this down inside the code and see if I can provide more insight.

issues with createTemplate()

@edge @trueadm

This test spec:

describe('should properly render input download attribute', () => {
                    let template;

                    beforeEach(() => {
                        template = Inferno.createTemplate((t, val1) =>
                            <input download={ val1 }></input>
                        );
                        Inferno.render(Inferno.createFragment(false, template), container);
                    });

                    it('Initial render (creation)', () => {
                        expect(
                            container.innerHTML
                        ).to.equal(
                            '<input>'
                        );
                    });

                    it('Second render (update)', () => {
                        Inferno.render(Inferno.createFragment(true, template), container);
                        expect(
                            container.innerHTML
                        ).to.equal(
                            '<input download="">'
                        );
                    }); 
                });

will throw this error

AssertionError: expected '<input download="[object Object]">' to equal '<input>'[email protected]:14602:19

My question is. What is this [object Object], are the value not replaced or what? Where is this [object Object] coming from?

This works if I set the value manually.

if we try to update, we will get an element is null in the console.log. I commented that out for now.

Children of template are not rendering properly

Here is a demo of the problem:

http://codepen.io/Pauan/pen/572d2d405fcbbbaf6a85b38fd5517094

It uses the latest code from trueadm/inferno/packages/inferno/dist/ on the dev branch.

The demo is a reduced test case: my real application is much more complex.

But the basic idea is the same: depending on a boolean condition, either render one subtree, or render another subtree.

The problem is, when it updates, it should display BarQux but instead it only displays Bar

Am I doing something wrong? Do templates not allow for a variable number of children? If so, then how can I accomplish this use case?

Can't get my bundle working.

Trying to compile this JSX crap with new babel 6 after taking a month off and shit is broken. Please help so I can pitch using inferno over react to my new team.

using this in gulpfile:

browserify("src/index.jsx")
.transform("babelify", {
presets: [
'es2015',
'stage-0'
],
plugins: [
"babel-plugin-syntax-jsx",
"babel-plugin-inferno"
]
})
.bundle()
.pipe(fs.createWriteStream("dist/bundle.js"));

Opening the index.html and loading the bundle.js I get this:

Uncaught TypeError: Super expression must either be null or a function, not undefined

Anyone else go through this?

EDIT:

I'm trying to get the example working so here is my index.jsx file:

import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';

class Component extends Inferno.Component {
constructor(props) {
super(props);
this.state = {
counter: 0
}
}
render() {
return (
// JSX markup
)
}
}

InfernoDOM.render(, document.body);

Docs: README.md typo

"Writing intensive modern UIs that require many updates/animations falls apart and becomings overly complicated"

Replace "and becomings" with ", becoming" or "and becomes".

build inferno+ES6 code as dev (with webpack) and dist (with rollup) script

Hi, I am trying to setup Inferno with npm build scripts. At this point my approach is to use webpack+watch+reload npm run dev for development and bundle a script with rollup for production npm run bundle.

The inferno packages on npm currently have a jsnext:main field, but that does not point to the es6 code, so rollup will rollup the distributed uml script that was already rollup-ed-up.

One approach could be to exclude Inferno from rolling up.

With the current inferno distribution rollup mycode+inferno is not supported is this correct?

Could inferno distribute the es6 code too?
Else jsnext:main does not make sence.

Here is my hello world. Note: the webpack dev reloading is working with this approach. The Rollup script does rollup the dist/inferno that was already rolledup and builds a scritps that errors in the browser.

main.js
import Inferno from 'inferno';
import InfernoDOM from 'inferno-dom';

const template = Inferno.createTemplate(() => ({
    tag: 'section',
    children: [
        { tag: 'h1', text: 'Hello World'}
    ]
}));

const main = document.querySelector('body');

InfernoDOM.render(template(), main);
package.json scripts
    "dev": "webpack-dev-server --config ./conf/webpack.dev.js --inline",
    "bundle": "node ./conf/rollup.prod.js",
webpack.dev.js
/* global __dirname */

const webpack = require('webpack');
const ExtractText = require('extract-text-webpack-plugin');

module.exports = {
  'entry': {
    'main': './app/main.js',
    'html': './app/index.html'
  },
  'output': {
    'path': './build',
    'publicPath': '/',
    'filename': './[name].js'
  },
  'devServer': {
    'contentBase': './build',
  },
  'module': {
    'loaders': [
      {
        'test': /\.html$/,
        'loader': 'file',
        'query': {
          'name': '[name].[ext]'
        }
      },
      {
        'loader': 'babel-loader',
        'test': /\.js$/,
        // 'exclude': /(node_modules)/,
        'query': {
          'presets': ['es2015']
        }
      }
      ]
    },
    'plugins': [
      new ExtractText('index.html'),
      new webpack.NoErrorsPlugin()
    ],
    'devtool': 'source-map'
  };
rollup.prod.js
const rollup = require('rollup').rollup;
const npm = require('rollup-plugin-npm');
const commonjs = require('rollup-plugin-commonjs');
const babel = require('rollup-plugin-babel');

rollup({
  'entry': './main.js',
  'plugins': [
    npm({ 'jsnext': true, 'main': true }),
    commonjs(),
    babel({ 'babelrc': false, 'presets': ['es2015-rollup'] }),
  ]
})
.then(function(bundle){
  return bundle.write({
    'banner': '/* Bundle */',
    'dest': 'dist/scripts/bundle.js',
    'format': 'iife',
    'indent': false,
    'sourceMap': false
  });
})
.catch(function(error){
  console.log(error);
});

when running the prod script built with rollup there is a Uncaught TypeError: babelHelpers.typeof is not a function because babelHelpers is defined in 2 places and the second overwrites the first one.

maximum callstack exceeded

I'm new to Inferno, so apologies if I am missing something obvious here. I have a really basic component with just a render() function:

render() {
    return (
      <div className="main">
        <Navbar />
        <div id="app"/>
      </div>
    );
  }

So Navbar is itself also a component, a basic <ul> for now. When I actually get to rendering the component as such:

Inferno.render(<Main/>, document.getElementById('root'));

I get a maximum call stack exceeded. It seems that in:

function getCorrectItemForValues(node, item) {
        if (node !== item.domTree && item.parent) {
            return getCorrectItemForValues(node, item.parent);
        } else {
            return item;
        }
    }

Its getting caught in the recursion. It has something to do with the Navbar component since when I set a breakpoint there I can see the item is the Navbar component. If I change that to just return item in all cases it works fine but I'm sure I am missing something obvious.

Any insight is appreciated! Thanks!

Transitions/Animations

My idea of how we might implement some transition states, in this case when a DOM node enter and leaves the document, we want to apply some form of transition along with a delay before the DOM node completes its enter or leave.

<div className="box" transition={{ name: 'box-animate', enter: 500, leave: 250 }} />

This would work very much like React's ReactCSSTransitionGroup (https://facebook.github.io/react/docs/animation.html).

So in the case above, when the div DOM node gets removed/added from/to the document, Inferno will apply some additional classNames (prefixed with box-animate as per above) to the DOM node. These classes would then allow the user to implicitly set different styles for the duration of the delay (in the example above, this would be 500ms or 250ms).

What do people think about this idea?

Uncaught RangeError: Maximum call stack size exceeded in most recent dev branch

I created a repo that has a minimal code sample to reproduce the bug, with latest dev branch of inferno as of 01/01/2016 20:38 PST

https://github.com/andyrj/inferno-max-call-stack-exceeded-bug

just git clone that repo, and then you can run the app with npm start... load up localhost:8080 in browser and it will dump out the error in chrome dev tools. The whole tab gets borked and chrome dev tools will stop responding on my machine.

Ran into this while making my inferno-redux-starter-kit demo project.

inferno-server fails simple case

The following code snippet results in thrown exception:

'use strict';
var assert = require('assert');
var Inferno = require('inferno');
var InfernoServer = require('inferno-server');

var template = Inferno.createTemplate(function() {
  return Inferno.TemplateFactory.createElement('div');
});

assert(InfernoServer.renderToString(template()), '<div></div>');
TypeError: Cannot read property 'create' of undefined
    at Object.renderToString (node_modules/inferno/dist/inferno-server.js:21:25)

I'm using "[email protected]" and "[email protected]".

Make license more explicit

Hi @trueadm,

I've just discovered inferno and I liked the approach that you have had for the VritualDom and to use t7 as template system, actually I've discovered Inferno through t7.

I've seen that you decided to use ISC license, as it's in package.json, however I think that it's very helpful to add a LICENSE file to the root of the project or add a LICENSE section in the README.

Thanks.

inferno without jsx (jsx alternatives)

Hi I found inferno while looking for jsx alternatives though t7. Call me not openminded for not falling in love with jsx. Watching the redux series made me want to use redux and just confirmed that I never touch{' '} . I know jsx is optional, but calling createElement() for every element does not make it any better.

From reading some of the tests I noticed that Inferno allows to create multiple elements with Inferno.createTemplate https://github.com/trueadm/inferno/blob/dev/test/browser/acceptance/no-jsx/dom-elements-tests4.js#L454 , so my first question is: would it be possible to just pass objects around or does the createTemplate need to be called everywhere?

I believe citojs uses just objects and at some point lastly calls cito.vdom.append once. Deku calls it the virtual element. I know this is syntax sugar but I bet there are some others not wanting to use jsx ever or trying to get away at some point in the future. Calling createElement might have a negative perf impact.

My second question is how deep is jsx to be built into Inferno? Will there ever be Inferno without jsx? smaller library size, less code to execute, no compile step when using es6-module-loader.

Also reading about Inferno and state-diffing "feels just right™"! I read all the issues and looked at the dev branch. But I want to know more :)

Would you suggest to start playing around with the dev branch? I dont mind things are not final...

Adding listitems does nothing

This is related to bug #88, but instead removing, adding more listitems.

class ChangeChildrenCount extends Component {
    constructor(props) {
        super(props);

        this.state = {
            list: ['1']
        };

        // Bindings
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick() {
        this.setState({
            list: ['1',  '2', '3', '4']
        });
    }

    render() {
        return (
            <div>
                <button onClick={this.handleClick}>1</button>
                {this.state.list.map(function (x, i) {
                    return <div>{i}</div>
                })}
            </div>
        );
    }
}


InfernoDOM.render(<ChangeChildrenCount />, document.body);

expected result: at the beginning there is single item: ( 0 ), then after clicking button there are four (0,1,2,3)

Looping is broken at latest Dev.

Hey,

Looping components seems to be broken at latest dev. It should render two

elements inside div's but nothing happens.

    var BaseView = Inferno.createTemplate(function (v0, v1) {
        return {
            tag: 'div',
            attrs: {
                class: 'login-view'
            },
            children: [{
                tag: 'button',
                attrs: {
                    onClick: v0
                },
                children: 'ADD'
            }, {
                tag: 'br'
            }, v1]
        };
    });

    var Looper = Inferno.createTemplate(function (v0) {
        return {
            tag: 'div',
            children: [
                {
                    tag: 'h1',
                    children: v0
                }
            ]
        };
    });

    var starter = Inferno.createTemplate(function (v0) {
        return {
            tag: v0
        }
    });

    var SomeError = function() {
        this.state = {
            list: ['SS', 'SS1']
        };

        this.render = function() {
            return BaseView(this.toggle, (function () {
                this.state.list.map(function(result){
                    return Looper(result);
                });
            }).call(this));
        };
    };
    SomeError.prototype = new Inferno.Component(null);
    SomeError.constructor = SomeError;

    InfernoDOM.render(starter(SomeError), document.body);

npm run build error

On branch dev (8a3fd3d), after a fresh rm -rf node_modules and npm i I get the following error when building. All tests pass

npm run build

> [email protected] build /Users/user/source/examples/inferno
> npm run clean && mkdirp dist && npm run build:dev && npm run build:prod


> [email protected] clean /Users/user/source/examples/inferno
> rimraf coverage/ dist/


> [email protected] build:dev /Users/user/source/examples/inferno
> babel-node config/rollup.config.js dev

/Users/user/source/examples/inferno/config/rollup.config.js:139
    throw reason;
    ^

SyntaxError: Unterminated comment (30:59) in /Users/user/source/examples/inferno/src/DOM/createTree.js
    at Parser.pp$4.raise (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4271:13)
    at Parser.pp$7.skipBlockComment (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4525:24)
    at Parser.pp$7.skipSpace (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4576:18)
    at Parser.pp$7.nextToken (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4497:54)
    at Parser.pp$7.next (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4452:8)
    at Parser.pp$3.parseIdent (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:4219:8)
    at Parser.pp$2.parseBindingAtom (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:3475:19)
    at Parser.pp$2.parseMaybeDefault (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:3522:23)
    at Parser.pp$2.parseBindingList (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:3507:23)
    at Parser.pp.parseFunctionParams (/Users/user/source/examples/inferno/node_modules/rollup/dist/rollup.js:3169:22)

npm ERR! Darwin 14.5.0
npm ERR! argv "/Users/user/node/latest/bin/node" "/Users/user/source/examples/inferno/node_modules/.bin/npm" "run" "build:dev"
npm ERR! node v5.3.0
npm ERR! npm  v3.5.2
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build:dev: `babel-node config/rollup.config.js dev`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build:dev script 'babel-node config/rollup.config.js dev'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the inferno package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     babel-node config/rollup.config.js dev
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs inferno
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls inferno
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/user/source/examples/inferno/npm-debug.log

npm ERR! Darwin 14.5.0
npm ERR! argv "/Users/user/node/latest/bin/node" "/Users/user/node/latest/bin/npm" "run" "build"
npm ERR! node v5.3.0
npm ERR! npm  v3.3.12
npm ERR! code ELIFECYCLE
npm ERR! [email protected] build: `npm run clean && mkdirp dist && npm run build:dev && npm run build:prod`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the [email protected] build script 'npm run clean && mkdirp dist && npm run build:dev && npm run build:prod'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the inferno package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run clean && mkdirp dist && npm run build:dev && npm run build:prod
npm ERR! You can get their info via:
npm ERR!     npm owner ls inferno
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /Users/user/source/examples/inferno/npm-debug.log

#perf-spike: Having trouble using Inferno with JSX (babel-plugin-inferno)

Hi,

First of all, thank you all for your efforts on this project!

Like I said in the title, I get this error: _src2.default.createFragment is not a function. By the way, I am also using webpack.

I can see that compiler creates this template:

_src2.default.render(_src2.default.createFragment({
  component: Component,
  props: {
    title: "abc",
    name: "basic-render"
  }
}, tpl1126106956), document.getElementById("app"));

Here is my configuration so far:

// webpack-dev-server.config.js
var webpack = require('webpack');
var path = require('path');
var buildPath = path.resolve(__dirname, 'build');
var nodeModulesPath = path.resolve(__dirname, 'node_modules');

var config = {
  entry: [
    'webpack/hot/dev-server',
    'webpack/hot/only-dev-server',
    path.join(__dirname, '/src/app/app.js')
  ],

  resolve: {
    extensions: ["", ".js", ".jsx"]
  },

  devServer:{
    contentBase: 'src',
    devtool: 'eval',
    hot: true,
    inline: true,
    port: 3000
  },

  devtool: 'eval',

  output: {
    path: buildPath,
    filename: 'app.js'
  },

  plugins: [
    new webpack.HotModuleReplacementPlugin()
  ],

  module: {
    loaders: [{
      test: /\.(js|jsx)?$/,
      loaders: ['babel-loader']
      //exclude: [nodeModulesPath]
    }]
  }
};

module.exports = config;
//.babelrc
{
    "env": {
        "development": {
            "presets": [
                "es2015", "stage-0"
            ]
        },
        "production": {
            "presets": [
                "es2015-rollup"
            ]

        }
    },
    "plugins": ["babel-plugin-inferno", "babel-plugin-syntax-jsx"]
}

And the app.js:

import Inferno from '../../node_modules/Inferno/src';

class MyComponent extends Inferno.Component {
  render() {
    return (
      <div className="basic">
        <span className={ this.props.name }>The title is { this.props.title }</span>
      </div>
    );
  }
}

Inferno.render(<MyComponent title="abc" name="basic-render" />, document.getElementById("app"));

I am sorry if this is just a rookie mistake and a useless question, but I'm quite new to this npm world. Thank you!

EDIT: I can run the example app without JSX just fine:

const { createElement } = Inferno.TemplateFactory;

class MyComponent extends Inferno.Component {
  render() {
    let template = Inferno.createTemplate((name, title) =>
      createElement("div", {className: "basic"},
        createElement("span", {className: name}, "The title is ", title)
      )
    );

    return template(this.props.name, this.props.title);
  }
}

let template = Inferno.createTemplate((MyComponent, title) =>
  createElement('div', null,
    createElement(MyComponent, {title: title, name: "basic-render"})
  )
);

Inferno.render(template(MyComponent, 'abc'), document.getElementById("app"));

[Q] How did you do it?

Hi. @KFlash here. Author of Trackira. I just wonder how you got this performance and your future plans?

Just to say it. When I did Trackira my goal was to create something average for people to use. And the performance are bob bob.

In my other private project I do things for real and this project is a component framework with a VD just like inferno. The performance on this is much better overall then citojs and almost same as inferno.

So I started to wonder. Inferno can work with or without templates? As in REACT createElement? How do you set your html attributes so they become an array? And can you explain the concept of your value nodes and static and dynamic?

When I attach attributes on a virtual node. I do:

vnode.attributes ()

Same concept as in jsBlocks.

So when I create a node I can use chaining like this:

CreateElement("div")
   .attributes ()
   .css ()
   .children () // create new child nodes

as you may notice. I can now only diff/patch children, attributes and css without touching anything else. And do a update and add the new changes.

Still you get super performance so could you tell me how?

Is there any mount / unmount in inferno and if so. Can you mount / unmount a single node or a whole tree?

I can in my project unmount all children on a specific node or a whole tree. And also mount.

And then I wonder about dirty checking. I haven't finished that yet. But I saw in the code you plan too. What would be the best approach here regarding performance?

Animation and transitions. Are you going to support? Your thoughts here. Just curious because I'm planning to add it but searching for the best approach.

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.