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,