From 46c8080716969300563c43bbe6afd378b5d44ad7 Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Fri, 27 Jun 2025 15:48:42 +0200 Subject: [PATCH 1/4] Ember API to enable Vite support in Ember Inspector --- images/0000-ember-api-for-inspector.png | Bin 0 -> 22963 bytes text/0000-ember-api-for-inspector.md | 195 ++++++++++++++++++++++++ 2 files changed, 195 insertions(+) create mode 100644 images/0000-ember-api-for-inspector.png create mode 100644 text/0000-ember-api-for-inspector.md diff --git a/images/0000-ember-api-for-inspector.png b/images/0000-ember-api-for-inspector.png new file mode 100644 index 0000000000000000000000000000000000000000..6ae0c9bd4b9fcc9530f166ef521069ad82010a33 GIT binary patch literal 22963 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

-JuXiI36(rFOfX}V#bBT0b09yGUSe| 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 literal 0 HcmV?d00001 diff --git a/text/0000-ember-api-for-inspector.md b/text/0000-ember-api-for-inspector.md new file mode 100644 index 0000000000..1dc4d504de --- /dev/null +++ b/text/0000-ember-api-for-inspector.md @@ -0,0 +1,195 @@ +--- +stage: accepted +start-date: 2025-06-27T00:00:00.000Z # In format YYYY-MM-DDT00:00:00.000Z +release-date: # In format YYYY-MM-DDT00:00:00.000Z +release-versions: +teams: # delete teams that aren't relevant + - framework +prs: + accepted: # Fill this in with the URL for the Proposal RFC PR +project-link: +suite: +--- + + + + + +# Ember API to enable Vite support in Ember Inspector + +## Summary + +Define the API Ember should expose to the Ember Inspector (and similar tools) so it's compatible with Vite. + +## Motivation + +The Ember Inspector is a browser extension that extends the capacity of regular debuggers for Ember specifically. It allows developers to inspect their Ember apps and view information like the version of Ember and Ember Data running, the components render tree, the data loaded on the page, the state of the different Ember object instances like services, controllers, routes... It's a practical and popular extension, widely used in the Ember community. Unfortunately, it’s incompatible with modern Ember apps building with Vite. + +In Ember 6.7, Vite should become the default experience when generating a new Ember app. To keep the developer experience as qualitative as it is now, it's very important to get the Ember Inspector working. To achieve this, we need to rethink the way `ember.js` exposes the modules used by the Inspector: this is the purpose of this RFC. + +## Current architecture + +The purpose of the Inspector is to display information about the Ember app running on the page. To do so, it needs to retrieve this information somehow. The architecture involves both the Inspector itself and the inspected Ember app that depends on a version of ember-source: + +![A picture of the architecture described in the following paragraph](/images/0000-ember-api-for-inspector.png) + +The Inspector (on the right) is composed of two main pieces: + +- The UI is an Ember app that displays the content of the Inspector window when it runs. +- The folder `ember_debug` is built into a script `ember_debug.js`. The Inspector injects this script into the page to connect to the inspected Ember app. + +The incompatibility with Vite apps lies in how `ember_debug.js` (on the left) uses ember-source. For a long time, `ember-cli` expressed all the modules using AMD (Asynchronous Module Definition) and `requirejs` `define()` statements. Addons and applications could rely on AMD loading to use these modules. This is what the Inspector does. When using `@embroider/vite` to build the Ember app with Vite, ember-source is loaded as ESM (ECMAScript modules), and there's essentially no `requirejs` module support: the Inspector was designed to work with the AMD approach and breaks when we move to ESM. + +In a nutshell, supporting Vite means fixing the bridge between ember-source and `ember_debug.js`. + +## Proposed design + +### Overview + +To fix the interaction between ember-source and ember-inspector, we want to implement changes in both repositories: + +- In **ember.js**: we want to implement an API to expose ESM modules from Ember. The exposed moules are those `ember_debug` needs to send relevant information to the Inspector UI. To do so, we want to introduce a new module `@ember/debug/inspector-support.js` that one can include in their Ember app. This module would define a global (e.g. `emberInspectorLoader`) which provides a function that loads the ESM modules. + +- In **ember-inspector**: we want to implement the ability for `ember_debug` to import all modules from Ember as ESM modules. This should be done without breaking the previous AMD implementation because the Inspector should keep its current ability to inspect Classic apps built with Ember CLI and Broccoli. To do so, we want to use top-level `await` in a conditional block that would be executed when the AMD modules don't exist. Using top-level `await` implies to emit the `ember_debug` script itself as ESM (This constraint has already been partially answered by a recent refactor of the `ember_debug` build, which now relies on Rollup). + +### Implementation + +On the **ember.js** side, a new module would expose a global provinding a `load` function: + +```js +globalThis.emberInspectorLoader = { + async load() { + return { + Application: await import('@ember/application'), + // Other modules... + } + } +} +``` + +Note that having this global variable existing in your app will simply define the `load()` function. Modules loading happen only when the function is executed, and this will happen on the Inspector side (see below). In other words, if it turns out the Inspector requires a few modules that were not yet involed in running the Ember app on the page, they will be loaded only when the developer starts the inspector. + +On the **ember-inspector** side, the file that handles the interactions with ember.js would looks like this: + +```js +// ember_debug/utils/ember.js + +// Current code relying on AMD to load modules... + +/* New conditional block + * Among all the Ember modules, captureRenderTree is critical for the inspector to work. + * If still not defined at this point, we can safely assume there's no AMD support. */ +if (!captureRenderTree) { + const internalEmberModules = await globalThis.emberInspectorLoader.load(); + Application = internalEmberModules.Application; + // Other modules... +} + +// Same exports as before +export { + Application + // Other modules... +} + +``` + +- It has a new conditional block to fallback to ESM support. +- It calls the `globalThis.emberInspectorLoader.load()`, that we made available in the ember.js part. + +(Note that the approach has been implemented in a proof of concept so we can make sure the Inspector works fine this way. PRs [ember.js#20892](https://github.com/emberjs/ember.js/pull/20892/files) and [ember-inspector#2625](https://github.com/emberjs/ember-inspector/pull/2625/files) allow testing a first iteration of the Vite support when used together.) + +### Detailed API + +The detailed API described below reflect what the Ember Inspector uses. + +

