Dojo version 6 contains several major ergonomic changes along with a few breaking changes to be aware of when migrating from version 5. As much as possible, these updates are automated by using the @dojo/cli-upgrade-app CLI command. When the upgrade command cannot automate the upgrade, helpful hints and information are provided in the output to guide you through the manual upgrade process for these changes.
To install the upgrade command, run the following from the project root:
npm install @dojo/cli-upgrade-app --no-save
To perform the migration, run the following command from the project root. The Dojo migration tool should automatically detect the necessary migration from your package.json.
dojo upgrade app
If you are upgrading from a version before 5.0.0, please first see the previous migration guides for more details.
- The
@dojo/clishould be updated to version 6.0.0, along with all the commands used by the project. - If your project is using
@dojo/widgetsand@dojo/interop, these packages also require upgrading to version 6.0.0.
Note: The migration tool may create line lengths that violate your projects linting rules, be sure to run your linter and manually fix any linting rule violations.
As part of the improvements made for Dojo version 6, the minimum version of TypeScript has changed to 3.4.5. This change is necessary to support the typings required by the new functional widgets and middleware.
Dojo version 6 should be fully compatible with 3.4.5 and newer. Updating a project's dependency should satisfy Dojo, however you may find changes are required in your project code to meet TypeScript additional checking added in newer versions.
In addition to upgrading TypeScript, the complementary library tslib should be upgraded to ~1.9.1.
has and widget-core merged with core
As part of Dojo version 6 we have continued to re-organize @dojo/framework's module structure. As a result, @dojo/framework/widget-core and @dojo/framework/has have been merged with @dojo/framework/core.
The @dojo/cli-upgrade-app command should automatically migrate your project's imports. Please let us know if you encounter any issues.
@dojo/framework/widget-core/d and @dojo/framework/widget-core/tsx moved to @dojo/framework/core/vdom
In addition to merging widget-core with core, the d and tsx exports have been moved into vdom.
Note: There is one exception, decorate has been moved from d to util.
The @dojo/cli-upgrade-app command should automatically migrate your project's imports. please let us know if you encounter any issues.
As part of Dojo version 6 we have continued to re-organize @dojo/framework's module structure. As a result, @dojo/framework/widget-core and @dojo/framework/has have merged into @dojo/framework/core.
The @dojo/cli-upgrade-app command should automatically migrate your project's imports. Please let us know if you encounter any issues.
In previous versions of Dojo, virtual DOM nodes created by widgets get decorated with additional metadata such as bind. These extra properties were never meant to get exposed to the end user. However, as this metadata was added by mutating the DNodes, they were inadvertently exposed. As of Dojo version 6, we no longer mutate DNodes to ensure that this implementation detail of the framework is not exposed to the end user.
We don't envisage this change affecting many projects, however, if it does please raise an issue with your use case so we can investigate an officially supported mechanism.
The replace method has been renamed to replaceChildren with the introduction of a new API for replace that will replace a single node of an assertion template and not target just the children.
Additionally we have deprecated passing an array of DNode to APIs that replace/modify children in favor of a factory function to ensure that the DNode are immutable. The existing API is still supported, but you will receive a warning and we recommend changing to use a function as the array API is likely to be removed in a future Dojo release.
const base = assertionTemplate(() => {
return v('div', { key: 'div' }, [v('div')]);
});
// existing API
base.setChildren('@div', [v('span')]);
// recommended API
base.setChildren('@div', () => [v('span')]);In Dojo 6, the Dojo router has changed from extending the QueueingEvented as a way to enable users to subscribe to events that occur when the router started automatically. Instead an extra option is available, autostart which can be used to control when the router actually starts up. This is defaulted to true as this is the most common use case. For scenarios where the initial routing events need to be captured, autostart can be set to false and then .start() explicitly called on the router instance.
import Registry from '@dojo/framework/core/Registry';
import { registerRouterInjector } from '@dojo/framework/routing/RouterInjector';
import routes from './routes.ts';
const registry = new Registry();
const router = registerRouterInjector(routes, registry, { autostart: false });
// wire up to any router events
router.on('nav', () => {
// do something on router nav, this will catch the initial routing event
});
router.start();The QueueingEvented module has been removed from Dojo, this was only ever intended to be used internally and not something that we recommend using externally.
The transition strategy for the virtual DOM renderer is no longer implicitly imported in vdom. To use VNode transitions that leverage exitAnimation or enterAnimation, the transition strategy needs to get explicitly imported and passed to the applications .mount call.
import renderer, { w } from '@dojo/framework/core/vdom';
import transition from '@dojo/framework/core/animations/cssTransitions';
const r = renderer(() => w(App, {}));
r.mount({ transition });The VNodeProperties interface has been updated, changing the event argument of event handlers from optional to required. The interface also now detects the event's target type based on the tag name.
You may experience compilation errors for any occurrences in your project where the event argument has been explicitly typed as optional, for example:
render() {
return v('button', { onclick: (event?: MouseEvent) => {
} });
}Removing ? should resolve any compilation errors:
render() {
return v('button', { onclick: (event: MouseEvent) => {
} });
}Work has begun on adding helperText and a consistent validation approach to @dojo/widgets.
One of the knock-on effects of adding helperText is that labelAfter no longer makes sense as it would clash with the helperText; as such, all labels will appear before / above the widget they belong to. If you with to place the label elsewhere, you can do so by manually creating one and using the for property to link it to your input.
The change from passing invalid to valid was both to remove the frequent use of negatives in widgets and to align better with the onValidate callback naming.
Finally, we have started writing our new widgets in TSX. We may convert existing widgets over to use TSX in future if we make any extensive changes to them.
invalidlabelAfter
customValidator?: (value: string) => { valid?: boolean; message?: string; } | void;onValidate?: (valid: boolean | undefined, message: string) => void;valid?: boolean | { valid: boolean; message: string; }leading?: () => DNode;trailing?: () => DNode;helperText?: string;
This widget has been removed in favour of the new leading / trailing properties on @dojo/text-input. We plan to adopt this approach for other widgets such as select / combobox etc in future.
To create a text-input with a leading dollar sign for example:
<TextInput leading={() => <span>$</span>} />openclass alongside 'root' when dialog is openunderlayEnterAnimation/underlayExitAnimationproperties- Ability to set any of the enter / exit animations to
nullto stop any animation from running
Renamed to TextArea in line with TextInput and other camcel cased widget names.
labelAfter
helperText?: string;
- default
collapseWidthof600. If nocollapseWidthis passed it will no longer collapse
labelAfter
helperText?: string
helperText?: string
.actionswrapper for toolbar actions which will automatically switch from row to column view when menu is collapsed into slide pane.alignoption to set the alignment of the embedded SlidePan that is displayed on narrow screens
This is a new widget to be used as a message bar to display notifications and messages to your users. It is designed to work similar to the material-design snackbar.
type?: 'success' | 'error'- whether the Snackbar should display with its success or error stateopen?: boolean- Whether the Snackbar is openmessageRenderer: () => RenderResult- A callback that returns what to render in the snackbar's message sectionactionsRenderer?: () => DNode | DNode[]- Buttons to render in the actions portion of the Snackbar
This new widget is a styled wrapper for app content similar to the material-design card. The widget takes children to render and an actiondRenderer function to ensure action buttons are placed in the correct location.
Card widget users should import it's css module to use it's classes to lay out it's content. For more information and examples of this, please see the card widget readme: https://github.com/dojo/widgets/blob/master/src/card/README.md.
actionsRenderer?: () => RenderResult- An Actions portion for the card, used primarily to render buttons