Skip to content

Commit

Permalink
feat: drop support for webpack 4 (#638)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: 🧨 Webpack 4 is no longer supported. Please upgrade to Webpack ^5.11.0 or use an older version of the plugin.
  • Loading branch information
piotr-oles authored Aug 2, 2021
1 parent 3e23b88 commit cdb531f
Show file tree
Hide file tree
Showing 36 changed files with 737 additions and 1,438 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@

## Installation

This plugin requires minimum **Node.js 12**, **Webpack 5**, **TypeScript 3.6**
This plugin requires minimum **Node.js 12+**, **Webpack ^5.11.0**, **TypeScript ^3.6.0**

* If you depend on **TypeScript 2.1 - 2.6.2**, please use [version 4](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/tree/v4.1.4) of the plugin.
* If you depend on **Webpack 4**, **TypeScript 2.7 - 3.5.3** or **ESLint** feature, please use [version 6](https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/tree/v6.2.6) of the plugin.
Expand Down
8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,10 @@
"minimatch": "^3.0.4",
"schema-utils": "2.7.0",
"semver": "^7.3.2",
"tapable": "^1.0.0"
"tapable": "^2.0.0"
},
"peerDependencies": {
"webpack": "^5.11.0"
},
"devDependencies": {
"@commitlint/config-conventional": "^11.0.0",
Expand All @@ -90,7 +93,6 @@
"@types/node": "^14.11.10",
"@types/rimraf": "^3.0.0",
"@types/semver": "^7.3.4",
"@types/webpack": "^4.41.22",
"@typescript-eslint/eslint-plugin": "^2.27.0",
"@typescript-eslint/parser": "^2.27.0",
"commitlint": "^11.0.0",
Expand All @@ -115,7 +117,7 @@
"tree-kill": "^1.2.2",
"ts-jest": "^26.4.1",
"typescript": "^3.8.3",
"webpack": "^4.42.1"
"webpack": "^5.11.0"
},
"engines": {
"node": ">=10",
Expand Down
2 changes: 1 addition & 1 deletion src/ForkTsCheckerWebpackPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { tapAfterEnvironmentToPatchWatching } from './hooks/tapAfterEnvironmentT
import { createPool, Pool } from './utils/async/pool';
import os from 'os';

class ForkTsCheckerWebpackPlugin implements webpack.Plugin {
class ForkTsCheckerWebpackPlugin {
/**
* Current version of the plugin
*/
Expand Down
4 changes: 2 additions & 2 deletions src/ForkTsCheckerWebpackPluginState.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Tap } from 'tapable';
import { FullTap } from 'tapable';
import { FilesMatch, Report } from './reporter';
import { Issue } from './issue';

Expand All @@ -9,7 +9,7 @@ interface ForkTsCheckerWebpackPluginState {
lastDependencies: FilesMatch | undefined;
watching: boolean;
initialized: boolean;
webpackDevServerDoneTap: Tap | undefined;
webpackDevServerDoneTap: FullTap | undefined;
}

function createForkTsCheckerWebpackPluginState(): ForkTsCheckerWebpackPluginState {
Expand Down
10 changes: 5 additions & 5 deletions src/hooks/pluginHooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ const compilerHookMap = new WeakMap<

function createForkTsCheckerWebpackPluginHooks() {
return {
start: new AsyncSeriesWaterfallHook<FilesChange, webpack.compilation.Compilation>([
start: new AsyncSeriesWaterfallHook<[FilesChange, webpack.Compilation]>([
'change',
'compilation',
]),
waiting: new SyncHook<webpack.compilation.Compilation>(['compilation']),
canceled: new SyncHook<webpack.compilation.Compilation>(['compilation']),
error: new SyncHook<Error, webpack.compilation.Compilation>(['error', 'compilation']),
issues: new SyncWaterfallHook<Issue[], webpack.compilation.Compilation | undefined, void>([
waiting: new SyncHook<[webpack.Compilation]>(['compilation']),
canceled: new SyncHook<[webpack.Compilation]>(['compilation']),
error: new SyncHook<[Error, webpack.Compilation]>(['error', 'compilation']),
issues: new SyncWaterfallHook<[Issue[], webpack.Compilation | undefined], void>([
'issues',
'compilation',
]),
Expand Down
9 changes: 5 additions & 4 deletions src/hooks/tapAfterEnvironmentToPatchWatching.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import webpack from 'webpack';
import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState';
import { InclusiveNodeWatchFileSystem } from '../watch/InclusiveNodeWatchFileSystem';
import { CompilerWithWatchFileSystem } from '../watch/CompilerWithWatchFileSystem';
import { WatchFileSystem } from '../watch/WatchFileSystem';

function tapAfterEnvironmentToPatchWatching(
compiler: webpack.Compiler,
state: ForkTsCheckerWebpackPluginState
) {
compiler.hooks.afterEnvironment.tap('ForkTsCheckerWebpackPlugin', () => {
const watchFileSystem = (compiler as CompilerWithWatchFileSystem).watchFileSystem;
const watchFileSystem = compiler.watchFileSystem;
if (watchFileSystem) {
// wrap original watch file system
(compiler as CompilerWithWatchFileSystem).watchFileSystem = new InclusiveNodeWatchFileSystem(
watchFileSystem,
compiler.watchFileSystem = new InclusiveNodeWatchFileSystem(
// we use some internals here
watchFileSystem as WatchFileSystem,
compiler,
state
);
Expand Down
2 changes: 1 addition & 1 deletion src/hooks/tapDoneToAsyncGetIssues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ function tapDoneToAsyncGetIssues(
}

if (stats.startTime) {
configuration.logger.infrastructure.info(
configuration.logger.infrastructure.log(
`Time: ${Math.round(Date.now() - stats.startTime).toString()} ms`
);
}
Expand Down
4 changes: 2 additions & 2 deletions src/hooks/tapStartToConnectAndRunReporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ function tapStartToConnectAndRunReporter(
if (state.watching) {
change = getFilesChange(compiler);

configuration.logger.infrastructure.info(
configuration.logger.infrastructure.log(
[
'Calling reporter service for incremental check.',
` Changed files: ${JSON.stringify(change.changedFiles)}`,
` Deleted files: ${JSON.stringify(change.deletedFiles)}`,
].join('\n')
);
} else {
configuration.logger.infrastructure.info('Calling reporter service for single check.');
configuration.logger.infrastructure.log('Calling reporter service for single check.');
}

let resolveDependencies: (dependencies: FilesMatch | undefined) => void;
Expand Down
5 changes: 3 additions & 2 deletions src/issue/IssueWebpackError.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import webpack from 'webpack';
import { relative } from 'path';
import { Issue } from './Issue';
import { formatIssueLocation } from './IssueLocation';
import forwardSlash from '../utils/path/forwardSlash';

class IssueWebpackError extends Error {
class IssueWebpackError extends webpack.WebpackError {
readonly hideStack = true;
readonly file: string | undefined;
readonly file: string = '';

constructor(message: string, readonly issue: Issue) {
super(message);
Expand Down
5 changes: 4 additions & 1 deletion src/logger/LoggerConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ function createLoggerConfiguration(
options: LoggerOptions | undefined
): LoggerConfiguration {
return {
infrastructure: createLogger((options && options.infrastructure) || 'silent', compiler),
infrastructure: createLogger(
(options && options.infrastructure) || 'webpack-infrastructure',
compiler
),
issues: createLogger((options && options.issues) || 'console', compiler),
devServer: options?.devServer !== false,
};
Expand Down
2 changes: 1 addition & 1 deletion src/reporter/FilesChange.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface FilesChange {
const compilerFilesChangeMap = new WeakMap<Compiler, FilesChange>();

function getFilesChange(compiler: Compiler): FilesChange {
return compilerFilesChangeMap.get(compiler) || {};
return compilerFilesChangeMap.get(compiler) || { changedFiles: [], deletedFiles: [] };
}

function updateFilesChange(compiler: Compiler, change: FilesChange): void {
Expand Down
9 changes: 0 additions & 9 deletions src/watch/CompilerWithWatchFileSystem.ts

This file was deleted.

26 changes: 12 additions & 14 deletions src/watch/InclusiveNodeWatchFileSystem.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,21 @@
import { ForkTsCheckerWebpackPluginState } from '../ForkTsCheckerWebpackPluginState';
import chokidar, { FSWatcher } from 'chokidar';
import { extname } from 'path';
import { Watcher, WatchFileSystem, WatchFileSystemOptions } from './WatchFileSystem';
import { WatchFileSystem } from './WatchFileSystem';
import { Compiler } from 'webpack';
import { clearFilesChange, updateFilesChange } from '../reporter';
import minimatch from 'minimatch';

const BUILTIN_IGNORED_DIRS = ['node_modules', '.git', '.yarn', '.pnp'];

function createIsIgnored(
ignored: WatchFileSystemOptions['ignored'] | undefined
ignored: string | RegExp | (string | RegExp)[] | undefined
): (path: string) => boolean {
const ignoredPatterns = ignored ? (Array.isArray(ignored) ? ignored : [ignored]) : [];
const ignoredFunctions = ignoredPatterns.map((pattern) => {
// ensure patterns are valid - see https://github.com/TypeStrong/fork-ts-checker-webpack-plugin/issues/594
if (typeof pattern === 'string') {
return (path: string) => minimatch(path, pattern);
} else if (typeof pattern === 'function') {
return pattern;
} else if (pattern instanceof RegExp) {
return (path: string) => pattern.test(path);
} else {
Expand Down Expand Up @@ -50,15 +48,15 @@ class InclusiveNodeWatchFileSystem implements WatchFileSystem {

private paused = true;

watch(
files: Iterable<string>,
dirs: Iterable<string>,
missing: Iterable<string>,
startTime?: number,
options?: Partial<WatchFileSystemOptions>,
callback?: Function,
callbackUndelayed?: Function
): Watcher {
watch: WatchFileSystem['watch'] = (
files,
dirs,
missing,
startTime,
options,
callback,
callbackUndelayed
) => {
clearFilesChange(this.compiler);
const isIgnored = createIsIgnored(options?.ignored);

Expand Down Expand Up @@ -173,7 +171,7 @@ class InclusiveNodeWatchFileSystem implements WatchFileSystem {
this.paused = true;
},
};
}
};
}

export { InclusiveNodeWatchFileSystem };
38 changes: 4 additions & 34 deletions src/watch/WatchFileSystem.ts
Original file line number Diff line number Diff line change
@@ -1,50 +1,20 @@
import { EventEmitter } from 'events';

interface WatchFileSystemOptions {
aggregateTimeout: number;
poll: boolean;
followSymlinks: boolean;
ignored: string | RegExp | Function | (string | RegExp | Function)[];
}
import webpack from 'webpack';

// watchpack v1 and v2 internal interface
interface Watchpack extends EventEmitter {
_onChange(item: string, mtime: number, file: string, type?: string): void;
_onRemove(item: string, file: string, type?: string): void;
}

// webpack 4 interface
interface WatcherV4 {
close(): void;
pause(): void;
getFileTimestamps(): Map<string, number>;
getContextTimestamps(): Map<string, number>;
}

// webpack 5 interface
interface WatcherV5 {
close(): void;
pause(): void;
getFileTimeInfoEntries(): Map<string, number>;
getContextTimeInfoEntries(): Map<string, number>;
}

type Watcher = WatcherV4 | WatcherV5;
type Watch = webpack.Compiler['watchFileSystem']['watch'];

interface WatchFileSystem {
watcher: Watchpack;
wfs?: {
watcher: Watchpack;
};
watch(
files: Iterable<string>,
dirs: Iterable<string>,
missing: Iterable<string>,
startTime?: number,
options?: Partial<WatchFileSystemOptions>,
callback?: Function,
callbackUndelayed?: Function
): Watcher;
watch: Watch;
}

export { WatchFileSystem, WatchFileSystemOptions, Watchpack, WatcherV4, WatcherV5, Watcher };
export { WatchFileSystem, Watchpack };
60 changes: 29 additions & 31 deletions test/e2e/OutOfMemoryAndCosmiconfig.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,38 @@ import path from 'path';
import { createProcessDriver } from 'karton';

describe('ForkTsCheckerWebpackPlugin Out Of Memory and Cosmiconfig', () => {
it.each([
{ async: false, webpack: '4.0.0' },
{ async: true, webpack: '^4.0.0' },
{ async: false, webpack: '^5.0.0' },
{ async: true, webpack: '^5.0.0' },
])('handles out of memory for %p', async ({ async, webpack }) => {
await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic'));
await sandbox.install('yarn', { webpack });
await sandbox.patch('webpack.config.js', 'async: false,', `async: ${JSON.stringify(async)},`);
it.each([{ async: false }, { async: true }])(
'handles out of memory for %p',
async ({ async }) => {
await sandbox.load(path.join(__dirname, 'fixtures/typescript-basic'));
await sandbox.install('yarn', {});
await sandbox.patch('webpack.config.js', 'async: false,', `async: ${JSON.stringify(async)},`);

await sandbox.write(
'fork-ts-checker.config.js',
`module.exports = { typescript: { memoryLimit: 10 } };`
);
await sandbox.write(
'fork-ts-checker.config.js',
`module.exports = { typescript: { memoryLimit: 10 } };`
);

const driver = createProcessDriver(sandbox.spawn('npm run webpack-dev-server'));
const driver = createProcessDriver(sandbox.spawn('yarn webpack serve --mode=development'));

// we should see an error message about out of memory
await driver.waitForStderrIncludes(
'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' +
"If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript."
);
// we should see an error message about out of memory
await driver.waitForStderrIncludes(
'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' +
"If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript."
);

// let's modify one file to check if plugin will try to restart the service
await sandbox.patch(
'src/index.ts',
"import { getUserName } from './model/User';",
"import { getUserName } from './model/User';\n"
);
// let's modify one file to check if plugin will try to restart the service
await sandbox.patch(
'src/index.ts',
"import { getUserName } from './model/User';",
"import { getUserName } from './model/User';\n"
);

// we should see an error message about out of memory again
await driver.waitForStderrIncludes(
'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' +
"If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript."
);
});
// we should see an error message about out of memory again
await driver.waitForStderrIncludes(
'Issues checking service aborted - probably out of memory. Check the `memoryLimit` option in the ForkTsCheckerWebpackPlugin configuration.\n' +
"If increasing the memory doesn't solve the issue, it's most probably a bug in the TypeScript."
);
}
);
});
4 changes: 2 additions & 2 deletions test/e2e/TypeDefinitions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ describe('Type Definitions', () => {
await sandbox.load(path.join(__dirname, 'fixtures/type-definitions'));
await sandbox.install('yarn', {});

expect(await sandbox.exec('npm run tsc').catch((error) => error)).toContain(
expect(await sandbox.exec('yarn tsc', { fail: true })).toContain(
"webpack.config.ts(7,7): error TS2322: Type 'string' is not assignable to type 'boolean | undefined'."
);

await sandbox.patch('webpack.config.ts', "async: 'invalid_value'", 'async: true');

expect(await sandbox.exec('npm run tsc')).not.toContain('error TS');
expect(await sandbox.exec('yarn tsc')).not.toContain('error TS');
});
});
Loading

0 comments on commit cdb531f

Please sign in to comment.