Giter VIP home page Giter VIP logo

Comments (9)

developit avatar developit commented on April 30, 2024

Yup, coming to Preact itself. Will update here as it does.

from preact.

c58 avatar c58 commented on April 30, 2024

Awesome, thanks!

from preact.

developit avatar developit commented on April 30, 2024

Fixed on master and passing your lovely tests. Will release as 4.0 under a beta npm dist-tag for a short time and then we'll be live.

from preact.

mrbar42 avatar mrbar42 commented on April 30, 2024

Sorry to comment on closed issue, but the non-es6 class construction still doesn't ever invoke getDefaultProps (I'm on 4.2.0).
apparently in the non es6 way all of the life cycle methods are under nodeName.prototype.
though I did no see any reference to getDefaultProps at all.
as seen here preact/src/vdom/index.js:32

let defaultProps = vnode.nodeName.defaultProps;

perhaps something like this would solve it.

let nodeName = vnode.nodeName;
let defaultProps = nodeName.defaultProps;
if (!defaultProps && nodeName.prototype.getDefaultProps) {
    defaultProps = nodeName.prototype.getDefaultProps();
}

or the non-es6 help page could be changed to this

export function createClass(obj) {
  function F() {
    Component.call(this);
  }

  let p = F.prototype = Object.create(Component.prototype);
  for (let i in obj) {
    if ('getDefaultProps' == i) F['defaultProps'] = obj[i]();
    p[i] = obj[i];
  }

  return p.constructor = F;
}

from preact.

developit avatar developit commented on April 30, 2024

@mrbar42 no problem!

getDefaultProps() is not part of the ES class API (in React as well), so it is actually handled in preact-compat rather than Preact itself. The implementation in preact-compat basically what you described.

I think we should at least document this somewhere (in the Wiki?), since I can see it causing some confusion. Also, perhaps we have a use-case here for something lighter than preact-compat that adds support for the createClass() API? A separate module would make it nice and optional, but easy to integrate without relying on all of preact-compat (not that it's particularly large).

Interested to hear your thoughts. Also any info about your use case would be helpful too!

from preact.

mrbar42 avatar mrbar42 commented on April 30, 2024

@developit

My use case is as follows, I hate fat bundles.. that's for one.
Secondly, I dislike es6 classes (as classes in JS are virtual)
as well as dislike jsx.
but that's really a personal preferences (I seem to be in minority ).

Coming from react I'm looking for the minimum to continue more or less the same.
For example I like the DOM shorthand
this for example will add ~800 bytes to the bundle with this minimal hack.
I don't need the whole compat package - just these couple of things.
If the case for preact is to only support es6 than so be it.
maybe some minor things could be added to the es5 help page.

Here are 4 example hacks

let wrapTag = tag => {
  return function () {
    let args = Array.prototype.slice.call(arguments);
    args.unshift(tag);
    return h.apply(null, args);
  };
};

const list = `a abbr address area article aside audio b base bdi bdo big blockquote body br
button canvas caption cite code col colgroup data datalist dd del details dfn
dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5
h6 head header hgroup hr html i iframe img input ins kbd keygen label legend li
link main map mark menu menuitem meta meter nav noscript object ol optgroup
option output p param picture pre progress q rp rt ruby s samp script section
select small source span strong style sub summary sup table tbody td textarea
tfoot th thead time title tr track u ul var video wbr`.split(' ');

export const DOM = list.reduce((base, t) => {base[t] = wrapTag(c);return base}, {});

export function unmountComponentAtNode(container) {
  render(h(() => null), container);
}

export function findDOMNode(component) {
  return component.base || null;
}

export function render(component, node, merge) {
  return PreactRender(component, node, merge || node.lastChild);
}

from preact.

developit avatar developit commented on April 30, 2024

I can certainly appreciate the small bundles (+ small modules) philosophy. I could definitely see these going into an ES5 wiki page, and potentially being their own modules too. For the DOM element factories, someone has already created a module that does what you are doing, so that's a start. He's using it for coffeescript, but the result is the same (usage without JSX).

Preact is definitely more geared towards the ES6 syntax, but there are lots of examples of using it via ES5 (or even ES3).

Another option is a wrapper library, similar to how I did preact-cycle. Basically just using Preact under the hood as a VDOM + Components renderer, but defining a new API on top of it.

If you venture down that road, I'm interested to see what you come up with!

- edit - just a thought: what about using something like Rollup to prune out the stuff you're not using from packages? Both preact and preact-compat support named imports and define jsnext:main so that Rollup can do tree shaking to remove dead code.

from preact.

mrbar42 avatar mrbar42 commented on April 30, 2024

@developit generally speaking, removing unused code and optimizing bundle is already done by webpack and tools as such.
more specifically for webpack, its done by uglify compressor, aggressive merge and dedup plugins.

are you talking strictly about redundant imports?

from preact.

developit avatar developit commented on April 30, 2024

Uglify's dead code elimination doesn't generally work across module boundaries when applied to Webpack's output, because modules export objects as their interfaces, and those objects count as references to ("uses of") otherwise unused internal functions. This is actually one of the reasons Preact has no internal namespace objects in its codebase - ES6-style imports via Rollup is currently the only way to flatten modules down to a single IIFE as part of a build.

My comment was mainly making use of the fact that Rollup looks for a jsnext:main property in the package.json of any modules you import, which allows it to traverse imports throughout the ES6 source of that dependency instead of bundling a mostly untouched ball of ES5. I don't have any great examples of this working because I tend to use LESS in my apps, which is not supported by Rollup (so I just use Webpack). This solution is also a bit brittle, since it relies on a single definition of what "jsnext" means (ES2015? JSX? who knows what's inside a given module).

I'm really hoping Webpack 2's tree shaking is at least as good as Rollup's. That would make it easy to import a library like preact, but entirely exclude parts of its functionality (eg: ES6 classes).

For my own use-cases, Preact is small enough that it's less than 50% of the total weight of my applications - once you build out a few modules and import some CSS, 3-4kb is unlikely to be much of a burden. Compared to the various front-end project setups I've had over the past decade, this is definitely the lightest. Previously I had been using dominictarr's hyperscript as a tiny h() implementation (no VDOM), but when I actually looked at the dependency sizes, it's roughly the same size as Preact, so I was giving up Virtual DOM and Components for no reason - crazy!

Last thing I wanted to mention was that you might benefit from setting up an intermediary module between your code and Preact + those addons you mentioned - something like import {..} from 'mrbar42-component';. I've been looking into this for some of my projects, and it seems like a nice way to insulate your implementation code (components, etc) from any library choices or API changes. Certainly it would provide a nice mechanism for you to import the couple bits you need from Preact (export { Component, render } from 'preact';), and then mix your own addons in as first-class named exports.

from preact.

Related Issues (20)

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.