+ +Expand to see the detailed API, with the full list of exports: + +```js +globalThis.emberInspectorLoader = { + async load() { + return { + Application: await import('@ember/application'), + ApplicationNamespace: await import('@ember/application/namespace'), + Array: await import('@ember/array'), + ArrayMutable: await import('@ember/array/mutable'), + ArrayProxy: await import('@ember/array/proxy'), + Component: await import('@ember/component'), + ComputedProperty: await import('@ember/object/computed'), + Controller: await import('@ember/controller'), + Debug: await import('@ember/debug'), + EmberDestroyable: await import('@ember/destroyable'), + EmberObject: await import('@ember/object'), + EnumerableMutable: await import('@ember/enumerable/mutable'), + InternalsEnvironment: await import('@ember/-internals/environment'), + InternalsMeta: await import('@ember/-internals/meta'), + InternalsMetal: await import('@ember/-internals/metal'), + InternalsRuntime: await import('@ember/-internals/runtime'), + InternalsUtils: await import('@ember/-internals/utils'), + InternalsViews: await import('@ember/-internals/views'), + Instrumentation: await import('@ember/instrumentation'), + RSVP: await import('rsvp'), + Runloop: await import('@ember/runloop'), + ObjectInternals: await import('@ember/object/internals'), + Service: await import('@ember/service'), + ObjectCore: await import('@ember/object/core'), + ObjectEvented: await import('@ember/object/evented'), + ObjectProxy: await import('@ember/object/proxy'), + ObjectObservable: await import('@ember/object/observable'), + ObjectPromiseProxyMixin: await import('@ember/object/promise-proxy-mixin'), + VERSION: await import('ember/version'), + GlimmerComponent: await import('@glimmer/component'), + GlimmerManager: await import('@glimmer/manager'), + GlimmerReference: await import('@glimmer/reference'), + GlimmerRuntime: await import('@glimmer/runtime'), + GlimmerUtil: await import('@glimmer/util'), + GlimmerValidator: await import('@glimmer/validator'), + } + } +} +``` + +
+ +### Explicit import in the Ember app & polyfill + +Using the new `@ember/debug/inspector-support.js` module in a Vite app requires to explicitly import it: + +```js +// my-ember-app/app/app.[js,ts] + +import '@ember/debug/inspector-support'; +``` + +This import will become available in the release that includes the implementation presented in the former section. However, Vite support for Ember apps is available back to 3.28. It means that people using Vite from 3.28 to whatever version includes this RFC will have a non-functional inspector. We intend to solve this issue using a polyfil implemented in a dedicated package. If an Ember app relies on a version of ember-source that doesn't include the new API, the import above should be changed to: + +```js +// my-ember-app/app/app.[js,ts] + +import '@embroider/inspector-support-polyfill'; +``` + +The polyfill will be in charge of providing the script that contains the API. Additionnally: +- It will adapt the content to the ember-source version if necessary (e.g We identified a module path which is different in version 4.8 and lower) +- It will error if the ember-source version includes the new API, and teach developers they should remove the dependency to the polyfill and replace the import with `'@ember/debug/inspector-support`. + +## Related concerns + +### Mixins deprecation + +Mixins are currently being deprecated (see #1111 to #1117). However, the detailed API above import mixins. This is because it would be preferable to implement the present RFC before mixins are actually removed. Removing the mixins is a breaking change that would likely be released in Ember 7. On the other hand, Vite could become the default way to build Ember apps from 6.7: having a functional Vite support ready by this time would preserve a good developer experience for people creating new Ember apps. + +Since mixins currently exist, and since the Inspector relies on them to render the correct information, it appears legit to include the mixins in the API. This way, the inspector keeps working correctly in Ember 6 and lower. Therefore, removing the mixins from the API would be part of #1111 to #1117 implementation. With the mixins gone, the Inspector code may require adjustment to display correclty the new without-mixin objects, but this should be ready for the major version that will remove them. From 72d533aee2b7a8974a41c8fee2af63441601b19c Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Fri, 27 Jun 2025 15:54:08 +0200 Subject: [PATCH 2/4] Ember API to enable Vite support in Ember Inspector: update with PR info --- ...spector.png => 1119-ember-api-for-inspector.png} | Bin ...inspector.md => 1119-ember-api-for-inspector.md} | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename images/{0000-ember-api-for-inspector.png => 1119-ember-api-for-inspector.png} (100%) rename text/{0000-ember-api-for-inspector.md => 1119-ember-api-for-inspector.md} (98%) diff --git a/images/0000-ember-api-for-inspector.png b/images/1119-ember-api-for-inspector.png similarity index 100% rename from images/0000-ember-api-for-inspector.png rename to images/1119-ember-api-for-inspector.png diff --git a/text/0000-ember-api-for-inspector.md b/text/1119-ember-api-for-inspector.md similarity index 98% rename from text/0000-ember-api-for-inspector.md rename to text/1119-ember-api-for-inspector.md index 1dc4d504de..17ae706020 100644 --- a/text/0000-ember-api-for-inspector.md +++ b/text/1119-ember-api-for-inspector.md @@ -6,7 +6,7 @@ release-versions: teams: # delete teams that aren't relevant - framework prs: - accepted: # Fill this in with the URL for the Proposal RFC PR + accepted: https://github.com/emberjs/rfcs/pull/1119 project-link: suite: --- @@ -43,7 +43,7 @@ In Ember 6.7, Vite should become the default experience when generating a new Em The purpose of the Inspector is to display information about the Ember app running on the page. To do so, it needs to retrieve this information somehow. The architecture involves both the Inspector itself and the inspected Ember app that depends on a version of ember-source: -![A picture of the architecture described in the following paragraph](/images/0000-ember-api-for-inspector.png) +![A picture of the architecture described in the following paragraph](/images/1119-ember-api-for-inspector.png) The Inspector (on the right) is composed of two main pieces: From 4c033c439d32eff565fccc382a18ddf7d8891b0c Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Fri, 27 Jun 2025 16:17:05 +0200 Subject: [PATCH 3/4] Ember API to enable Vite support in Ember Inspector: links and typos --- text/1119-ember-api-for-inspector.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/text/1119-ember-api-for-inspector.md b/text/1119-ember-api-for-inspector.md index 17ae706020..85374950fd 100644 --- a/text/1119-ember-api-for-inspector.md +++ b/text/1119-ember-api-for-inspector.md @@ -37,7 +37,7 @@ Define the API Ember should expose to the Ember Inspector (and similar tools) so The Ember Inspector is a browser extension that extends the capacity of regular debuggers for Ember specifically. It allows developers to inspect their Ember apps and view information like the version of Ember and Ember Data running, the components render tree, the data loaded on the page, the state of the different Ember object instances like services, controllers, routes... It's a practical and popular extension, widely used in the Ember community. Unfortunately, it’s incompatible with modern Ember apps building with Vite. -In Ember 6.7, Vite should become the default experience when generating a new Ember app. To keep the developer experience as qualitative as it is now, it's very important to get the Ember Inspector working. To achieve this, we need to rethink the way `ember.js` exposes the modules used by the Inspector: this is the purpose of this RFC. +In Ember 6.7, Vite should become the default experience when generating a new Ember app. To keep the developer experience as qualitative as it is now, it's very important to get the Ember Inspector working. To achieve this, we need to rethink how `ember.js` exposes the modules used by the Inspector: this is the purpose of this RFC. ## Current architecture @@ -60,13 +60,13 @@ In a nutshell, supporting Vite means fixing the bridge between ember-source and To fix the interaction between ember-source and ember-inspector, we want to implement changes in both repositories: -- In **ember.js**: we want to implement an API to expose ESM modules from Ember. The exposed moules are those `ember_debug` needs to send relevant information to the Inspector UI. To do so, we want to introduce a new module `@ember/debug/inspector-support.js` that one can include in their Ember app. This module would define a global (e.g. `emberInspectorLoader`) which provides a function that loads the ESM modules. +- In **ember.js**: we want to implement an API to expose ESM modules from Ember. The exposed modules are those `ember_debug` needs to send relevant information to the Inspector UI. To do so, we want to introduce a new module `@ember/debug/inspector-support.js` that one can include in their Ember app. This module would define a global (e.g. `emberInspectorLoader`) which provides a function that loads the ESM modules. -- In **ember-inspector**: we want to implement the ability for `ember_debug` to import all modules from Ember as ESM modules. This should be done without breaking the previous AMD implementation because the Inspector should keep its current ability to inspect Classic apps built with Ember CLI and Broccoli. To do so, we want to use top-level `await` in a conditional block that would be executed when the AMD modules don't exist. Using top-level `await` implies to emit the `ember_debug` script itself as ESM (This constraint has already been partially answered by a recent refactor of the `ember_debug` build, which now relies on Rollup). +- In **ember-inspector**: we want to implement the ability for `ember_debug` to import all modules from Ember as ESM modules. This should be done without breaking the previous AMD implementation because the Inspector should keep its current ability to inspect Classic apps built with Ember CLI and Broccoli. To do so, we want to use top-level `await` in a conditional block that would be executed when the AMD modules don't exist. Using top-level `await` implies emitting the `ember_debug` script itself as ESM (This constraint has already been partially answered by a recent refactor of the `ember_debug` build, which now relies on Rollup). ### Implementation -On the **ember.js** side, a new module would expose a global provinding a `load` function: +On the **ember.js** side, a new module would expose a global providing a `load` function: ```js globalThis.emberInspectorLoader = { @@ -79,9 +79,9 @@ globalThis.emberInspectorLoader = { } ``` -Note that having this global variable existing in your app will simply define the `load()` function. Modules loading happen only when the function is executed, and this will happen on the Inspector side (see below). In other words, if it turns out the Inspector requires a few modules that were not yet involed in running the Ember app on the page, they will be loaded only when the developer starts the inspector. +Note that having this global variable in your app will simply define the `load()` function. Modules will load only when the function is executed, and this will occur on the Inspector side (see below). In other words, if it turns out the Inspector requires a few modules that were not yet involved in running the Ember app on the page, they will be loaded only when the developer starts the inspector. -On the **ember-inspector** side, the file that handles the interactions with ember.js would looks like this: +On the **ember-inspector** side, the file that handles the interactions with ember.js would look like this: ```js // ember_debug/utils/ember.js @@ -106,13 +106,13 @@ export { ``` - It has a new conditional block to fallback to ESM support. -- It calls the `globalThis.emberInspectorLoader.load()`, that we made available in the ember.js part. +- It calls the `globalThis.emberInspectorLoader.load()` that we made available in the ember.js part. (Note that the approach has been implemented in a proof of concept so we can make sure the Inspector works fine this way. PRs [ember.js#20892](https://github.com/emberjs/ember.js/pull/20892/files) and [ember-inspector#2625](https://github.com/emberjs/ember-inspector/pull/2625/files) allow testing a first iteration of the Vite support when used together.) ### Detailed API -The detailed API described below reflect what the Ember Inspector uses. +The detailed API described below reflects what the Ember Inspector uses.
@@ -166,7 +166,7 @@ globalThis.emberInspectorLoader = { ### Explicit import in the Ember app & polyfill -Using the new `@ember/debug/inspector-support.js` module in a Vite app requires to explicitly import it: +Using the new `@ember/debug/inspector-support.js` module in a Vite app requires explicitly importing it: ```js // my-ember-app/app/app.[js,ts] @@ -174,7 +174,7 @@ Using the new `@ember/debug/inspector-support.js` module in a Vite app requires import '@ember/debug/inspector-support'; ``` -This import will become available in the release that includes the implementation presented in the former section. However, Vite support for Ember apps is available back to 3.28. It means that people using Vite from 3.28 to whatever version includes this RFC will have a non-functional inspector. We intend to solve this issue using a polyfil implemented in a dedicated package. If an Ember app relies on a version of ember-source that doesn't include the new API, the import above should be changed to: +This import will become available in the release that includes the implementation presented in the former section. However, Vite support for Ember apps is available back to 3.28. It means that people using Vite from 3.28 to whatever version includes this RFC will have a non-functional inspector. We intend to solve this issue using a polyfill implemented in a dedicated package. If an Ember app relies on a version of ember-source that doesn't include the new API, the import above should be changed to: ```js // my-ember-app/app/app.[js,ts] @@ -182,14 +182,14 @@ This import will become available in the release that includes the implementatio import '@embroider/inspector-support-polyfill'; ``` -The polyfill will be in charge of providing the script that contains the API. Additionnally: +The polyfill will be in charge of providing the script that contains the API. Additionally: - It will adapt the content to the ember-source version if necessary (e.g We identified a module path which is different in version 4.8 and lower) -- It will error if the ember-source version includes the new API, and teach developers they should remove the dependency to the polyfill and replace the import with `'@ember/debug/inspector-support`. +- It will error if the ember-source version includes the new API, and teach developers they should remove the dependency on the polyfill and replace the import with `'@ember/debug/inspector-support`. ## Related concerns ### Mixins deprecation -Mixins are currently being deprecated (see #1111 to #1117). However, the detailed API above import mixins. This is because it would be preferable to implement the present RFC before mixins are actually removed. Removing the mixins is a breaking change that would likely be released in Ember 7. On the other hand, Vite could become the default way to build Ember apps from 6.7: having a functional Vite support ready by this time would preserve a good developer experience for people creating new Ember apps. +Mixins are currently being deprecated (see [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+)). However, the detailed API above imports mixins. This is because it would be preferable to implement the present RFC before mixins are actually removed. Removing the mixins is a breaking change that would likely be released in Ember 7. On the other hand, Vite could become the default way to build Ember apps from 6.7: having a functional Vite support ready by this time would preserve a good developer experience for people creating new Ember apps. -Since mixins currently exist, and since the Inspector relies on them to render the correct information, it appears legit to include the mixins in the API. This way, the inspector keeps working correctly in Ember 6 and lower. Therefore, removing the mixins from the API would be part of #1111 to #1117 implementation. With the mixins gone, the Inspector code may require adjustment to display correclty the new without-mixin objects, but this should be ready for the major version that will remove them. +Since mixins currently exist, and since the Inspector relies on them to render the correct information, it appears legit to include the mixins in the API. This way, the inspector keeps working correctly in Ember 6 and lower. Therefore, removing the mixins from the API would be part of [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+) implementation. With the mixins gone, the Inspector code may require adjustments to display correclty the new without-mixin objects, but this should be ready for the major version that will remove them. From 2151c4fe4e6dc73ec7cefc15928f94388c4dbd2f Mon Sep 17 00:00:00 2001 From: Marine Dunstetter Date: Thu, 3 Jul 2025 17:47:15 +0200 Subject: [PATCH 4/4] Restructuring the RFC to introduce long-term vs compatibility API --- images/1119-ember-api-for-inspector.png | Bin 22963 -> 48256 bytes text/1119-ember-api-for-inspector.md | 182 ++++++++++++++---------- 2 files changed, 107 insertions(+), 75 deletions(-) diff --git a/images/1119-ember-api-for-inspector.png b/images/1119-ember-api-for-inspector.png index 6ae0c9bd4b9fcc9530f166ef521069ad82010a33..350c14e9ed7cb3f380e9742b623fa0e892ccde89 100644 GIT binary patch literal 48256 zcmbrlWmH_j);8FJyA#}ky9IZ5LP&565Zv9H;K2g~ha^~Vf)lI>F2P+J58im=L+*WN z-tX_s^jf`6^{(3TY^kbK=X8v=rV=&=IR*d#z*bR~*8u>Kp#T8*7!CYPc|oCB@qBsG zR@YVdcm2=jTq4yWQR0{r&yv>FGaw_@Jz;oRN{CuCAVzmgeH(GBGj1#Ke@Fn;RV+ zosf{w*VpIc<5OQ>udS_JTwGjHQStfnXA={Xf`Wqe^>tlc-MziNpFe*Z8XEHR^Ou&E z1_cG_>+65|^ofm)O-M+HlatfY(b3M%j)#ZG)6=u6swyihD=schK|w)8M1&}|hV2

fg-|yw8-b1J%2PS5#O3w||2^WYu@Dc|2 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

-JuXiI36(rFOfX}V#bBT0b09yGUSe| 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 diff --git a/text/1119-ember-api-for-inspector.md b/text/1119-ember-api-for-inspector.md index 85374950fd..92c21d01e3 100644 --- a/text/1119-ember-api-for-inspector.md +++ b/text/1119-ember-api-for-inspector.md @@ -50,38 +50,96 @@ The Inspector (on the right) is composed of two main pieces: - The UI is an Ember app that displays the content of the Inspector window when it runs. - The folder `ember_debug` is built into a script `ember_debug.js`. The Inspector injects this script into the page to connect to the inspected Ember app. +### Vite support issue + The incompatibility with Vite apps lies in how `ember_debug.js` (on the left) uses ember-source. For a long time, `ember-cli` expressed all the modules using AMD (Asynchronous Module Definition) and `requirejs` `define()` statements. Addons and applications could rely on AMD loading to use these modules. This is what the Inspector does. When using `@embroider/vite` to build the Ember app with Vite, ember-source is loaded as ESM (ECMAScript modules), and there's essentially no `requirejs` module support: the Inspector was designed to work with the AMD approach and breaks when we move to ESM. In a nutshell, supporting Vite means fixing the bridge between ember-source and `ember_debug.js`. -## Proposed design +### Global approach issue + +One important underlying problem with the current architecture is that most of the logic in `ember_debug.js` is the consequence of Ember not providing an API for tools like the Inspector. There's no Ember function that returns _the description of the application_ as a POJO (or JSON or whatever), so the `ember_debug.js` script creates its own description using the AMD modules available, with downsides: + +- Since Ember doesn't expose a public API, Ember doesn't have any legitimate responsibility about what modules are available or not. If Ember code is reorganized and a module used by the Inspector has its path changed, there's no signal to tell the Inspector will break: it's the Inspector's problem to be presented with a fait accompli and align with the latest released version of Ember. + +- The Inspector's code contains complex conditional pieces to support different Ember versions as the framework internals evolve. What piece of code supports what version is not explicitly indicated and the code is hard to maintain overall. Also, it happens that latest changes in the framework are not reflected, and tests are not always able to catch the issues (e.g. in Ember Inspector 4.13.1, most services are marked as computed properties because the execution path that marks services is no longer taken). + +### Conclusion + +Fixing the interactions between ember-source and ember-inspector to support Vite requires changes in both ember.js and ember-inspector: the former must expose the modules the inspector need as ESM, the latter must be able to consume ESM modules. However, implementing a new API in ember-source require to think this API future-proof. And future-proof implies that not only we solve the Vite support issue, but also the global approach issue. This is the reason why there are two different aspect to this RFC: + +- The long-term goal aspect: Describe the API to implement in ember.js. This API should describe objects a way that match the Inspector requirements. + +- The compatibility aspect: Vite support for Ember apps is available from 3.28 to latest. It means that at the time of writing, people who migrated their app to build with Vite are stuck with a non-functional Inspector. We must fix the support for all of these versions, which don't and will never have the new API describing objects. In other words, we need a compat API to make the bridge between old Ember versions and Vite world. + +## Long-term design + +### Overview + +// TODO + +### Implementation + +// TODO + +### Explicit import in the Ember app + +Using the new `@ember/debug/inspector-support` module in a Vite app requires explicitly importing it: + +```js +// my-ember-app/app/app.[js,ts] + +import '@ember/debug/inspector-support'; +``` + +This import will become available in the release that includes the implementation presented in the former section. If an Ember app relies on a version of ember-source that doesn't include the new API, the import above should be changed to: + +```js +// my-ember-app/app/app.[js,ts] + +import '@embroider/compat/inspector-support'; +``` + +The next section will detail the content of `@embroider/compat/inspector-support`. + + +## Compatibility design + +⚠️ Whereas the "Long-term design" section aims at defining the best API possible for the future, the present "Compatibility" section is more time sensitive. As explained earlier, Vite is already there, it should become the default in Ember 6.7, and the Inspector is currently broken for Ember+Vite developers. That's the reason why this section proposes a solution that is easy to implement in a short delay without reinventing entirely the communication between ember-source and ember-inspector. ### Overview -To fix the interaction between ember-source and ember-inspector, we want to implement changes in both repositories: +To fix the interaction between ember-source and ember-inspector for versions that don't have the new API yet, we want to use the concept of "compat" functionnality introduced in Embroider. The package `@embroider/compat` is what makes the bridge between classic Ember and Vite world. -- In **ember.js**: we want to implement an API to expose ESM modules from Ember. The exposed modules are those `ember_debug` needs to send relevant information to the Inspector UI. To do so, we want to introduce a new module `@ember/debug/inspector-support.js` that one can include in their Ember app. This module would define a global (e.g. `emberInspectorLoader`) which provides a function that loads the ESM modules. +- In **@embroider/compat**: we want to implement a compat API to expose ESM modules from Ember. The exposed modules are those `ember_debug` - as currently implemented - needs to send relevant information to the Inspector UI. To do so, we want to introduce a new module `@embroider/compat/inspector-support` that one can include in their Ember app. This module would define a global (e.g. `emberInspectorLoader`) which provides a function that loads the ESM modules. -- In **ember-inspector**: we want to implement the ability for `ember_debug` to import all modules from Ember as ESM modules. This should be done without breaking the previous AMD implementation because the Inspector should keep its current ability to inspect Classic apps built with Ember CLI and Broccoli. To do so, we want to use top-level `await` in a conditional block that would be executed when the AMD modules don't exist. Using top-level `await` implies emitting the `ember_debug` script itself as ESM (This constraint has already been partially answered by a recent refactor of the `ember_debug` build, which now relies on Rollup). +- In **ember-inspector**: we want to implement the ability for `ember_debug` to import all the modules from Ember as ESM modules. This should be done without breaking the previous AMD implementation because the Inspector should keep its current ability to inspect Classic apps built with Ember CLI and Broccoli. To do so, we want to use top-level `await` in a conditional block that would be executed when the AMD modules don't exist. Using top-level `await` implies emitting the `ember_debug` script itself as ESM (This constraint has already been partially answered by a recent refactor of the `ember_debug` build, which now relies on Rollup). ### Implementation -On the **ember.js** side, a new module would expose a global providing a `load` function: +On the **@embroider/compat** side, a new module `@embroider/compat/inspector-support` would expose a global providing a `load` function: ```js globalThis.emberInspectorLoader = { async load() { + const [ + Application, + // Other names... + ] = await Promise.all([ + import('@ember/application'), + // Other imports... + ]) return { - Application: await import('@ember/application'), + Application, // Other modules... } } } ``` -Note that having this global variable in your app will simply define the `load()` function. Modules will load only when the function is executed, and this will occur on the Inspector side (see below). In other words, if it turns out the Inspector requires a few modules that were not yet involved in running the Ember app on the page, they will be loaded only when the developer starts the inspector. +Note that having `emberInspectorLoader` global variable in your app will simply define the `load()` function. Modules will load only when the function is executed, and this will occur on the Inspector side (see below). In other words, if it turns out the Inspector requires a few modules that were not yet involved in running the Ember app on the page, they will be loaded only when the developer starts the inspector. -On the **ember-inspector** side, the file that handles the interactions with ember.js would look like this: +On the **ember-inspector** side, the file that imports the ESM modules would look like this: ```js // ember_debug/utils/ember.js @@ -110,7 +168,7 @@ export { (Note that the approach has been implemented in a proof of concept so we can make sure the Inspector works fine this way. PRs [ember.js#20892](https://github.com/emberjs/ember.js/pull/20892/files) and [ember-inspector#2625](https://github.com/emberjs/ember-inspector/pull/2625/files) allow testing a first iteration of the Vite support when used together.) -### Detailed API +### Detailed compat API The detailed API described below reflects what the Ember Inspector uses. @@ -119,77 +177,51 @@ The detailed API described below reflects what the Ember Inspector uses.

Expand to see the detailed API, with the full list of exports: ```js -globalThis.emberInspectorLoader = { - async load() { - return { - Application: await import('@ember/application'), - ApplicationNamespace: await import('@ember/application/namespace'), - Array: await import('@ember/array'), - ArrayMutable: await import('@ember/array/mutable'), - ArrayProxy: await import('@ember/array/proxy'), - Component: await import('@ember/component'), - ComputedProperty: await import('@ember/object/computed'), - Controller: await import('@ember/controller'), - Debug: await import('@ember/debug'), - EmberDestroyable: await import('@ember/destroyable'), - EmberObject: await import('@ember/object'), - EnumerableMutable: await import('@ember/enumerable/mutable'), - InternalsEnvironment: await import('@ember/-internals/environment'), - InternalsMeta: await import('@ember/-internals/meta'), - InternalsMetal: await import('@ember/-internals/metal'), - InternalsRuntime: await import('@ember/-internals/runtime'), - InternalsUtils: await import('@ember/-internals/utils'), - InternalsViews: await import('@ember/-internals/views'), - Instrumentation: await import('@ember/instrumentation'), - RSVP: await import('rsvp'), - Runloop: await import('@ember/runloop'), - ObjectInternals: await import('@ember/object/internals'), - Service: await import('@ember/service'), - ObjectCore: await import('@ember/object/core'), - ObjectEvented: await import('@ember/object/evented'), - ObjectProxy: await import('@ember/object/proxy'), - ObjectObservable: await import('@ember/object/observable'), - ObjectPromiseProxyMixin: await import('@ember/object/promise-proxy-mixin'), - VERSION: await import('ember/version'), - GlimmerComponent: await import('@glimmer/component'), - GlimmerManager: await import('@glimmer/manager'), - GlimmerReference: await import('@glimmer/reference'), - GlimmerRuntime: await import('@glimmer/runtime'), - GlimmerUtil: await import('@glimmer/util'), - GlimmerValidator: await import('@glimmer/validator'), - } - } -} +Application: await import('@ember/application'), +ApplicationNamespace: await import('@ember/application/namespace'), +Array: await import('@ember/array'), +ArrayMutable: await import('@ember/array/mutable'), +ArrayProxy: await import('@ember/array/proxy'), +Component: await import('@ember/component'), +ComputedProperty: await import('@ember/object/computed'), +Controller: await import('@ember/controller'), +Debug: await import('@ember/debug'), +EmberDestroyable: await import('@ember/destroyable'), +EmberObject: await import('@ember/object'), +EnumerableMutable: await import('@ember/enumerable/mutable'), +InternalsEnvironment: await import('@ember/-internals/environment'), +InternalsMeta: await import('@ember/-internals/meta'), +InternalsMetal: await import('@ember/-internals/metal'), +InternalsRuntime: await import('@ember/-internals/runtime'), +InternalsUtils: await import('@ember/-internals/utils'), +InternalsViews: await import('@ember/-internals/views'), +Instrumentation: await import('@ember/instrumentation'), +RSVP: await import('rsvp'), +Runloop: await import('@ember/runloop'), +ObjectInternals: await import('@ember/object/internals'), +Service: await import('@ember/service'), +ObjectCore: await import('@ember/object/core'), +ObjectEvented: await import('@ember/object/evented'), +ObjectProxy: await import('@ember/object/proxy'), +ObjectObservable: await import('@ember/object/observable'), +ObjectPromiseProxyMixin: await import('@ember/object/promise-proxy-mixin'), +VERSION: await import('ember/version'), +GlimmerComponent: await import('@glimmer/component'), +GlimmerManager: await import('@glimmer/manager'), +GlimmerReference: await import('@glimmer/reference'), +GlimmerRuntime: await import('@glimmer/runtime'), +GlimmerUtil: await import('@glimmer/util'), +GlimmerValidator: await import('@glimmer/validator'), ```
-### Explicit import in the Ember app & polyfill - -Using the new `@ember/debug/inspector-support.js` module in a Vite app requires explicitly importing it: - -```js -// my-ember-app/app/app.[js,ts] - -import '@ember/debug/inspector-support'; -``` - -This import will become available in the release that includes the implementation presented in the former section. However, Vite support for Ember apps is available back to 3.28. It means that people using Vite from 3.28 to whatever version includes this RFC will have a non-functional inspector. We intend to solve this issue using a polyfill implemented in a dedicated package. If an Ember app relies on a version of ember-source that doesn't include the new API, the import above should be changed to: - -```js -// my-ember-app/app/app.[js,ts] - -import '@embroider/inspector-support-polyfill'; -``` - -The polyfill will be in charge of providing the script that contains the API. Additionally: -- It will adapt the content to the ember-source version if necessary (e.g We identified a module path which is different in version 4.8 and lower) -- It will error if the ember-source version includes the new API, and teach developers they should remove the dependency on the polyfill and replace the import with `'@ember/debug/inspector-support`. +### Ember versions concerns -## Related concerns +Since `'@ember/debug/inspector-support` fits the way the Inspector currently works, the content should fit each supported Ember version depending on modules availability: -### Mixins deprecation +- The content of the script will adapt to the ember-source version relying on `@embroider/macros` (e.g. We identified a module path which is different in version 4.8 and lower). -Mixins are currently being deprecated (see [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+)). However, the detailed API above imports mixins. This is because it would be preferable to implement the present RFC before mixins are actually removed. Removing the mixins is a breaking change that would likely be released in Ember 7. On the other hand, Vite could become the default way to build Ember apps from 6.7: having a functional Vite support ready by this time would preserve a good developer experience for people creating new Ember apps. +- This philosophy also applies to changes that could be done in future versions. For instance Mixins are currently being deprecated (see [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+)). Removing the mixins is a breaking change that would likely be released in Ember 7. However, the compat API above imports mixins because the Inspector currently use them. If we can't get the Long-term API ready for Ember 7, then removing the mixins from the compat API and defining a macro condition to have them in 6+ would be part of [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+) implementation. -Since mixins currently exist, and since the Inspector relies on them to render the correct information, it appears legit to include the mixins in the API. This way, the inspector keeps working correctly in Ember 6 and lower. Therefore, removing the mixins from the API would be part of [#1111 to #1117](https://github.com/emberjs/rfcs/pulls?q=is%3Apr+author%3Awagenet+created%3A%3E2025-06-01+) implementation. With the mixins gone, the Inspector code may require adjustments to display correclty the new without-mixin objects, but this should be ready for the major version that will remove them. +- An error will be thrown if the ember-source version includes the new API, and teach developers they should remove the dependency on the polyfill and replace the import with `'@ember/debug/inspector-support`.