For anyone curious about the new Explicit Resource Management features coming soon and supported by latest versions of TypeScript here are some steps to enable it in your Ember apps today!
Steps
- install dependencies
- add babel plugin to
ember-cli-build.js
to enable the plugin - add import to
app/app.ts
to enable the polyfill
Dependencies
npm install -D @babel/plugin-proposal-explicit-resource-management disposablestack
Enable plugin
In ember-cli-build.js
add the following
--- a/ember-cli-babel.js 2025-01-16 21:15:53.949082700 -0500
+++ b/ember-cli-babel.js 2025-01-16 21:16:32.965648714 -0500
@@ -6,6 +6,12 @@
const app = new EmberApp(defaults, {
'ember-cli-babel': { enableTypeScriptTransform: true },
+ babel: {
+ plugins: [
+ '@babel/plugin-proposal-explicit-resource-management',
+ ],
+ },
+
// Add options here
});
Enable polyfill
Add this to the top of app/app.ts
:
import 'disposablestack/auto';
Using
You can now use the using
keyword as well as Symbol.dispose
and DisposableStack
. Also all the Async variants of that as well.
Here is an example that handles persistent storage via localStorage
.
import Service from '@ember/service';
class PersistentStore<T = unknown> {
data: T
constructor(readonly key: string) {
this.data = JSON.parse(localStorage.getItem(key) ?? '{}') as T;
}
[Symbol.dispose]() {
localStorage.setItem(this.key, JSON.stringify(this.data));
}
}
interface FooBarData {
foo?: string;
bar?: string;
}
const FOO_BAR_KEY = 'my-fancy-foo-bar-key';
export default class FooBar extends Service {
updateFoo(newValue: string) {
using store = new PersitententStore<FooBarData>(FOO_BAR_KEY);
store.data.foo = newValue;
}
updateBar(newValue: string) {
using store = new PersitententStore<FooBarData>(FOO_BAR_KEY);
store.data.bar = newValue;
}
}