Closed jorgebucaran closed 6 years ago
Although all these may increase the lib size but they can be dispatched through separate packages like InfernoJS does ?
@nitin42
Lifecycle events already exist. Maybe they can be improved? Do you have any suggestions?
~SSR. There are several ad-hoc solutions. See also: https://github.com/hyperapp/hyperapp-server for a WIP. Not sure if I should wait for SSR to release 1.0. I think not, but what do you think?~
Controlled Components. You can create your own ~custom tags~ controlled components already.
~Recycling of DOM nodes and recomposing components. How do you mean? lol~ We are doing this one! I've updated the todo list. /cc @ngryman
Oh! I really wanted to work on hyperapp
and right now I am going through the Elm Architecture doc. Where can I start ?
From recycling of DOM nodes I meant to say that re-using the dom nodes upon their disposal.
Or I can work on the website ? This will also led me to understand the core concepts and the design principles of the lib by writing about the api and their functionality. Let me know what you think !
Where can I start ?
I think here is a good place to start.
Or I can work on the website?
Be my guest! π
Ok so I will be rendering the docs on web. Meanwhile I will go through the link you provided and will start contributing !
Is there something on (HyperApp core) which I can hack? Other discussions are already on π₯ ! I am interested in investing my time by working on HyperApp but don't know where to start. Like cli tool discussion does not have an answer and I feel growing that discussion further is unneeded. Same goes for other discussions. Anything ?
@nitin42 you could try build an app with HyperApp; find a limitation and try improve it or find something that you find writing over and over again and try abstract that process out to a custom element or mixin?
Or help build out functionality of example applications such as the Hacker News PWA. So we can get it up on https://hnpwa.com/
HNPWA seems a good idea!!
I could implement :
I think I should start working!
Should we use Github's "milestone" feature for 1.0? Not sure how it works, but this seems like the sort of use case they made that feature for.
@jbucaran What's the plan for the relationship between picodom and hyperapp? If hyperapp wants to eventually consume picodom as a dependency, should that be part of 1.0 milestone?
@andrewiggins At this point both vdom engines are the same, but I presume they might eventually begin to differ since both have different "core values". HyperApp is opinionated about state management, while picodom isn't.
I also don't want to consume picodom in hyperapp, but it might happen. The probability is very low though.
Why do we need both actions and events?
Take this really vanilla app:
app({
state: {
images: []
},
view: function(state) {
return h('div', {}, state.images.map(function(image) {
return h('img', {src: 'images/' + image.url});
}));
},
actions: {
updateImages: function(state, actions, data) {
state.images = data;
return state;
}
},
events: {
updateImages: function(state, actions, images) {
actions.updateImages(images);
}
}
});
setTimeout(function() {
emit('updateImages', []);
}, 5000);
This is cool, but why not allow this:
app({
state: {
images: []
},
view: function(state) {
return h('div', {}, state.images.map(function(image) {
return h('img', {src: 'images/' + image.url});
}));
},
actions: {
updateImages: function(state, actions, data) {
state.images = data;
return state;
}
}
});
setTimeout(function() {
emit('action', {name: 'updateImages', data: []});
}, 5000);
@brandonros Why do we need both actions and events?
I think the separation is important from an architecture point of view.
Now, you can also create custom events, in which case you are responsible for calling yourself, but they also work in the same way as the default events.
Actions return a partial state or a thunk, or maybe just call several other actions. Actions can be async functions too.
Events reduce over some data by successively calling each event handler of the specified event.
Consider the following example.
const emit = app({
events: {
someEvent: [
(state, actions, data) => data + 1,
(state, actions, data) => data + 1,
(state, actions, data) => data + 1
]
}
})
And this is the result of firing someEvent
with some data.
console.log(
emit("someEvent", 10)
) // => 13
An event can have more than one callback associated with it.
myEvent: [handler1, handler2, handler3]
An action is always a single call.
These are some of my thoughts. I am sure that:
setTimeout(function() {
emit('action', {name: 'updateImages', data: []});
}, 5000);
Would be interesting, and we can consider the implications of making emit work in both ways, allowing you also to emit default events.
@jbucaran I think it the time it took you to write this response, you could have made emit('action', {name: 'updateImages', data: []});
work. :)
@brandonros It didn't take so long and this is good documentation for subscribers too! :)
So, what about this:
const Sender = emit => ({
events: {
send(state, actions, { name, data }) {
return actions[name](data)
}
}
})
const emit = app({
mixins: [Sender]
})
Then use it to call actions directly outside your app.
emit("send", { name: "updateImages", data: [...] })
Making it work for action
might be possible too, but would require some "hacking" since action
is one of the default events.
@jbucaran Thank you for taking the time to supply that example. I appreciate that and I hope it helps somebody else.
I've got one more "idea" that I came up with using this, just playing around with it.
I really don't like having to set up Browserify or Webpack or all of that crap. I'm trying to avoid Babel + JSX as well, just for exercise.
Back in the jQuery days, I used to do a lot of:
$('body').html('<div>a really big <span>html string</span></div>')
I saw you guys had the ability to use the (html`html string here`), but that requires Browserify.
Is it possible to get compiled/ported so you can just include a page, and then call h(html('long string'))
or something similar?
I just spent 15 minutes trying to figure out why the "load" event isn't working.
Your codepad says it is 'init' instead of load. Please update the docs. https://github.com/hyperapp/hyperapp/blob/master/docs/events.md
Load is in 0.11 which should be out anytime now... Master is ahead of npm publish by a bit.
Thunks do not work and when I try to install it to help debug to provide more information (all I can get is a minified version), I get rollup.config.js not found
Edit: I see what you mean about master. Can you put the rollup.config.js in the repo please?
Edit: I was trying to build an old version. Ignore, thanks!
I recall someone else running into that when npm installing the package from master git repo. I have always had to make local copy and create a symlink in node_modules to the local repo to test newest version. Hopefully 0.11 will be out soon.
@brandonros As h
implement the normalised hyperscript representation, that allow you to use hyperscript-helpers
. That allow you to use an elm like syntax to create your virtual dom node.
import { h, app } from "hyperapp"
import helpers from "hyperscript-helpers"
const { div, h1 } = helpers(h)
app({
state: {
title: "Hi.",
},
view: state =>
div(null, [
h1(null, state.title)
])
})
I am also working on my own implementation, to create a more optimised (tree shaking, right h
call) experience for Hyperapp and Picodom users.
@brandonros If you want to go completely standalone, this works (as long as you're targeting mostly es6 compatible browsers):
<html>
<head>
<script src="https://unpkg.com/hyperx"></script>
<script src="https://unpkg.com/hyperapp"></script>
</head>
<body>
<script>
const {app, h} = hyperapp
const html = hyperx(h, {attrToProp: false})
/*
now you can produce virtual trees like this:
html`
<div class="foo">
<p>AAA</p>
<p>BBB</p>
</div>`
*/
//initialize your app:
app({...})
</script>
</body>
</html>
The reason this method is not usually mentioned or recommended is because there is a performance penalty to compiling the hyperx strings in browser when it could be handled by a browserify transform or webpack loader.
It's also possible to do something similar for a standalone html page written with JSX, but I can't remember the module name. babel-standalone
I think.
@nitin42 Recomposing components (like lodash) for expressing state updates
What is this? I don't use lodash and I am not familiar with the concept "recomposing components" either. But it sounds interesting.
I think @nitin42 is referring to this:
var _ = require('lodash/core');
// Load the FP build for immutable auto-curried iteratee-first data-last methods.
var fp = require('lodash/fp');
Thanks @naugtur, but now I am more confused! π
EDIT: Not sure I understand what this has to do why hyperapp either.
waiting for SSR so much π
@lyquocnam There are ways to hydrate pre-rendered HTML. We already use it at work π―.
@jbucaran have any examples about Hyperapp with backend and SSR ?
Edit: ~hyperApp~ -> Hyperapp
@lyquocnam Nope, no non-trivial SSR example, but we created hyperapp/server and could use some help. π
/cc @andrewiggins @SkaterDad @corysimmons
Swamped for about the next month then I can work on some SSR solution. Anyone is welcome to beat me to it. π¬
Hey there!!! Sean from the webpack team. Please let me know if we can help support any AoT compilation needs via a webpack loader. :-D There are lots of great examples out there already but we are here to support ya'll!!!!
Also, not sure what your lazy loading story looks like, but as long as your api accepts a Function -> Promise<YourComponentPrimative>
then it can support webpack code splitting for syntaxes like
import();
Now that #311 has been merged, what's remaining before achieving 1.0 status?
@okwolf Almost nothing! π
@TheLarkInn what would it take for hyperapp to have default support for bundle splitting with async imports similarly to what Vue supports?
Seems to me it's just about accepting a promise where a component or custom tag is expected, but I only saw that at a conference ;)
I think that would have to be a Mixin of some sort since we don't ship with polyfills π€
Just thinking out loud here π
Or we could just check if Promise
is a thing and then check if a certain view is a Promise
Webpack is buggy and bundles are huge or require a ton of config (there are literally books on how to use that project.............). It seems almost all "JS fatigue" revolves around that project...
This seems to go against what Hyperapp is trying to do (i.e. not overcomplicate simple things).
I'd vote not doing anything to support webpack and just build a simple bundler from scratch.
@corysimmons Webpack is buggy... It seems almost all "JS fatigue" revolves around that project...
That's not very nice man. JS fatigue is a myth and @TheLarkInn is just offering help. I am not a webpack user myself, but I can think of many users who want to bundle their hyperapps with webpack.
@TheLarkInn There are lots of great examples out there already but we are here to support ya'll!!!!
Can you show me an example of this? π
Webpack... bundles are huge
They can get bigger than rollup if you are bundling a ton of modules, but that's because of how webpack works.
[webpack] work by wrapping each module in a function, putting them in a bundle with a browser-friendly implementation of require, and evaluating them one-by-one. Thatβs great if you need things like on-demand loading, but otherwise itβs a bit of a waste, and it gets worse if you have lots of modules.
and
If you need code-splitting, or you have lots of static assets, or youβre building something with lots of CommonJS dependencies, Webpack is a better choice. If your codebase is ES2015 modules and youβre making something to be used by other people, you probably want Rollup.
Also:
[webpack] ...at runtime, each of those module functions is evaluated in turn to populate the module cache. This architecture has lots of advantages β it makes it possible to implement advanced features like code-splitting and on-demand loading, and hot module replacement (HMR).
Webpack is fine β€οΈ . I use it and the API is straightforward.
@corysimmons Let's try to be a bit more civil π
Also scope hoisting has helped a ton! My boilerplate counter is only 2kb gzipped using webpack, So bundles being very large might not apply so much anymore.
Let's not blame JS fatigue on a single library π
Otherwise, I wonder if this should be a Mixin (official Mixin) or in core π€
Separate issue: https://github.com/hyperapp/hyperapp/issues/379
Yeah I'm toxic. Bye guys.
@corysimmons Whoa, I just said: "that's not very nice man" because you went on a little off-topic rant blasting webpack.
And now you left the organization too? I don't get it, were you expecting anyone to support you on this or pretend you didn't say anything?
- [ ] Optimize patch?
@JorgeBucaran is this referring to what #378 would do to help fix #373?
@okwolf Nope, #373 came up just recently. Optimize patch involves rewriting the patch
function.
The objective is to rewrite it in less code and make it faster at the same time. ππ₯
The objective is to rewrite it in less code and make it faster at the same time. ππ₯
@JorgeBucaran I understand how to measure code size, but what metric are we using to determine performance in this instance?
We use js-framework-benchmark.
An interesting project to put on a test, will there be SSR support in 1.0 or this feature is not on a roadmap?
@VladShcherbin Thanks! Hyperapp now provides automatic SSR hydration out of the box since 0.14.0.
@JorgeBucaran yeah, I've seen hydration in the docs.
I mean, when a user requests a page, how do you generate html for this page on server (using node for example), is there any demo/repo of this?
Components #238(See https://github.com/hyperapp/hyperapp/issues/238#issuecomment-312455621)[ ] Flow by @andyrj? #323 #311[ ] Optimize patch?Post-1.0