Skip to content

Commit

Permalink
feat(scripts): add async typecheck report
Browse files Browse the repository at this point in the history
fork ts checker in sync mode was pretty slow. So we add async
typechecking and tap into the plugin hooks for showing up in
console.
  • Loading branch information
swashata committed Apr 29, 2019
1 parent 3f3face commit 3bf18dd
Show file tree
Hide file tree
Showing 14 changed files with 3,059 additions and 1,927 deletions.
2 changes: 1 addition & 1 deletion examples/plugin/src/ts/module.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export function strRepeat(item: string, times: number): string {
return item.repeat(times);
return item.repeat(times + 1);
}
6 changes: 3 additions & 3 deletions examples/plugin/wpackio.project.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ module.exports = {
main: ['./src/app/index.js'],
mobile: ['./src/app/mobile.js'],
},
hasTypeScript: false,
// hasTypeScript: false,
// Extra webpack config to be passed directly
webpackConfig: (config, merge, appDir, isDev) => {
const svgoLoader = {
Expand Down Expand Up @@ -99,7 +99,7 @@ module.exports = {
entry: {
main: ['./src/foo/foo.js'],
},
hasTypeScript: false,
// hasTypeScript: false,
// Extra webpack config to be passed directly
webpackConfig: undefined,
},
Expand All @@ -110,7 +110,7 @@ module.exports = {
entry: {
main: ['./src/reactapp/index.jsx'],
},
hasTypeScript: false,
// hasTypeScript: false,
webpackConfig: (config, merge, appDir, isDev) => {
const customRules = {
module: {
Expand Down
5 changes: 3 additions & 2 deletions examples/theme/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@
"private": true,
"devDependencies": {
"@wpackio/scripts": "file:../../packages/scripts",
"node-sass": "^4.10.0"
"node-sass": "^4.12.0"
},
"scripts": {
"bootstrap": "wpackio-scripts bootstrap",
"build": "wpackio-scripts build",
"start": "wpackio-scripts start",
"archive": "wpackio-scripts pack"
"archive": "wpackio-scripts pack",
"dev": "../../packages/scripts/lib/bin/index.js"
},
"dependencies": {
"@wpackio/entrypoint": "file:../../packages/entrypoint"
Expand Down
1 change: 1 addition & 0 deletions examples/theme/src/single/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const foo = 'foo';
3 changes: 3 additions & 0 deletions examples/theme/src/single/single.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import foo from './module';

console.log('hello!');
6 changes: 6 additions & 0 deletions examples/theme/wpackio.project.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ module.exports = {
webpackConfig: undefined,
},
// If has more length, then multi-compiler
{
name: 'single',
entry: {
main: ['./src/single/single.js'],
},
},
],
// Output path relative to the context directory
// We need relative path here, else, we can not map to publicPath
Expand Down
4,401 changes: 2,637 additions & 1,764 deletions examples/theme/yarn.lock

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare module 'react-dev-utils/typescriptFormatter' {
export default function formatter(message: any, useColors: boolean): string;
}
2 changes: 1 addition & 1 deletion packages/scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
"ora": "^3.4.0",
"postcss-loader": "^3.0.0",
"pretty-error": "^2.1.1",
"react-dev-utils": "^6.0.4",
"react-dev-utils": "^9.0.0",
"sass-loader": "^7.1.0",
"slugify": "^1.3.4",
"style-loader": "^0.23.1",
Expand Down
66 changes: 51 additions & 15 deletions packages/scripts/src/bin/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {
printGeneralInfoMessage,
printCompileTimeMessages,
webpackStatToJsonOptions,
printErrorHeading,
printWarningHeading,
} from './utils';

/**
Expand Down Expand Up @@ -81,22 +83,28 @@ export function serve(options: ProgramOptions | undefined): void {
done: () => {
printSuccessfullyCompiledMessage();
},
onWatching() {
printWatchingMessage();
},
onError: msg => {
console.log('');
console.log(`${chalk.bgRed.black(' ERROR ')} please review`);
console.log('');
msg.errors.forEach(e => console.log(e));
console.log('');
printErrorHeading('ERROR');
msg.errors.forEach(e => {
console.log(e);
console.log('');
});
printFailedCompileMEssage();
},
onWarn: msg => {
printWarningHeading('WARNING');
msg.warnings.forEach(e => {
console.log(e);
console.log('');
});
printCompiledWithWarnMessage();
msg.warnings.forEach(e => console.log(e));
},
onEmit: stats => {
printCompileTimeMessages(stats, lastWebpackStat);
lastWebpackStat = stats.toJson(webpackStatToJsonOptions);
printWatchingMessage();
},
firstCompile: (stats: webpack.Stats) => {
spinner.stop();
Expand All @@ -107,27 +115,55 @@ export function serve(options: ProgramOptions | undefined): void {
console.log('');

if (stats.hasErrors()) {
console.log('');
console.log(
`${chalk.bgRed.black(' ERROR ')} please review`
);
messages.errors.forEach(e => console.log(e));
console.log('');
printErrorHeading('ERROR');
messages.errors.forEach(e => {
console.log(e);
console.log('');
});
printFailedCompileMEssage();
} else if (stats.hasWarnings()) {
printWarningHeading('WARNING');
messages.warnings.forEach(e => {
console.log(e);
console.log('');
});
printCompiledWithWarnMessage();
messages.warnings.forEach(e => console.log(e));
} else {
printSuccessfullyCompiledMessage();
}
printCompileTimeMessages(stats, lastWebpackStat);
printWatchingMessage();
lastWebpackStat = stats.toJson(webpackStatToJsonOptions);
},
onBsChange(file) {
printGeneralInfoMessage(`changed: ${chalk.bold(file)}`);
printGeneralInfoMessage('reloading browser');
},
onTcStart() {
printGeneralInfoMessage('waiting for typecheck results...');
},
onTcEnd(messages) {
if (messages.errors.length || messages.warnings.length) {
if (messages.errors.length) {
printErrorHeading('TS ERROR');
messages.errors.forEach(e => {
console.log(e);
console.log('');
});
}
if (messages.warnings.length) {
printWarningHeading('TS WARNING');
messages.warnings.forEach(e => {
console.log(e);
console.log('');
});
}
} else {
printGeneralInfoMessage(
'no typecheck errors',
logSymbols.success
);
}
},
});
server.serve();

Expand Down
20 changes: 18 additions & 2 deletions packages/scripts/src/bin/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,8 +179,24 @@ export function printFailedCompileMEssage() {
);
}

export function printGeneralInfoMessage(msg: string) {
console.info(addTimeStampToLog(`${logSymbols.info} ${msg}`));
export function printGeneralInfoMessage(msg: string, symbol?: string) {
if (typeof symbol === 'undefined') {
// eslint-disable-next-line no-param-reassign
symbol = logSymbols.info;
}
console.info(addTimeStampToLog(`${symbol} ${msg}`));
}

export function printErrorHeading(msg: string = 'ERROR'): void {
console.log('');
console.log(`${chalk.bgRed.black(` ${msg} `)} please review`);
console.log('');
}

export function printWarningHeading(msg: string = 'WARNING'): void {
console.log('');
console.log(`${chalk.bgYellow.black(` ${msg} `)} please review`);
console.log('');
}

export const bulletSymbol = chalk.magenta(figures.pointer);
Expand Down
40 changes: 22 additions & 18 deletions packages/scripts/src/config/WebpackConfigHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,23 @@ interface CommonWebpackConfig {
externals: webpack.Configuration['externals'];
}

/**
* Check if file exists or not using fs API.
*/
export function fileExists(filepath: string): boolean {
try {
// tslint:disable-next-line:non-literal-fs-path
return fs.statSync(filepath).isFile();
} catch (_) {
return false;
}
}

export function hasTypeScript(cwd: string): [boolean, string] {
const tsconfigPath = path.resolve(cwd, './tsconfig.json');
return [fileExists(tsconfigPath), tsconfigPath];
}

/**
* A helper class to get different configuration of webpack.
*/
Expand Down Expand Up @@ -283,11 +300,8 @@ export class WebpackConfigHelper {
}),
];
// Add ts checker plugin if project has tsconfig.json
const tsconfigPath = path.resolve(this.cwd, './tsconfig.json');
if (
this.fileExists(tsconfigPath) &&
this.file.hasTypeScript !== false
) {
const [isTs, tsconfigPath] = hasTypeScript(this.cwd);
if (isTs && this.file.hasTypeScript !== false) {
// dynamic require forktschecker otherwise it will throw error
try {
// eslint-disable-next-line import/no-extraneous-dependencies, global-require, @typescript-eslint/no-var-requires
Expand All @@ -296,9 +310,11 @@ export class WebpackConfigHelper {
new ForkTsCheckerWebpackPlugin({
tsconfig: tsconfigPath,
tslint: undefined,
async: false,
async: this.isDev,
silent: true,
formatter: 'codeframe',
useTypescriptIncrementalApi: true,
checkSyntacticErrors: true,
formatterOptions: {
highlightCode: true,
},
Expand Down Expand Up @@ -663,18 +679,6 @@ ${bannerConfig.copyrightText}${bannerConfig.credit ? creditNote : ''}`,
return defaults;
}

/**
* Check if file exists or not using fs API.
*/
private fileExists(filepath: string): boolean {
try {
// tslint:disable-next-line:non-literal-fs-path
return fs.statSync(filepath).isFile();
} catch (_) {
return false;
}
}

/**
* Get calculated app directory
*/
Expand Down
Loading

0 comments on commit 3bf18dd

Please sign in to comment.