Permalink
Browse files

Merge branch 'master' into event-case

  • Loading branch information...
developit committed May 23, 2018
2 parents 716e4bf + 7e49a91 commit 5a8d256008f8d0e38b1de955b6b979d2ffe2b859
@@ -0,0 +1 @@
test/ts/
@@ -0,0 +1,10 @@
[ignore]
<PROJECT_ROOT>/dist/.*
[include]
[libs]
[lints]
[options]
@@ -4,9 +4,15 @@
/dist
/_dev
/coverage
package-lock.json
/test/ts/**/*.js
# Additional bundles
/devtools.js
/devtools.js.map
/debug.js
/debug.js.map
# Editor and IDE configuration
.vscode/
.idea/
@@ -3,7 +3,7 @@ sudo: false
language: node_js
node_js:
- "6"
- "8"
cache:
directories:
@@ -20,18 +20,6 @@ install:
script:
- npm run build
- npm run test
- BROWSER=true COVERAGE=false FLAKEY=false PERFORMANCE=false npm run test:karma
- COVERAGE=true npm run test
- COVERAGE=false FLAKEY=false PERFORMANCE=false npm run test:karma
- ./node_modules/coveralls/bin/coveralls.js < ./coverage/lcov.info
# Necessary to compile native modules for io.js v3 or Node.js v4
env:
- CXX=g++-4.8
# Necessary to compile native modules for io.js v3 or Node.js v4
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- g++-4.8
@@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2017 Jason Miller
Copyright (c) 2015-present Jason Miller
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
117 README.md
@@ -3,7 +3,7 @@
<img alt="Preact" title="Preact" src="https://cdn.rawgit.com/developit/b4416d5c92b743dbaec1e68bc4c27cda/raw/3235dc508f7eb834ebf48418aea212a05df13db1/preact-logo-trans.svg" width="550">
</a>
</p>
<p align="center">Fast <b>3kB</b> alternative to React, with the same ES2015 API.</p>
<p align="center">Fast <b>3kB</b> alternative to React with the same modern API.</p>
**All the power of Virtual DOM components, without the overhead:**
@@ -31,7 +31,7 @@
- [Linked State](#linked-state)
- [Examples](#examples)
- [Extensions](#extensions)
- [Developer Tools](#developer-tools)
- [Debug Mode](#debug-mode)
- [Backers](#backers)
- [Sponsors](#sponsors)
- [License](#license)
@@ -49,6 +49,7 @@
[![travis](https://travis-ci.org/developit/preact.svg?branch=master)](https://travis-ci.org/developit/preact)
[![coveralls](https://img.shields.io/coveralls/developit/preact/master.svg)](https://coveralls.io/github/developit/preact)
[![gzip size](http://img.badgesize.io/https://unpkg.com/preact/dist/preact.min.js?compression=gzip)](https://unpkg.com/preact/dist/preact.min.js)
[![install size](https://packagephobia.now.sh/badge?p=preact)](https://packagephobia.now.sh/result?p=preact)
Preact supports modern browsers and IE9+:
@@ -60,38 +61,60 @@ Preact supports modern browsers and IE9+:
## Demos
#### Real-World Apps
- [**Preact Hacker News**](https://hn.kristoferbaxter.com) _([GitHub Project](https://github.com/kristoferbaxter/preact-hn))_
- [**Play.cash**](https://play.cash) :notes:
- [**ESBench**](http://esbench.com) is built using Preact.
- [**BigWebQuiz**](https://bigwebquiz.com) _([GitHub Project](https://github.com/jakearchibald/big-web-quiz))_
- [**Nectarine.rocks**](http://nectarine.rocks) _([GitHub Project](https://github.com/developit/nectarine))_ :peach:
- [**Documentation Viewer**](https://documentation-viewer.firebaseapp.com) _([GitHub Project](https://github.com/developit/documentation-viewer))_
- [**TodoMVC**](https://preact-todomvc.surge.sh) _([GitHub Project](https://github.com/developit/preact-todomvc))_
- [**Hacker News Minimal**](https://developit.github.io/hn_minimal/) _([GitHub Project](https://github.com/developit/hn_minimal))_
- [**Preact Boilerplate**](https://preact-boilerplate.surge.sh) _([GitHub Project](https://github.com/developit/preact-boilerplate))_ :zap:
- [**Preact Offline Starter**](https://preact-starter.now.sh) _([GitHub Project](https://github.com/lukeed/preact-starter))_ :100:
- [**Preact PWA**](https://preact-pwa.appspot.com/) _([GitHub Project](https://github.com/ezekielchentnik/preact-pwa))_ :hamburger:
- [**Preact Mobx Starter**](https://awaw00.github.io/preact-mobx-starter/) _([GitHub Project](https://github.com/awaw00/preact-mobx-starter))_ :sunny:
- [**Preact Redux Example**](https://github.com/developit/preact-redux-example) :star:
- [**OSS.Ninja**](https://oss.ninja) _([GitHub Project](https://github.com/developit/oss.ninja))_
- [**GuriVR**](https://gurivr.com) _([GitHub Project](https://github.com/opennewslabs/guri-vr))_
- [**Color Picker**](https://colors.now.sh) _([GitHub Project](https://github.com/lukeed/colors-app))_ :art:
- [**Rainbow Explorer**](https://use-the-platform.com/rainbow-explorer/) _([GitHub Project](https://github.com/vaneenige/rainbow-explorer/))_ :rainbow:
- [**Offline Gallery**](https://use-the-platform.com/offline-gallery/) _([GitHub Project](https://github.com/vaneenige/offline-gallery/))_ :balloon:
- [**Periodic Weather**](https://use-the-platform.com/periodic-weather/) _([GitHub Project](https://github.com/vaneenige/periodic-weather/))_ :sunny:
- [**Rugby News Board**](http://nbrugby.com) _[(GitHub Project)](https://github.com/rugby-board/rugby-board-node)_
- [**Preact Gallery**](https://preact.gallery/) an 8KB photo gallery PWA built using Preact.
- [**Rainbow Explorer**](https://use-the-platform.com/rainbow-explorer/) Preact app to translate real life color to digital color _([Github project](https://github.com/vaneenige/rainbow-explorer))_.
- [**YASCC**](https://carlosqsilva.github.io/YASCC/#/) Yet Another SoundCloud Client _([Github project](https://github.com/carlosqsilva/YASCC))_.
- [**Journalize**](https://preact-journal.herokuapp.com/) 14k offline-capable journaling PWA using preact. _([Github project](https://github.com/jpodwys/preact-journal))_.
#### Runnable Examples
- [**Flickr Browser**](http://codepen.io/developit/full/VvMZwK/) (@ CodePen)
- [**Animating Text**](http://codepen.io/developit/full/LpNOdm/) (@ CodePen)
- [**60FPS Rainbow Spiral**](http://codepen.io/developit/full/xGoagz/) (@ CodePen)
- [**Simple Clock**](http://jsfiddle.net/developit/u9m5x0L7/embedded/result,js/) (@ JSFiddle)
- [**3D + ThreeJS**](http://codepen.io/developit/pen/PPMNjd?editors=0010) (@ CodePen)
- [**Stock Ticker**](http://codepen.io/developit/pen/wMYoBb?editors=0010) (@ CodePen)
- [**Create your Own!**](https://jsfiddle.net/developit/rs6zrh5f/embedded/result/) (@ JSFiddle)
- [**Preact Coffeescript**](https://github.com/crisward/preact-coffee)
- [**GuriVR**](https://gurivr.com) _([GitHub Project](https://github.com/opennewslabs/guri-vr))_
- [*Create your Own!*](https://jsfiddle.net/developit/rs6zrh5f/embedded/result/) (@ JSFiddle)
### Starter Projects
- [**Preact Boilerplate**](https://preact-boilerplate.surge.sh) _([GitHub Project](https://github.com/developit/preact-boilerplate))_ :zap:
- [**Preact Offline Starter**](https://preact-starter.now.sh) _([GitHub Project](https://github.com/lukeed/preact-starter))_ :100:
- [**Preact PWA**](https://preact-pwa.appspot.com/) _([GitHub Project](https://github.com/ezekielchentnik/preact-pwa))_ :hamburger:
- [**Parcel + Preact + Unistore Starter**](https://github.com/hwclass/parcel-preact-unistore-starter)
- [**Preact Mobx Starter**](https://awaw00.github.io/preact-mobx-starter/) _([GitHub Project](https://github.com/awaw00/preact-mobx-starter))_ :sunny:
- [**Preact Redux Example**](https://github.com/developit/preact-redux-example) :star:
- [**Preact Redux/RxJS/Reselect Example**](https://github.com/continuata/preact-seed)
- [**V2EX Preact**](https://github.com/yanni4night/v2ex-preact)
- [**BigWebQuiz**](https://bigwebquiz.com/) _([GitHub Project](https://github.com/jakearchibald/big-web-quiz))_
- [**Color Picker**](https://colors.now.sh) _([GitHub Project](https://github.com/lukeed/colors-app))_ :art:
- [**Rainbow Explorer**](https://use-the-platform.com/rainbow-explorer/) _([GitHub Project](https://github.com/vaneenige/rainbow-explorer/))_ :rainbow:
- [**Offline Gallery**](https://use-the-platform.com/offline-gallery/) _([GitHub Project](https://github.com/vaneenige/offline-gallery/))_ :balloon:
- [**Periodic Weather**](https://use-the-platform.com/periodic-weather/) _([GitHub Project](https://github.com/vaneenige/periodic-weather/))_ :sunny:
- [**Play.cash**](https://play.cash) :notes:
- [**Rugby News Board**](http://nbrugby.com) _[(GitHub Project)](https://github.com/rugby-board/rugby-board-node)_
- [**Preact Coffeescript**](https://github.com/crisward/preact-coffee)
- [**Preact + TypeScript + Webpack**](https://github.com/k1r0s/bleeding-preact-starter)
- [**0 config => Preact + Poi**](https://github.com/k1r0s/preact-poi-starter)
- [**Zero configuration => Preact + Typescript + Parcel**](https://github.com/aalises/preact-typescript-parcel-starter)
---
## Libraries & Add-ons
- :raised_hands: [**preact-compat**](https://git.io/preact-compat): use any React library with Preact *([full example](http://git.io/preact-compat-example))*
- :twisted_rightwards_arrows: [**preact-context**](https://github.com/valotas/preact-context): React's `createContext` api for Preact
- :page_facing_up: [**preact-render-to-string**](https://git.io/preact-render-to-string): Universal rendering.
- :eyes: [**preact-render-spy**](https://github.com/mzgoddard/preact-render-spy): Enzyme-lite: Renderer with access to the produced virtual dom for testing.
- :loop: [**preact-render-to-json**](https://git.io/preact-render-to-json): Render for Jest Snapshot testing.
- :earth_americas: [**preact-router**](https://git.io/preact-router): URL routing for your components
- :bookmark_tabs: [**preact-markup**](https://git.io/preact-markup): Render HTML & Custom Elements as JSX & Components
@@ -111,12 +134,16 @@ Preact supports modern browsers and IE9+:
- :shaved_ice: [**preact-codemod**](https://github.com/vutran/preact-codemod): Transform your React code to Preact.
- :construction_worker: [**preact-helmet**](https://github.com/download/preact-helmet): A document head manager for Preact
- :necktie: [**preact-delegate**](https://github.com/NekR/preact-delegate): Delegate DOM events
- :art: [**preact-stylesheet-decorator**](https://github.com/k1r0s/preact-stylesheet-decorator): Add Scoped Stylesheets to your Preact Components
- :electric_plug: [**preact-routlet**](https://github.com/k1r0s/preact-routlet): Simple `Component Driven` Routing for Preact using ES7 Decorators
- :fax: [**preact-bind-group**](https://github.com/k1r0s/preact-bind-group): Preact Forms made easy, Group Events into a Single Callback
- :hatching_chick: [**preact-habitat**](https://github.com/zouhir/preact-habitat): Declarative Preact widgets renderer in any CMS or DOM host ([demo](https://codepen.io/zouhir/pen/brrOPB)).
#### UI Component Libraries
> Want to prototype something or speed up your development? Try one of these toolkits:
- [**preact-material-components**](https://github.com/prateekbh/preact-material-components): Material Design Components for Preact ([website](https://prateekbh.github.io/preact-material-components/))
- [**preact-material-components**](https://github.com/prateekbh/preact-material-components): Material Design Components for Preact ([website](https://material.preactjs.com/))
- [**preact-mdc**](https://github.com/BerndWessels/preact-mdc): Material Design Components for Preact ([demo](https://github.com/BerndWessels/preact-mdc-demo))
- [**preact-mui**](https://git.io/v1aVO): The MUI CSS Preact library.
- [**preact-photon**](https://git.io/preact-photon): build beautiful desktop UI with [photon](http://photonkit.com)
@@ -178,6 +205,14 @@ import preact from 'preact';
> ]
> }
> ```
> **For using Preact along with TypeScript add to `tsconfig.json`:**
>
> ```json
> {
> "jsx": "react",
> "jsxFactory": "h",
> }
> ```
### Rendering JSX
@@ -197,7 +232,7 @@ render((
), document.body);
```
This should seem pretty straightforward if you've used hyperscript or one of its many friends. If you're not, the short of it is that the h function import gets used in the final, transpiled code as a drop in replacement for React.createElement, and so needs to be imported even if you don't explicitly use it in the code you write. Also note that if you're the kind of person who likes writing your React code in "pure JavaScript" (you know who you are) you will need to use h(...) wherever you would otherwise use React.createElement.
This should seem pretty straightforward if you've used hyperscript or one of its many friends. If you're not, the short of it is that the `h()` function import gets used in the final, transpiled code as a drop in replacement for `React.createElement()`, and so needs to be imported even if you don't explicitly use it in the code you write. Also note that if you're the kind of person who likes writing your React code in "pure JavaScript" (you know who you are) you will need to use `h()` wherever you would otherwise use `React.createElement()`.
Rendering hyperscript with a virtual DOM is pointless, though. We want to render components and have them updated when data changes - that's where the power of virtual DOM diffing shines. :star2:
@@ -245,7 +280,7 @@ In order to have the clock's time update every second, we need to know when `<Cl
So, we want to have a 1-second timer start once the Component gets added to the DOM, and stop if it is removed. We'll create the timer and store a reference to it in `componentDidMount`, and stop the timer in `componentWillUnmount`. On each timer tick, we'll update the component's `state` object with a new time value. Doing this will automatically re-render the component.
So, we want to have a 1-second timer start once the Component gets added to the DOM, and stop if it is removed. We'll create the timer and store a reference to it in `componentDidMount()`, and stop the timer in `componentWillUnmount()`. On each timer tick, we'll update the component's `state` object with a new time value. Doing this will automatically re-render the component.
```js
import { h, render, Component } from 'preact';
@@ -313,7 +348,7 @@ class Foo extends Component {
While this achieves much better runtime performance, it's still a lot of unnecessary code to wire up state to UI.
Fortunately there is a solution, in the form of a module called [linkstate](https://github.com/developit/linkstate). Calling `linkState(component, 'text')` returns a function that accepts an Event and uses it's associated value to update the given property in your component's state. Calls to `linkState()` with the same arguments are cached, so there is no performance penalty. Here is the previous example rewritten using _Linked State_:
Fortunately there is a solution, in the form of a module called [linkstate](https://github.com/developit/linkstate). Calling `linkState(component, 'text')` returns a function that accepts an Event and uses its associated value to update the given property in your component's state. Calls to `linkState()` with the same arguments are cached, so there is no performance penalty. Here is the previous example rewritten using _Linked State_:
```js
import linkState from 'linkstate';
@@ -410,25 +445,51 @@ class MixedComponent extends Component {
}
```
## Developer Tools
## Debug Mode
You can inspect and modify the state of your Preact UI components at runtime using the
[React Developer Tools](https://github.com/facebook/react-devtools) browser extension.
1. Install the [React Developer Tools](https://github.com/facebook/react-devtools) extension
2. Import the "preact/devtools" module in your app
3. Reload and go to the 'React' tab in the browser's development tools
2. Import the "preact/debug" module in your app
3. Set `process.env.NODE_ENV` to 'development'
4. Reload and go to the 'React' tab in the browser's development tools
```js
import { h, Component, render } from 'preact';
// Enable devtools. You can reduce the size of your app by only including this
// Enable debug mode. You can reduce the size of your app by only including this
// module in development builds. eg. In Webpack, wrap this with an `if (module.hot) {...}`
// check.
require('preact/devtools');
require('preact/debug');
```
### Runtime Error Checking
To enable debug mode, you need to set `process.env.NODE_ENV=development`. You can do this
with webpack via a builtin plugin.
```js
// webpack.config.js
// Set NODE_ENV=development to enable error checking
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('development')
}
});
```
When enabled, warnings are logged to the console when undefined components or string refs
are detected.
### Developer Tools
If you only want to include devtool integration, without runtime error checking, you can
replace `preact/debug` in the above example with `preact/devtools`. This option doesn't
require setting `NODE_ENV=development`.
## Backers
@@ -6,12 +6,12 @@ export default {
format: 'umd',
file: 'devtools.js',
name: 'preactDevTools',
sourcemap: true
sourcemap: true,
globals: {
preact: 'preact'
}
},
external: ['preact'],
globals: {
preact: 'preact'
},
plugins: [
babel({
sourceMap: true,
@@ -3,13 +3,13 @@ import babel from 'rollup-plugin-babel';
import memory from 'rollup-plugin-memory';
export default {
strict: true,
input: 'src/preact.js',
output: {
format: 'iife',
file: 'dist/preact.dev.js',
name: 'preact',
sourcemap: true
sourcemap: true,
strict: true
},
plugins: [
memory({
@@ -1,7 +1,8 @@
/* eslint-disable no-console */
if (process.env.NODE_ENV === 'development') {
const { options } = require('preact');
const preact = require('preact');
const options = preact.options;
const oldVnodeOption = options.vnode;
options.vnode = function(vnode) {
@@ -50,6 +51,29 @@ if (process.env.NODE_ENV === 'development') {
if (oldVnodeOption) oldVnodeOption.call(this, vnode);
};
try {
const oldRender = preact.render;
preact.render = function (vnode, parent, merge) {
if (parent == null && merge == null) {
// render(vnode, parent, merge) can't have both parent and merge be undefined
console.error('The "containerNode" or "replaceNode" is not defined in the render method. ' +
'Component: \n\n' + serializeVNode(vnode));
}
else if (parent == merge) {
// if parent == merge, it doesn't reason well and would cause trouble when preact
// tries to update or replace that 'replaceNode' element
console.error(
'The "containerNode" and "replaceNode" are the same in render method, ' +
'when the "replaceNode" DOM node is expected to be a child of "containerNode". ' +
'docs-ref: https://preactjs.com/guide/api-reference#-preact-render-. Component: \n\n' +
serializeVNode(vnode)
);
}
return oldRender(vnode, parent, merge);
};
}
catch (e) {}
const inspectChildren = (children, inspect) => {
if (!Array.isArray(children)) {
children = [children];
@@ -246,13 +246,16 @@ function createDevToolsBridge() {
/** Notify devtools that a component has been updated with new props/state. */
const componentUpdated = component => {
const prevRenderedChildren = [];
visitNonCompositeChildren(instanceMap.get(component), childInst => {
prevRenderedChildren.push(childInst);
});
let instance = instanceMap.get(component);
if (instance) {
visitNonCompositeChildren(instance, childInst => {
prevRenderedChildren.push(childInst);
});
}
// Notify devtools about updates to this component and any non-composite
// children
const instance = updateReactComponent(component);
instance = updateReactComponent(component);
Reconciler.receiveComponent(instance);
visitNonCompositeChildren(instance, childInst => {
if (!childInst._inDevTools) {
@@ -327,6 +330,7 @@ function isRootComponent(component) {
* @param {(Component) => void} visitor
*/
function visitNonCompositeChildren(component, visitor) {
if (!component) return;
if (component._renderedComponent) {
if (!component._renderedComponent._component) {
visitor(component._renderedComponent);
Oops, something went wrong.

0 comments on commit 5a8d256

Please sign in to comment.