diff --git a/packages/addon-dev/src/rollup-clean-plugin.ts b/packages/addon-dev/src/rollup-clean-plugin.ts
index c91aaa8ea..9a1eb1ef7 100644
--- a/packages/addon-dev/src/rollup-clean-plugin.ts
+++ b/packages/addon-dev/src/rollup-clean-plugin.ts
@@ -11,7 +11,15 @@ export default function clean(): Plugin {
name: 'clean',
transform(_code, id) {
changed.add(id);
- return;
+ // support colocation changes
+ // could also be done directly in the babel plugin
+ // by passing rollup context into it
+ let hbsFilename = id.replace(/\.\w{1,3}$/, '') + '.hbs';
+ console.log('watch', hbsFilename, '?');
+ if (hbsFilename !== id && existsSync(hbsFilename)) {
+ console.log('watch', hbsFilename, 'for', id);
+ this.addWatchFile(hbsFilename);
+ }
},
generateBundle(options, bundle) {
if (existsSync(options.dir!)) {
diff --git a/tests/scenarios/v2-addon-dev-watch-test.ts b/tests/scenarios/v2-addon-dev-watch-test.ts
index c48bacc0c..1b1126740 100644
--- a/tests/scenarios/v2-addon-dev-watch-test.ts
+++ b/tests/scenarios/v2-addon-dev-watch-test.ts
@@ -3,6 +3,7 @@ import { baseV2Addon } from './scenarios';
import type { PreparedApp } from 'scenario-tester';
import { Scenarios } from 'scenario-tester';
import fs from 'fs/promises';
+import { existsSync } from 'fs';
import QUnit from 'qunit';
import merge from 'lodash/merge';
import { DevWatcher, becomesModified, isNotModified } from './helpers';
@@ -73,6 +74,7 @@ Scenarios.fromProject(() => baseV2Addon())
flip
`,
+ 'other.hbs': '
',
'out.hbs': `{{yield}}`,
'demo.js': `
import Component from '@glimmer/component';
@@ -143,31 +145,55 @@ Scenarios.fromProject(() => baseV2Addon())
let someFile = path.join(addon.dir, 'src/components/demo.hbs');
let distPath = path.join(addon.dir, 'dist/components/test.js');
let srcPathDemo = path.join(addon.dir, 'src/components/demo.hbs');
- let distPathDemo = path.join(addon.dir, 'dist/_app_/components/demo.js');
+ let distPathDemoComp = path.join(addon.dir, 'dist/components/demo.js');
+ let srcPathButton = path.join(addon.dir, 'src/components/other.hbs');
+ let distPathButton = path.join(addon.dir, 'dist/_app_/components/other.js');
- assert.strictEqual(
- await fs.exists(distPathDemo),
- true,
- `Expected ${distPathDemo} to exist`
- );
- let origContent = await fs.readFile(srcPathDemo);
+ assert.strictEqual(existsSync(distPathButton), true, `Expected ${distPathButton} to exist`);
+ let origContent = await fs.readFile(srcPathButton);
+ let demoContent = await fs.readFile(srcPathDemo);
- await fs.rm(srcPathDemo);
+ await fs.rm(srcPathButton);
await watcher?.nextBuild();
+ assert.strictEqual(existsSync(distPathButton), false, `Expected ${distPathButton} to be deleted`);
- assert.strictEqual(
- await fs.exists(distPathDemo),
- false,
- `Expected ${distPathDemo} to be deleted`
- );
-
- await fs.writeFile(srcPathDemo, origContent);
+ await fs.writeFile(srcPathButton, origContent);
await watcher?.nextBuild();
- assert.strictEqual(
- await fs.exists(distPathDemo),
- true,
- `Expected ${distPathDemo} to exist`
- );
+ assert.strictEqual(existsSync(distPathButton), true, `Expected ${distPathButton} to exist`);
+
+ await becomesModified({
+ filePath: distPathDemoComp,
+ assert,
+ // Update a component
+ fn: async () => {
+ let someContent = await fs.readFile(srcPathDemo);
+
+ // generally it's bad to introduce time dependencies to a test, but we need to wait long enough
+ // to guess for how long it'll take for the file system to update our file.
+ //
+ // the `stat` is measured in `ms`, so it's still pretty fast
+ await aBit(10);
+ await fs.writeFile(srcPathDemo, someContent + `\n`);
+ await watcher?.nextBuild();
+ },
+ });
+
+ await becomesModified({
+ filePath: distPathDemoComp,
+ assert,
+ // Update a component
+ fn: async () => {
+ // generally it's bad to introduce time dependencies to a test, but we need to wait long enough
+ // to guess for how long it'll take for the file system to update our file.
+ //
+ // the `stat` is measured in `ms`, so it's still pretty fast
+ await aBit(10);
+ await fs.rm(srcPathDemo);
+ await watcher?.nextBuild();
+ },
+ });
+
+ await fs.writeFile(srcPathDemo, demoContent);
await isNotModified({
filePath: distPath,
@@ -255,7 +281,6 @@ Scenarios.fromProject(() => baseV2Addon())
await watcher.start();
let manifestPath = path.join(addon.dir, 'package.json');
-
await becomesModified({
filePath: manifestPath,
assert,