infernojs / inferno Goto Github PK
View Code? Open in Web Editor NEW:fire: An extremely fast, React-like JavaScript library for building modern user interfaces
Home Page: https://infernojs.org
License: MIT License
:fire: An extremely fast, React-like JavaScript library for building modern user interfaces
Home Page: https://infernojs.org
License: MIT License
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);
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.
hello,
a
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"));
return (
<div>
<div>
{z(this.props.isok)}
</div>
</div>
)
return (
<div>
{z(this.props.isok)}
</div>
)
a
regards,
should be dist/inferno.js
, is currently just inferno.js
this breaks requiring unless you do require('inferno/dist/inferno')
in your app code
"Writing intensive modern UIs that require many updates/animations falls apart and becomings overly complicated"
Replace "and becomings" with ", becoming" or "and becomes".
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?
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!
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.
It is little bit scary to switch from some vdom to inferno bc of this =)
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)
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);
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
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,
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?
@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.
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
.
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?
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,
I'm not sure if the following proposal makes sense for Inferno.
Maybe it's already supported. (See: Matt-Esch/virtual-dom#343 )
I want to combine:
virtual-dom
level-js
(=leveldb in the browser),stream modules
Concept:
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)?
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.
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();
});
Good day!
Say please, what's the difference from virtual dom libraries making Inferno so fast?
Say from virtual-dom...
Thanks.
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.
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?
Good day, @trueadm !
We have // TODO
in README.md
in API
section.
Could you finish this section, please?
Thanks!
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.
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.
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);
"dev": "webpack-dev-server --config ./conf/webpack.dev.js --inline",
"bundle": "node ./conf/rollup.prod.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'
};
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.
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.
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
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
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...
If anyone wants to join in on the discussion on the development of t7 or Inferno, please let me know via email and I'll send you an invite. :)
My email is: dg (at) domgan.com
Hey,
Looping components seems to be broken at latest dev. It should render two
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);
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).
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.
You can't maintain focus in Inferno. You have no support for document.activeElement()
.
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?
I'm building a Provider component for our inferno-redux
bindings.
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!
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:
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.
Upcoming roadmap for Q1-Q2 2016.
inferno
into separate packages, such as: inferno-dom
, inferno-server
, inferno-component
inferno-test-utilities
this.refs.node
inferno-router
and inferno-redux
https://github.com/paldepind/snabbdom#hooks
Is this approach interesting for Inferno?
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,
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]".
http://infernojs.org/benchmarks/angular-test-table/infernojs/index.html
do main table display none - for measuring only render dom without paint and reflow
create 5000 items
results:
angular2 - 100ms
inferno - 190ms
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"));
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
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.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 ๐
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.
I think this is a known issue, but posting it here to track it better.
Currently, tests on all versions of IE fail with: ReferenceError: 'Symbol' is undefined
. Would be great to get back support for IE9+!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.