From beb6c2bc8276eacdc700d1db61c1c15b9a421d08 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9ry=20Debongnie?= Date: Tue, 27 Aug 2019 14:46:37 +0200 Subject: [PATCH] [DOC] improve readme and comparison closes #244 --- README.md | 19 +++++++++----- doc/comparison.md | 66 +++++++++++++++++++++++++++++++++++++---------- 2 files changed, 66 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 317c534e..bf5b5b10 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,20 @@ _A web framework for structured, dynamic and maintainable applications_ ## Project Overview -The Odoo Web Library (OWL) is a small -UI framework intended to be the basis for the [Odoo](https://www.odoo.com/) Web Client, and hopefully many -other Odoo related projects. OWL's main feature is a _declarative component system_, with QWeb as a template engine, asynchronous rendering, and an underlying virtual dom. +The Odoo Web Library (OWL) is a small (~16kb gzipped) UI framework intended to be the basis for +the [Odoo](https://www.odoo.com/) Web Client, and hopefully many other Odoo +related projects. OWL's main features are: + +- a _declarative component system_, (template based, with asynchronous rendering and a virtual dom) +- a store implementation (for state management) +- a small frontend router **Try it online!** An online playground is available at [https://odoo.github.io/owl/playground](https://odoo.github.io/owl/playground) to let you experiment with the OWL framework. ## OWL's Design Principles OWL is designed to be used in highly dynamic applications where changing -requirements are common, code needs to be maintained by large teams. +requirements are common and code needs to be maintained by large teams. - **XML based**: templates are based on the XML format, which allows interesting applications. For example, they could be stored in a database and modified @@ -26,8 +30,11 @@ requirements are common, code needs to be maintained by large teams. for various reasons (security/deployment/dynamic modules/specific assets tools), it is not ok to use standard web tools based on `npm`. -Owl is not designed to be fast or small (even though it is quite good on those -two topics). If you are interested in a comparison with React or Vue, you will +Owl is not designed to be fast nor small (even though it is quite good on those +two topics). It is a no nonsense framework to build applications. There is only +one way to define components (with classes). + +If you are interested in a comparison with React or Vue, you will find some more information [here](doc/comparison.md). ## Example diff --git a/doc/comparison.md b/doc/comparison.md index 6c957fda..c247565e 100644 --- a/doc/comparison.md +++ b/doc/comparison.md @@ -10,6 +10,7 @@ discussed, feel free to open an issue/submit a PR to correct this text. ## Content - [Size](#size) +- [Class Based](#class-based) - [Tooling/Build Step](#toolingbuild-step) - [Templating](#templating) - [Asynchronous rendering](#asynchronous-rendering) @@ -21,12 +22,23 @@ discussed, feel free to open an issue/submit a PR to correct this text. OWL is intended to be small and to work at a slightly lower level of abstraction than React and Vue. Also, jQuery is not the same kind of framework, but it is interesting to compare. -| Framework | Size (minified) | Size (minified, gzipped) | -| ------------------------ | --------------- | ------------------------ | -| OWL | 32kb | 11kb | -| Vue + VueX | | 30kb | -| React + ReactDOM + Redux | | 40kb | -| jQuery | 86kb | 30kb | +| Framework | Size (minified, gzipped) | +| ------------------------ | ------------------------ | +| OWL | 16kb | +| Vue + VueX | 30kb | +| React + ReactDOM + Redux | 40kb | +| jQuery | 30kb | + +## Class Based + +Both React and Vue moved away from defining components with classes. They prefer +a more functional approach, in particular, with the new `hooks` mechanisms. + +This has some advantages and disadvantages. But the end result is that React +and Vue both offers multiple different ways of defining new components. In +contrast, Owl has only one mechanism: class-based components. We believe that Owl +components are fast enough for all our usecases, and making it as simple as +possible for developers is more valuable (for us). ## Tooling/Build step @@ -45,7 +57,7 @@ components, which also necessitate a build step. On the flipside, external tooling may make it harder to use in some case, but it also brings a lot of benefits. And React/Vue have both a large ecosystem. -### Templating +## Templating OWL uses its own QWeb engine, which compiles templates on the frontend, as they are needed. This is extremely convenient for our use case, in @@ -128,8 +140,10 @@ by getters/setters. With that, it can notify components whenever the state that they read was changed. Owl is closer to vue: it also tracks magically the state properties, but it does -only increment a counter whenever it changes (and a _deep_ counter for each of -its parents). This assumes that the state is actually a tree. +only increment an internal counter whenever it changes. Note that it is done +with a `Proxy`, which means that it is totally transparent to the developers. +Adding new keys is supported. Once any part of the state has been changed, a +rendering is scheduled in the next microtask tick (promise queue). ## State Management @@ -190,7 +204,33 @@ keeps track of who get data, and retrigger a render when it was changed. **Owl** -Owl store is a little bit like a mix of redux and vuex: it has mutations and -actions, like VueX, it keeps track of the state changes, but it does not notify -a component when the state changes. Instead, components need to connect to the -store like in redux, with a function that will listen to the relevant state. +Owl store is a little bit like a mix of redux and vuex: it has actions (but not +mutations), and like VueX, it keeps track of the state changes. However, it does +not notify a component when the state changes. Instead, components need to connect +to the store like in redux, by inheriting the `ConnectedComponent` class. + +```javascript +const actions = { + increment({ state }, val) { + state.counter += val; + } +}; + +const state = { + counter: 0 +}; +const store = new owl.Store({ state, actions }); + +class Counter extends owl.ConnectedComponent { + static mapStoreToProps(state) { + return { + value: state.counter + }; + } + increment() { + this.env.store.dispatch("increment"); + } +} + +const counter = new Counter({ store, qweb }); +``` \ No newline at end of file