Skip to content

Commit

Permalink
Added enhancement for watch mode callbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
Rzial committed Apr 11, 2019
1 parent 47226d0 commit 28b5e20
Show file tree
Hide file tree
Showing 7 changed files with 151 additions and 3 deletions.
32 changes: 32 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ anything similar to this making hard knowing what happens under the hood. In
this package you will be able to understand what is happening on the
enhancements just by reading their source files.

> The earliest version of Typescript supported by this package is actually v2.8.0 because
Typescript Enhaced uses the internal mechanism of `tsc` watch mode. Maybe, if demanded,
in a future release this could be upgraded.


### Usage
```bash
npm i --save-dev typescript typescript-enhanced
Expand Down Expand Up @@ -73,3 +78,30 @@ To enable this enhacement just add to your `tsconfig.json` the following line.

This is applied as the last before transformation of the chain so you can
modify its behaviour by using any before transformer if you want.

#### On Fail/Success Commands for watch mode
Sometimes do you want to do anything on watch mode states like starting a
server or execute a post-process. This is actually imposible with the `tsc`
command but `tsce` is able to manage this situation.

To enable this enhacement just add to your `tsconfig.json` the following line.
```json5
{
// ...
"compilerOptions": {
// ...
"onWatchFail": "<My command>",
"onWatchSuccess": "<My command>"
// ...
}
// ...
}
```

or just by adding the following parameters to the `tsce` command call

```bash
tsce --watch --onWatchFail <My command> --onWatchSuccess <My command>
```
### Contribution
Any contribution to upgrade this package is actually welcome :)
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
"typescript": "^3.4.1"
},
"peerDependencies": {
"typescript": ">= 2.3.0"
"typescript": ">= 2.8.0"
}
}
1 change: 1 addition & 0 deletions samples/call-program-on-watch-success/src/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log('This will be printed on build');
22 changes: 22 additions & 0 deletions samples/call-program-on-watch-success/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"extends": "../_common_/tsconfig",

"compilerOptions": {
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDirs": [
"./src"
],

/* Module Resolution Options */
"baseUrl": "./src", /* Base directory to resolve non-absolute module names. */
"paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
"@module/*": ["./module/*"]
},

/* Enhanced Options */
"onWatchSuccess": "node ./dist/main"
},
"include": [
"./src"
]
}
3 changes: 1 addition & 2 deletions src/enhancements/enable-custom-transformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ module.exports = function (ts) {
return Array.isArray(transformerModules)
? transformerModules
.map(({module, options}) => {
// TODO: Handle error
// TODO: Put an actual transformer
// TODO: Handle errors
return require(module.startsWith('./') || module.startsWith('../') || module.startsWith('/')
? configPath + '/' + module
: module)(options);
Expand Down
93 changes: 93 additions & 0 deletions src/enhancements/enable-watch-mode-callbacks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/**
* This file is part of the typescript-enhanced package.
*
* (c) Pedro Pérez Furio <[email protected]>
*
* For the full copyright and license information, please view the LICENSE.md
* file that was distributed with this source code.
*/
const { spawnSync } = require('child_process');
const { dirname, resolve } = require('path');

/**
* Enables the "onWatchSuccess" and "onWatchFail" properties on the tsconfig.json. It requires the version 2.8.0 of
* typescript package because before that version, the "createWatchProgram" don't exists.
*
* @param ts
*/
module.exports = function (ts) {
// Creates a message for the tsce --init command
ts.Diagnostics.On_Watch_Success_Description = ts.diag(100004,
ts.DiagnosticCategory.Message, "On_Watch_Success_Description_100004",
"Command that will be called on watch when the compilation process ends succesfully.");

ts.Diagnostics.On_Watch_Fail_Description = ts.diag(100006,
ts.DiagnosticCategory.Message, "On_Watch_Fail_Description_100006",
"Command that will be called on watch when the compilation process fails.");

// Adds an option to tsconfig.json to enable this enhacement
ts.optionDeclarations = ts.optionDeclarations.concat([
{
name: "onWatchSuccess",
type: "string",
category: ts.Diagnostics.Enhancement_Options,
description: ts.Diagnostics.On_Watch_Success_Description
},
{
name: "onWatchFail",
type: "string",
category: ts.Diagnostics.Enhancement_Options,
description: ts.Diagnostics.On_Watch_Fail_Description
}
]);

// Config path
const { options: { project } } = ts.parseCommandLine(ts.sys.args);
const configPath = dirname(resolve(ts.normalizePath(project || ts.sys.getCurrentDirectory())));

// Hook on createProgram
const createWatchProgram = ts.createWatchProgram;
ts.createWatchProgram = function (...args) {
let hadProgram = false, hadErrors = false, watchProcessed = false, compilerOptions = false;

const [host] = args;
const afterProgramCreate = host.afterProgramCreate;
const onWatchStatusChange = host.onWatchStatusChange;

host.afterProgramCreate = function (...args) {
const [builderProgram] = args;
const program = builderProgram.getProgramOrUndefined();

hadProgram = !!program;
hadErrors = program && !ts.getPreEmitDiagnostics(program).length;
watchProcessed = false;
compilerOptions = program.getCompilerOptions();

return afterProgramCreate(...args);
};

host.onWatchStatusChange = function (...args) {
const result = onWatchStatusChange(...args);

if (!watchProcessed && hadProgram) {
watchProcessed = true;

const { onWatchSuccess, onWatchFail } = compilerOptions;

if (onWatchSuccess && hadErrors) {
const [ onWatchSuccessCommand, ...onWatchSuccessArgs] = onWatchSuccess.split(' ');
spawnSync(onWatchSuccessCommand, onWatchSuccessArgs, { cwd: configPath, stdio: 'inherit' });
}

if (onWatchFail && !hadErrors) {
const [ onWatchFailCommand, ...onWatchFailArgs] = onWatchFail.split(' ');
spawnSync(onWatchFailCommand, onWatchFailArgs, { cwd: configPath, stdio: 'inherit' });
}
}

return result;
};

return createWatchProgram(...args);
};
};
1 change: 1 addition & 0 deletions src/tsce.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ const ts = require('typescript/lib/tsc');
require('./enhancements/enable-enhancements-diagnostic-messages')(ts);
require('./enhancements/enable-resolve-aliased-modules')(ts);
require('./enhancements/enable-custom-transformers')(ts);
require('./enhancements/enable-watch-mode-callbacks')(ts);

module.exports = ts;

0 comments on commit 28b5e20

Please sign in to comment.