jorgebucaran / hyperapp

1kB-ish JavaScript framework for building hypertext applications
MIT License
19.08k stars 780 forks source link

Made a hyperapp boilerplate repo with webpack 🎉 #11

Closed selfup closed 7 years ago

selfup commented 7 years ago

https://github.com/selfup/hyperapp-one

Let me know what you think of the structure.

Heavily inspired (the view is pretty much the same :joy:) by the simple counter example!

A lot of people like a quick repo that is already wired up. Nothing crazy, just a simple boilerplate 😄

jorgebucaran commented 7 years ago

@selfup Looks great. Clean structure and separation of concerns! My only suggestion would be to use the full hyperapp- prefix, since hyper- is already popular with the HyperTerm folks.

selfup commented 7 years ago

@jbucaran That is a great point! I'll rename the repo and change the remote on my end. Thanks for the feedback

Update

Ok it is updated:

  1. repo: https://github.com/selfup/hyperapp-one
  2. gh-page: http://selfup.me/hyperapp-one
jorgebucaran commented 7 years ago

@selfup Thanks! Now's perfect.

tunnckoCore commented 7 years ago

Looks cool to me too. But I think there can have folders for effects and subs too? :)

selfup commented 7 years ago

@tunnckoCore I can add two empty directories for effects and subs :smile:

The app itself doesn't use them, but it will give an idea as to where to create them when they need it!

Great suggestion

Update

Added subs and effects with an empty files in each that has a comment block explaining why they are there.

https://github.com/selfup/hyperapp-one/tree/master/src

Example comment block in ./src/effects/counter.js

/**
 * There are no effects for this application
 * But this is an example of directory and file structure for effects
 * Seperation of concerns are key in functional paradigms!
 */
jorgebucaran commented 7 years ago

Thanks @selfup!

selfup commented 7 years ago

Going to add hooks tonight as well. Forgot about those 😂

selfup commented 7 years ago

Ok added hooks dir and how to remove git history to start as a new repo :tada:

aeosynth commented 7 years ago

is hot module reloading possible?

selfup commented 7 years ago

@aeosynth I was under the impression that the DOM changed once you hit save in your editor.

You have to visit: http://localhost:8080/webpack-dev-server/index.html for this behavior btw!

Once at this url (after npm start) go ahead and change 0 to 10 for the num value in the model. Save. You will see it update automagically

If you visit just: http://localhost:8080 you will have to refresh manually

True HMRE

Now if you want true hot module replacement:

There would first need to be some sort of babel-preset-hyperapp-hmre library/loader to enable this as an actual feature in the boilerplate repo.


I would suggest opening a new issue for hmre 😄

AutoSponge commented 7 years ago

I created a hyperapp server using neutrino.js: gomix

jorgebucaran commented 7 years ago

@AutoSponge This is awesome Paul, thanks for sharing!

jorgebucaran commented 7 years ago

@AutoSponge Do you think this would do a nice preset?

jorgebucaran commented 7 years ago

https://github.com/heygrady/neutrino-preset-standard/blob/master/src/index.js

AutoSponge commented 7 years ago

@jbucaran I see a couple of options:

  1. Get HRM working and make it a preset that builds on -web
  2. Create a preset that steals stuff from -web but ignores HMR

Also, I think there's an opportunity to figure out server-side render and make it part of the preset options.

jorgebucaran commented 7 years ago

@dodekeract @lukejacksonn Is this something you folks would find handy?

Hi @maraisr! Do you have any experience getting HMR working?

maraisr commented 7 years ago

@jbucaran I have yeah - its a pain at first, and will need to write some funk re-hibernate type stuff within our code base.

Basically, ou gets a callback for whenever a module has been re-compiled with its new source, so some eval magic, or whatever. My best bet would be to look through the VueJS codebase, and look at how Evan does it.

selfup commented 7 years ago

Updated to 0.7.1 🎉

FlorianWendelborn commented 7 years ago

HMR would be amazing.

