Skip to content

Conversation

gonzaloriestra
Copy link
Contributor

@gonzaloriestra gonzaloriestra commented Jul 8, 2025

WHY are these changes introduced?

Fixes https://github.com/shop/issues-develop/issues/11518

When running app dev, we need to watch for changes in imported files that live outside of the extension folders.

WHAT is this pull request doing?

  • Adds tree-sitter dependency to parse extensions code
  • When running dev, it finds imported files from the entry files of each extension and adds them to the watcher, for JS/TS/Rust files
  • Keeps a list of imported paths for each extension to know which extensions require an update
  • Refresh the paths on update events (to detect new imports without restarting)
18-34-ca55s-5fuoc

How to test your changes?

  • Create an app with 3 extensions: JS, TS and Rust
  • For each extension, import files from a folder outside of /extensions
  • Run dev and check that it detect changes in the imported files
  • Update the imports while running dev and check it watches the expected files

Measuring impact

How do we know this change was effective? Please choose one:

  • n/a - this doesn't need measurement, e.g. a linting rule or a bug-fix
  • Existing analytics will cater for this addition
  • PR includes analytics changes to measure impact

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes

@gonzaloriestra gonzaloriestra added the stale-exempt If added, the PR/issue won't be closed by stale-bot label Jul 17, 2025
Copy link
Contributor

github-actions bot commented Sep 17, 2025

Coverage report

St.
Category Percentage Covered / Total
🟡 Statements
78.77% (+0.27% 🔼)
13674/17360
🟡 Branches
72.79% (+0.29% 🔼)
6626/9103
🟡 Functions
79.01% (+0.23% 🔼)
3527/4464
🟡 Lines
79.13% (+0.29% 🔼)
12929/16339
Show new covered files 🐣
St.
File Statements Branches Functions Lines
🟢
... / flow-template.ts
100% 100% 100% 100%
🟢
... / import-extractor.ts
84.21% 78.13% 87.5% 88.89%
Show files with reduced coverage 🔻
St.
File Statements Branches Functions Lines
🟢
... / extension-instance.ts
82.68% (-0.38% 🔻)
77.6% (-1.14% 🔻)
92.73%
82.42% (-0.42% 🔻)
🔴
... / extension.ts
57.38% (-2.97% 🔻)
60%
44.44% (-5.56% 🔻)
58.33% (-3.07% 🔻)
🟢
... / app-event-watcher.ts
97.62% (-0.11% 🔻)
91.43% (+2.86% 🔼)
95.45% 100%
🟢
... / bundle.ts
82.35% (-10.87% 🔻)
66.67%
73.33% (-14.9% 🔻)
83.67% (-12.62% 🔻)
🟢
... / session.ts
89.6% (-0.08% 🔻)
77.53% 91.67%
88.98% (-0.09% 🔻)
🟢
... / ConcurrentOutput.tsx
98.36% (-1.64% 🔻)
92% (-4% 🔻)
100%
98.33% (-1.67% 🔻)
🟢
... / Tasks.tsx
94% (-6% 🔻)
93.1% (-6.9% 🔻)
88.89% (-11.11% 🔻)
93.62% (-6.38% 🔻)
🟢
... / environments.ts
100%
91.67% (-8.33% 🔻)
100% 100%
🟢
... / session.ts
97.96% (-2.04% 🔻)
100%
85.71% (-14.29% 🔻)
97.96% (-2.04% 🔻)
🔴
... / ui.tsx
49.15% (-2.46% 🔻)
42.86% (-5.53% 🔻)
51.61% (-1.51% 🔻)
48.28% (-2.54% 🔻)
🟡
... / flags.ts
71.43% (-19.48% 🔻)
100%
50% (-25% 🔻)
66.67% (-23.33% 🔻)
🟢
... / theme-command.ts
85.71% (-0.24% 🔻)
68.25% (-1.9% 🔻)
83.33%
87.04% (-0.24% 🔻)

Test suite run success

3256 tests passing in 1367 suites.

Report generated by 🧪jest coverage report action from 2641765

@gonzaloriestra gonzaloriestra marked this pull request as ready for review September 17, 2025 14:01
@gonzaloriestra gonzaloriestra requested a review from a team as a code owner September 17, 2025 14:01
Copy link
Contributor

We detected some changes at packages/*/src and there are no updates in the .changeset.
If the changes are user-facing, run pnpm changeset add to track your changes and include them in the next release CHANGELOG.

Caution

DO NOT create changesets for features which you do not wish to be included in the public changelog of the next CLI release.

Copy link
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

packages/cli-kit/dist/public/node/import-extractor.d.ts
/**
 * Extracts import paths from a source file.
 * Supports JavaScript, TypeScript, and Rust files.
 *
 * @param filePath - Path to the file to analyze.
 * @returns Array of absolute paths to imported files.
 */
export declare function extractImportPaths(filePath: string): string[];

Existing type declarations

We found no diffs with existing type declarations

Comment on lines +192 to +211
private getExtensionEntryFiles(extension: ExtensionInstance): string[] {
const entryFiles: string[] = []

// First, check if we have an explicit entrySourceFilePath
if (extension.entrySourceFilePath) {
entryFiles.push(extension.entrySourceFilePath)
return entryFiles
}

// For UI extensions, check targeting/extension_points configuration
const config = extension.configuration
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const targetingConfig = (config as any).targeting || (config as any).extension_points
if (targetingConfig && Array.isArray(targetingConfig)) {
for (const target of targetingConfig) {
if (target.module) {
const modulePath = joinPath(extension.directory, target.module)
if (fileExistsSync(modulePath)) {
entryFiles.push(modulePath)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function should probably be in extension-instance

Also, I think the implementation is wrong. For ui_extensions we generate custom in-memory entry files in getBundleExtensionStdinContent, we need to use that to watch for changes.

This already returns a string with format import ..., so it can be passed directly to the parser. Maybe with a new function extractImportPathFromFileContent(content: string)

/**
* Performs the actual rescan of extension imports
*/
private async doRescanExtensionImports(extensionPath: string): Promise<void> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have both scanExtensionsForImports and doRescanExtensionImports? they seem to be doing almost the exact thing.

We can have a shared scanImportsForExtension(extension...) and then call it either for ALL or just for the one that was just updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stale-exempt If added, the PR/issue won't be closed by stale-bot
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants