{"action":"created","comment":{"url":"https://api.github.com/repos/dojo/dojo.io/pulls/comments/152273743","pull_request_review_id":78103592,"id":152273743,"diff_hunk":"@@ -0,0 +1,263 @@\n+---\n+title: Dojo 2 Beta 4\n+date: 2017-11-17 18:00:00\n+authorId: kitsonk\n+featured_image: featured.png\n+---\n+\n+The Beta 4 Release of Dojo 2 puts us on a clear path to releasing Dojo 2.  It has several significant changes and updates.\n+\n+{% asset_img featured.png feature-full %}\n+\n+<!-- more -->\n+\n+## Getting Beta 4\n+\n+Beta 4 is currently tagged as `latest` in npm, so all just updating to the latest version will provide you with Beta 4.  We also have a release tag of `beta4` in npm if you want to focus just on using Beta 4.\n+\n+With Beta 3, we revised our package versions to make it easier to keep a compatible set of packes.  We are releasing all the pre-release versions of Dojo 2 packages under major version `0`, but are introducing breaking changes in the minor release (e.g. `0.2.0` has breaking changes from `0.1.0`).  The versions we publish to npm rely upon a minor range.  You will see that some packages for Beta 4 are `0.3.#` and some are `0.2.#`, but they all depend on a range of version they know they are compatible with.  This means you don't have to rely upon a release tag.  So ideally you would want to ensure if you are managing your dependencies directly, you depend upon a minor release (e.g. `~0.2.0`) for packages.\n+\n+As we make releases of packages in anticipation of Beta 5, we will not publish those packages to `latest` until we release Beta 5.\n+\n+## Integrated virtual DOM\n+\n+This was the biggest fundamental change for the Beta 4 release.  Instead of depending on the [Maquette](https://maquettejs.org/) virtual DOM library, we realised that our specialised requirements and needs were better solved in the medium and long term by integrating it directly.  So in Beta 4 we have replaced Maquette with `@dojo/widget-core/vdom`.\n+\n+This has allowed us to directly merge our abstraction of widgets and virtual DOM nodes with the virtual DOM nodes that get rendered to the DOM.  This increases the performance of the widgeting system, but also allowed us to make other performance and memory improvements to the widgeting system.\n+\n+This alone would not have had an effect on users of Dojo 2, but it allowed us to address a whole list of features we desired and refactoring of code that introduced some significant **breaking changes** in Beta 4.\n+\n+## Virtual DOM classes\n+\n+We felt that one of the biggest usability issues we had with Dojo 2 had to do with dealing with classes.  In Beta 4, we have changed this significantly, and while it is a **breaking change** we think the end result is _a lot_ more usable.\n+\n+Previously, `classes` were actually an object map of keys with a boolean value.  If you were using the theming system, you would use a function to specify your classes in a more functional way, which would generate a memoised map for you.  If you weren't you would have to do this yourself.  While it might be ok to author, it was really difficult to test.  It would look something like this:\n+\n+```typescript\n+import { v } from '@dojo/widget-core/d';\n+import WidgetBase from '@dojo/widget-core/WidgetBase';\n+import ThemeableMixin, { theme } from '@dojo/widget-core/mixins/Themeable';\n+import * as css from './styles/mywidget.m.css';\n+\n+const ThemeableBase = ThemeableMixin(WidgetBase);\n+\n+@theme(css)\n+export default class MyWidget extends ThemeableBase {\n+    protected render() {\n+        return v('div', {\n+            classes: this.classes(css.root).fixed(css.rootFixed)\n+        }, [ 'Hello world!' ])\n+    }\n+}\n+```\n+\n+With the changes in Beta 4, this gets written as:\n+\n+```typescript\n+import { v } from '@dojo/widget-core/d';\n+import WidgetBase from '@dojo/widget-core/WidgetBase';\n+import ThemedMixin, { theme } from '@dojo/widget-core/mixins/Themed';\n+import * as css from './styles/mywidget.m.css';\n+\n+const ThemedBase = ThemedMixin(WidgetBase);\n+\n+@theme(css)\n+export default class MyWidget extends ThemedBase {\n+    protected render() {\n+        return v('div', {\n+            classes: [ this.theme(css.root), css.rootFixed ]\n+        }, [ 'Hello world!' ])\n+    }\n+}\n+```\n+\n+The `classes` property is now just an array of strings.  Also we think that the mixed in method `theme()` is a lot more clear on what you are doing instead of `classes()`.  _Fixed_ classes are just simply added to the array, instead of being supplied to a chained function.","path":"site/source/_posts/2017/11/17-Dojo-2-Beta-4/Dojo-2-Beta-4.md","position":74,"original_position":74,"commit_id":"728fe02e509708c28a4f7353a79a36efc4718114","original_commit_id":"728fe02e509708c28a4f7353a79a36efc4718114","user":{"login":"dylans","id":97291,"avatar_url":"https://avatars1.githubusercontent.com/u/97291?v=4","gravatar_id":"","url":"https://api.github.com/users/dylans","html_url":"https://github.com/dylans","followers_url":"https://api.github.com/users/dylans/followers","following_url":"https://api.github.com/users/dylans/following{/other_user}","gists_url":"https://api.github.com/users/dylans/gists{/gist_id}","starred_url":"https://api.github.com/users/dylans/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dylans/subscriptions","organizations_url":"https://api.github.com/users/dylans/orgs","repos_url":"https://api.github.com/users/dylans/repos","events_url":"https://api.github.com/users/dylans/events{/privacy}","received_events_url":"https://api.github.com/users/dylans/received_events","type":"User","site_admin":false},"body":"Also the mixed in `theme()` method more clearly express intent over the former `classes()` name.","created_at":"2017-11-21T13:27:47Z","updated_at":"2017-11-21T13:31:54Z","html_url":"https://github.com/dojo/dojo.io/pull/327#discussion_r152273743","pull_request_url":"https://api.github.com/repos/dojo/dojo.io/pulls/327","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/comments/152273743"},"html":{"href":"https://github.com/dojo/dojo.io/pull/327#discussion_r152273743"},"pull_request":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/327"}}},"pull_request":{"url":"https://api.github.com/repos/dojo/dojo.io/pulls/327","id":153629791,"html_url":"https://github.com/dojo/dojo.io/pull/327","diff_url":"https://github.com/dojo/dojo.io/pull/327.diff","patch_url":"https://github.com/dojo/dojo.io/pull/327.patch","issue_url":"https://api.github.com/repos/dojo/dojo.io/issues/327","number":327,"state":"open","locked":false,"title":"Add back the Beta 4 blog","user":{"login":"kitsonk","id":1282577,"avatar_url":"https://avatars0.githubusercontent.com/u/1282577?v=4","gravatar_id":"","url":"https://api.github.com/users/kitsonk","html_url":"https://github.com/kitsonk","followers_url":"https://api.github.com/users/kitsonk/followers","following_url":"https://api.github.com/users/kitsonk/following{/other_user}","gists_url":"https://api.github.com/users/kitsonk/gists{/gist_id}","starred_url":"https://api.github.com/users/kitsonk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kitsonk/subscriptions","organizations_url":"https://api.github.com/users/kitsonk/orgs","repos_url":"https://api.github.com/users/kitsonk/repos","events_url":"https://api.github.com/users/kitsonk/events{/privacy}","received_events_url":"https://api.github.com/users/kitsonk/received_events","type":"User","site_admin":false},"body":"This will re-instate the Beta 4 Blog whenever it is the appropriate time to release it.\r\n\r\nResolves #303 ","created_at":"2017-11-20T13:31:50Z","updated_at":"2017-11-21T13:31:55Z","closed_at":null,"merged_at":null,"merge_commit_sha":"2d28428bb60af7495d3f9d98a7516f4779669155","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/dojo/dojo.io/pulls/327/commits","review_comments_url":"https://api.github.com/repos/dojo/dojo.io/pulls/327/comments","review_comment_url":"https://api.github.com/repos/dojo/dojo.io/pulls/comments{/number}","comments_url":"https://api.github.com/repos/dojo/dojo.io/issues/327/comments","statuses_url":"https://api.github.com/repos/dojo/dojo.io/statuses/728fe02e509708c28a4f7353a79a36efc4718114","head":{"label":"kitsonk:beta4-blog-again","ref":"beta4-blog-again","sha":"728fe02e509708c28a4f7353a79a36efc4718114","user":{"login":"kitsonk","id":1282577,"avatar_url":"https://avatars0.githubusercontent.com/u/1282577?v=4","gravatar_id":"","url":"https://api.github.com/users/kitsonk","html_url":"https://github.com/kitsonk","followers_url":"https://api.github.com/users/kitsonk/followers","following_url":"https://api.github.com/users/kitsonk/following{/other_user}","gists_url":"https://api.github.com/users/kitsonk/gists{/gist_id}","starred_url":"https://api.github.com/users/kitsonk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kitsonk/subscriptions","organizations_url":"https://api.github.com/users/kitsonk/orgs","repos_url":"https://api.github.com/users/kitsonk/repos","events_url":"https://api.github.com/users/kitsonk/events{/privacy}","received_events_url":"https://api.github.com/users/kitsonk/received_events","type":"User","site_admin":false},"repo":{"id":87395981,"name":"dojo.io","full_name":"kitsonk/dojo.io","owner":{"login":"kitsonk","id":1282577,"avatar_url":"https://avatars0.githubusercontent.com/u/1282577?v=4","gravatar_id":"","url":"https://api.github.com/users/kitsonk","html_url":"https://github.com/kitsonk","followers_url":"https://api.github.com/users/kitsonk/followers","following_url":"https://api.github.com/users/kitsonk/following{/other_user}","gists_url":"https://api.github.com/users/kitsonk/gists{/gist_id}","starred_url":"https://api.github.com/users/kitsonk/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kitsonk/subscriptions","organizations_url":"https://api.github.com/users/kitsonk/orgs","repos_url":"https://api.github.com/users/kitsonk/repos","events_url":"https://api.github.com/users/kitsonk/events{/privacy}","received_events_url":"https://api.github.com/users/kitsonk/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/kitsonk/dojo.io","description":"Dojo 2 - source for the Dojo 2 website","fork":true,"url":"https://api.github.com/repos/kitsonk/dojo.io","forks_url":"https://api.github.com/repos/kitsonk/dojo.io/forks","keys_url":"https://api.github.com/repos/kitsonk/dojo.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kitsonk/dojo.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kitsonk/dojo.io/teams","hooks_url":"https://api.github.com/repos/kitsonk/dojo.io/hooks","issue_events_url":"https://api.github.com/repos/kitsonk/dojo.io/issues/events{/number}","events_url":"https://api.github.com/repos/kitsonk/dojo.io/events","assignees_url":"https://api.github.com/repos/kitsonk/dojo.io/assignees{/user}","branches_url":"https://api.github.com/repos/kitsonk/dojo.io/branches{/branch}","tags_url":"https://api.github.com/repos/kitsonk/dojo.io/tags","blobs_url":"https://api.github.com/repos/kitsonk/dojo.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kitsonk/dojo.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kitsonk/dojo.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/kitsonk/dojo.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kitsonk/dojo.io/statuses/{sha}","languages_url":"https://api.github.com/repos/kitsonk/dojo.io/languages","stargazers_url":"https://api.github.com/repos/kitsonk/dojo.io/stargazers","contributors_url":"https://api.github.com/repos/kitsonk/dojo.io/contributors","subscribers_url":"https://api.github.com/repos/kitsonk/dojo.io/subscribers","subscription_url":"https://api.github.com/repos/kitsonk/dojo.io/subscription","commits_url":"https://api.github.com/repos/kitsonk/dojo.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/kitsonk/dojo.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/kitsonk/dojo.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/kitsonk/dojo.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/kitsonk/dojo.io/contents/{+path}","compare_url":"https://api.github.com/repos/kitsonk/dojo.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kitsonk/dojo.io/merges","archive_url":"https://api.github.com/repos/kitsonk/dojo.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kitsonk/dojo.io/downloads","issues_url":"https://api.github.com/repos/kitsonk/dojo.io/issues{/number}","pulls_url":"https://api.github.com/repos/kitsonk/dojo.io/pulls{/number}","milestones_url":"https://api.github.com/repos/kitsonk/dojo.io/milestones{/number}","notifications_url":"https://api.github.com/repos/kitsonk/dojo.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kitsonk/dojo.io/labels{/name}","releases_url":"https://api.github.com/repos/kitsonk/dojo.io/releases{/id}","deployments_url":"https://api.github.com/repos/kitsonk/dojo.io/deployments","created_at":"2017-04-06T06:49:22Z","updated_at":"2017-11-16T16:47:24Z","pushed_at":"2017-11-20T13:26:07Z","git_url":"git://github.com/kitsonk/dojo.io.git","ssh_url":"git@github.com:kitsonk/dojo.io.git","clone_url":"https://github.com/kitsonk/dojo.io.git","svn_url":"https://github.com/kitsonk/dojo.io","homepage":"","size":6115,"stargazers_count":0,"watchers_count":0,"language":"CSS","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"archived":false,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"dojo:master","ref":"master","sha":"0225c499226b46a707b04a168e09f267a64dc60b","user":{"login":"dojo","id":86896,"avatar_url":"https://avatars2.githubusercontent.com/u/86896?v=4","gravatar_id":"","url":"https://api.github.com/users/dojo","html_url":"https://github.com/dojo","followers_url":"https://api.github.com/users/dojo/followers","following_url":"https://api.github.com/users/dojo/following{/other_user}","gists_url":"https://api.github.com/users/dojo/gists{/gist_id}","starred_url":"https://api.github.com/users/dojo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dojo/subscriptions","organizations_url":"https://api.github.com/users/dojo/orgs","repos_url":"https://api.github.com/users/dojo/repos","events_url":"https://api.github.com/users/dojo/events{/privacy}","received_events_url":"https://api.github.com/users/dojo/received_events","type":"Organization","site_admin":false},"repo":{"id":78557857,"name":"dojo.io","full_name":"dojo/dojo.io","owner":{"login":"dojo","id":86896,"avatar_url":"https://avatars2.githubusercontent.com/u/86896?v=4","gravatar_id":"","url":"https://api.github.com/users/dojo","html_url":"https://github.com/dojo","followers_url":"https://api.github.com/users/dojo/followers","following_url":"https://api.github.com/users/dojo/following{/other_user}","gists_url":"https://api.github.com/users/dojo/gists{/gist_id}","starred_url":"https://api.github.com/users/dojo/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dojo/subscriptions","organizations_url":"https://api.github.com/users/dojo/orgs","repos_url":"https://api.github.com/users/dojo/repos","events_url":"https://api.github.com/users/dojo/events{/privacy}","received_events_url":"https://api.github.com/users/dojo/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/dojo/dojo.io","description":"Dojo 2 - source for the Dojo 2 website","fork":false,"url":"https://api.github.com/repos/dojo/dojo.io","forks_url":"https://api.github.com/repos/dojo/dojo.io/forks","keys_url":"https://api.github.com/repos/dojo/dojo.io/keys{/key_id}","collaborators_url":"https://api.github.com/repos/dojo/dojo.io/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/dojo/dojo.io/teams","hooks_url":"https://api.github.com/repos/dojo/dojo.io/hooks","issue_events_url":"https://api.github.com/repos/dojo/dojo.io/issues/events{/number}","events_url":"https://api.github.com/repos/dojo/dojo.io/events","assignees_url":"https://api.github.com/repos/dojo/dojo.io/assignees{/user}","branches_url":"https://api.github.com/repos/dojo/dojo.io/branches{/branch}","tags_url":"https://api.github.com/repos/dojo/dojo.io/tags","blobs_url":"https://api.github.com/repos/dojo/dojo.io/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/dojo/dojo.io/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/dojo/dojo.io/git/refs{/sha}","trees_url":"https://api.github.com/repos/dojo/dojo.io/git/trees{/sha}","statuses_url":"https://api.github.com/repos/dojo/dojo.io/statuses/{sha}","languages_url":"https://api.github.com/repos/dojo/dojo.io/languages","stargazers_url":"https://api.github.com/repos/dojo/dojo.io/stargazers","contributors_url":"https://api.github.com/repos/dojo/dojo.io/contributors","subscribers_url":"https://api.github.com/repos/dojo/dojo.io/subscribers","subscription_url":"https://api.github.com/repos/dojo/dojo.io/subscription","commits_url":"https://api.github.com/repos/dojo/dojo.io/commits{/sha}","git_commits_url":"https://api.github.com/repos/dojo/dojo.io/git/commits{/sha}","comments_url":"https://api.github.com/repos/dojo/dojo.io/comments{/number}","issue_comment_url":"https://api.github.com/repos/dojo/dojo.io/issues/comments{/number}","contents_url":"https://api.github.com/repos/dojo/dojo.io/contents/{+path}","compare_url":"https://api.github.com/repos/dojo/dojo.io/compare/{base}...{head}","merges_url":"https://api.github.com/repos/dojo/dojo.io/merges","archive_url":"https://api.github.com/repos/dojo/dojo.io/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/dojo/dojo.io/downloads","issues_url":"https://api.github.com/repos/dojo/dojo.io/issues{/number}","pulls_url":"https://api.github.com/repos/dojo/dojo.io/pulls{/number}","milestones_url":"https://api.github.com/repos/dojo/dojo.io/milestones{/number}","notifications_url":"https://api.github.com/repos/dojo/dojo.io/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/dojo/dojo.io/labels{/name}","releases_url":"https://api.github.com/repos/dojo/dojo.io/releases{/id}","deployments_url":"https://api.github.com/repos/dojo/dojo.io/deployments","created_at":"2017-01-10T17:40:20Z","updated_at":"2017-10-27T18:48:18Z","pushed_at":"2017-11-20T20:11:00Z","git_url":"git://github.com/dojo/dojo.io.git","ssh_url":"git@github.com:dojo/dojo.io.git","clone_url":"https://github.com/dojo/dojo.io.git","svn_url":"https://github.com/dojo/dojo.io","homepage":"","size":23264,"stargazers_count":7,"watchers_count":7,"language":"CSS","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":26,"mirror_url":null,"archived":false,"open_issues_count":89,"forks":26,"open_issues":89,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/327"},"html":{"href":"https://github.com/dojo/dojo.io/pull/327"},"issue":{"href":"https://api.github.com/repos/dojo/dojo.io/issues/327"},"comments":{"href":"https://api.github.com/repos/dojo/dojo.io/issues/327/comments"},"review_comments":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/327/comments"},"review_comment":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/dojo/dojo.io/pulls/327/commits"},"statuses":{"href":"https://api.github.com/repos/dojo/dojo.io/statuses/728fe02e509708c28a4f7353a79a36efc4718114"}},"author_association":"OWNER"}}
{"actor":{"display_login":"dylans"}}