lukejacksonn commented 7 years ago

I would never turn down the offer of some HMR action!

Rob-pw commented 7 years ago

Bump for interest! ^^'

selfup commented 7 years ago

Upgrading to 8.1 for the boilerplate as well as a few other changes (webpack config, yarn.lock, package.json)

https://github.com/selfup/hyperapp-one/pull/15

andyrj commented 7 years ago

I don't think you have to create anything extra to enable HMR now... I just slapped a quick example together that simply empties document.body.innerHTML within the `module.hot.accept...

import { h, app } from 'hyperapp';

export default (initState) => {
    app({
        state: initState,
        view: (state, actions) => {
            return (
                <div>
                    <p>Hot module reload! no refresh required!</p>
                    <button onclick={actions.increment}>Click</button>
                    <span>{state.count}</span>
                </div>
            );
        },
        actions: {
            increment: (state) => Object.assign({}, state, { count: state.count + 1 } )
        },
        events: {
            render: (data) => {
                window.state = Object.assign({}, window.state, data)
            }
        }
    });
};
import app from './app';

document.body.innerHTML = '';
app({count: 0});

if (module.hot) {
    module.hot.accept('./app', () => {
        document.body.innerHTML = '';
        app(window.state);
    });
    module.hot.accept();
}

EDIT: Fixed format by @jbucaran

EDIT: Thanks for fixing the format, I fixed the code snippet to show HMR without modifying hyperapp Sorry about the formatting above, not sure why the code section stuff isn't working for me atm...

my setup is using jsdom to SSR so I have to add that initial document.body.innerHTML = ''; to prevent client render doubling dom, I really don't see a requirement for an extra plugin/mixin like the react-transform-hmr, should be able to save the state in the accept and pass it into your new app as well...

jorgebucaran commented 7 years ago

@andyrj Thanks! I know @MatejMazur would love to see this.

Related

MatejBransky commented 7 years ago

@andyrj Hi, could you send me a working example with HMR (ideally repo)? Because your code is only with static state but that's not the use case for HMR.

Or even better try reproduce this with your solution: problem01-solved

My solution needs only HMR mixin (basically on event "hmr" => return state) and boilerplate with module.hot that you have too. But I'd like to see clearer solution! 👍 Because I don't have any previous experience with dev of HMR implementations.

andyrj commented 7 years ago

@MatejMazur I see the issue with HMR you are referring to but I think what is needed is a small change to the hyperapp api to accommodate saving state between module replacements... I just hacked together the needed changes in a repo and also made an example app that shows your counter saving state during HMR...

granted this approach only saves the state every second, you could essentially change the setInterval to work for your needs, and the only change needed to the hyperapp api is returning an object that can retrieve the current state instance...

Hyperapp fork with necessary change to api: https://github.com/andyrj/hyperapp Working example repo: https://github.com/andyrj/hyperapp-starter/tree/HMR-example

don't have a fancy gif to link in here, but it's working on my browser, kind of had to force the git repo installed hyperapp fork of mine to work by 'cd node_modules/hyperapp && npm install' then I could build my example app and run it as normal npm run dev

andyrj commented 7 years ago

I am not familiar with the hyperapp minxins, if they have access to the full app.state, then I would guess you could do something similar from a mixin without mucking with hyperapp app.js like I had to there...

andyrj commented 7 years ago

@MatejMazur updated the HMR example to not need modifications to hyperapp... working really well, noticed after looking in docs that I could just add a render event to copy new state into a global and the HMR can just reload from there... try it out see if this pattern works for your use case I guess, I think it's what I'm gonna use moving forward with hyperapp

Also trying to make this into a simple plugin... https://github.com/andyrj/hyperapp-webpack-hmr first hyperapp mixin and first time I've decided to publish to npm :) heh be gentle

jorgebucaran commented 7 years ago

Now that https://github.com/hyperapp/awesome-hyperapp exists, we can close here! Thank you for making this @selfup! You were the first. 💥