Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(watch): add --ignore flag #110

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions README.md
Expand Up @@ -97,6 +97,15 @@ tsx watch ./file.ts
All imported files are watched except from the following directories:
`node_modules`, `bower_components`, `vendor`, `dist`, and `.*` (hidden directories).

#### Ignore files from being watched

If you wish to exclude files from being watched, you can pass `--ignored` multiple times:
```sh
tsx watch --ignored ./ignore-me.js --ignored ./ignore-me-too.js ./file.ts
romanlamsal marked this conversation as resolved.
Show resolved Hide resolved
```

This flag is passed to [chokidar](https://github.com/paulmillr/chokidar) thus glob patterns also work here.

#### Tips
- Press <kbd>Return</kbd> to manually rerun
- Pass in `--clear-screen=false` to disable clearing the screen on rerun
Expand Down
10 changes: 9 additions & 1 deletion src/watch/index.ts
Expand Up @@ -27,7 +27,12 @@ const flags = {
description: 'Clearing the screen on rerun',
default: true,
},
};
ignored: {
romanlamsal marked this conversation as resolved.
Show resolved Hide resolved
type: [String],
description: 'Defines files/paths to be ignored',
romanlamsal marked this conversation as resolved.
Show resolved Hide resolved
default: [],
romanlamsal marked this conversation as resolved.
Show resolved Hide resolved
},
} as const;

export const watchCommand = command({
name: 'watch',
Expand All @@ -47,6 +52,7 @@ export const watchCommand = command({
noCache: argv.flags.noCache,
tsconfigPath: argv.flags.tsconfig,
clearScreen: argv.flags.clearScreen,
ignored: argv.flags.ignored,
ipc: true,
};

Expand Down Expand Up @@ -123,6 +129,8 @@ export const watchCommand = command({

// Distribution files
'**/dist/**',

...options.ignored,
],
ignorePermissionErrors: true,
},
Expand Down
65 changes: 65 additions & 0 deletions tests/specs/watch.ts
Expand Up @@ -141,5 +141,70 @@ export default testSuite(async ({ describe }, fixturePath: string) => {
// await tsxProcess;
// }, 2000);
});

describe('ignore', ({ test }) => {
test('multiple files ignored', async () => {
// given
const initialValue = 'first round';
const alteredValue = 'second round';
const includedFilename = 'included.js';
const ignoredFilenames = ['ignored-1.js', 'ignored-2.js'];

const fixtures = await createFixture({
[includedFilename]: `
import { value as value1 } from './ignored-1';
import { value as value2 } from './ignored-2';
console.log(value1 + value2);
`.trim(),
[ignoredFilenames[0]]: `export const value = '${initialValue}';`,
[ignoredFilenames[1]]: `export const value = '${initialValue}';`,
});

const tsxProcess = tsx({
args: [
'watch',
'--clear-screen=false',
`--ignored=${path.join(fixtures.path, ignoredFilenames[0])}`,
`--ignored=${path.join(fixtures.path, ignoredFilenames[1])}`,
path.join(fixtures.path, includedFilename),
],
});

let aggregatedOutput = '';
async function onStdOut(data: Buffer) {
const chunkString = data.toString();
aggregatedOutput += chunkString;

if (new RegExp(`${initialValue}\n`).test(chunkString)) {
await Promise.all(ignoredFilenames.map(ignoredFilename => fixtures.writeFile(ignoredFilename, `export const value = '${alteredValue}';`)));
// make sure to wait for chokidar to pick up changes
// in the ignored file before manually triggering a rerun
setTimeout(async () => {
await fixtures.writeFile(includedFilename, 'console.log(\'TERMINATE\');');
}, 500);
} else if (chunkString.match('TERMINATE\n')) {
// cleanup
await fixtures.rm();
tsxProcess.kill();
}
}
tsxProcess.stdout?.on('data', onStdOut);

let error = false;
tsxProcess.stderr?.on('data', () => {
error = true;
});

// when
await tsxProcess;

// then
if (error) {
// manten does not come with a fail() utility.
expect('No error throwing').toEqual('but was thrown.');
}
expect(aggregatedOutput).not.toMatch(alteredValue);
});
});
});
});