Skip to content

Commit

Permalink
feat: use micromatch for lazy tsconfig glob matching
Browse files Browse the repository at this point in the history
This should also fix !32 since files are not collected only once
anymore but lazily matched against the tsconfig glob
  • Loading branch information
Etienne-Buschong committed Jan 18, 2023
1 parent a0c39dd commit 9ff696d
Show file tree
Hide file tree
Showing 10 changed files with 78 additions and 27 deletions.
1 change: 1 addition & 0 deletions .idea/prettier.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
"@storybook/manager-webpack5": "~6.5.9",
"@types/jest": "28.1.8",
"@types/node": "16.11.7",
"@types/micromatch": "^4.0.2",
"@typescript-eslint/eslint-plugin": "5.40.0",
"@typescript-eslint/parser": "5.40.0",
"eslint": "~8.15.0",
Expand All @@ -59,6 +60,8 @@
"prettier": "^2.6.2",
"ts-jest": "28.0.8",
"ts-morph": "^15.1.0",
"get-tsconfig": "^4.3.0",
"micromatch": "^4.0.5",
"ts-node": "10.9.1",
"typescript": "4.8.4",
"webpack": "^5.64.0",
Expand Down
6 changes: 5 additions & 1 deletion packages/angular-demo/.storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ module.exports = {
}

// add your own webpack tweaks if needed
config.plugins.push(new WebpackAngularTypesPlugin());
config.plugins.push(
new WebpackAngularTypesPlugin({
tsconfigPath: './packages/angular-demo/.storybook/tsconfig.json',
}),
);

return config;
},
Expand Down
2 changes: 1 addition & 1 deletion packages/angular-demo/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
],
"compilerOptions": {
"target": "es2020",
"target": "es2021",
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitOverride": true,
Expand Down
4 changes: 3 additions & 1 deletion packages/storybook-webpack-angular-types-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
"version": "0.0.1",
"type": "commonjs",
"dependencies": {
"ts-morph": "^15.1.0"
"ts-morph": "^15.1.0",
"get-tsconfig": "^4.3.0",
"micromatch": "^4.0.5"
},
"peerDependencies": {
"@storybook/components": "^6.5.10",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Module } from 'webpack';

export interface WebpackAngularTypesPluginOptions {
excludeProperties?: RegExp;
tsconfigPath?: string;
}

export type EntityModifier = 'getter' | 'setter';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import { getTsconfig } from 'get-tsconfig';
import * as micromatch from 'micromatch';
import * as path from 'path';
import * as process from 'process';
import { ModuleKind, ModuleResolutionKind, Project, ScriptTarget } from 'ts-morph';
import { Compiler, Module } from 'webpack';
import { DEFAULT_TS_CONFIG_PATH, PLUGIN_NAME } from '../constants';
Expand All @@ -12,17 +16,9 @@ export class WebpackAngularTypesPlugin {
// A queue for modules, that should be processed by the plugin in the next seal-hook
private moduleQueue: Module[] = [];

// A dummy tsProject that is used to gather the glob-paths from the "include"
// field of the tsconfig file (therefore all dependency resolution etc is skipped)
// TODO maybe this can be replaced with a super-fast glob implementation
private tsProject = new Project({
tsConfigFilePath: DEFAULT_TS_CONFIG_PATH,
skipLoadingLibFiles: true,
skipFileDependencyResolution: true,
});
private readonly tsconfigPaths: string[] = this.getTsconfigPaths();

constructor(private options: WebpackAngularTypesPluginOptions = {}) {}

apply(compiler: Compiler) {
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
compilation.dependencyTemplates.set(CodeDocDependency, new CodeDocDependencyTemplate());
Expand Down Expand Up @@ -78,19 +74,14 @@ export class WebpackAngularTypesPlugin {

private isModuleProcessable(module: Module): boolean {
const filePath = module.nameForCondition();
return !!filePath && filePath.endsWith('.ts') && this.isPathIncludedInTsConfig(filePath);
}

// Skip null values (e.g. raw files)
if (!filePath) {
return false;
}

// Only add modules that are part of the tsProject
// noinspection RedundantIfStatementJS
if (!this.tsProject.getSourceFile(filePath) || !filePath.endsWith('.ts')) {
return false;
}

return true;
private isPathIncludedInTsConfig(pathToCheck: string): boolean {
const res = micromatch([pathToCheck], this.tsconfigPaths, {
format: this.toUnixPath,
});
return res.length === 1;
}

private getProcessableModule(module: Module): ModuleInformation | null {
Expand All @@ -104,4 +95,34 @@ export class WebpackAngularTypesPlugin {
path: filePath,
};
}

private getTsconfigPaths(): string[] {
const tsconfigPath = this.options.tsconfigPath ?? DEFAULT_TS_CONFIG_PATH;
const tsconfigResult = getTsconfig(tsconfigPath);
//
const tsConfigRootDir = path.join(process.cwd(), tsconfigPath, '..');
const includedPaths = tsconfigResult?.config.include || [];
const excludedPaths = tsconfigResult?.config.exclude || [];
return [
...this.transformToAbsolutePaths(tsConfigRootDir, includedPaths),
...this.transformToAbsolutePaths(tsConfigRootDir, excludedPaths).map(this.negateGlob),
].map(this.toUnixPath);
}

private transformToAbsolutePaths(base: string, paths: string[]): string[] {
return paths.map((p) => {
if (path.isAbsolute(p)) {
return p;
}
return path.join(base, p);
});
}

private negateGlob(glob: string): string {
return `!${glob}`;
}

private toUnixPath(path: string): string {
return path.replaceAll('\\', '/');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"noImplicitOverride": true,
"noPropertyAccessFromIndexSignature": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true
"noFallthroughCasesInSwitch": true,
"types": ["node"]
},
"files": [],
"include": [],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"declaration": true,
"types": []
"types": ["node"],
"lib": ["ES2021", "DOM"]
},
"include": ["**/*.ts"],
"exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.test.ts"]
Expand Down
19 changes: 18 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3583,6 +3583,11 @@
dependencies:
"@types/node" "*"

"@types/braces@*":
version "3.0.1"
resolved "https://repo.aeb.com/artifactory/api/npm/npm/@types/braces/-/braces-3.0.1.tgz#5a284d193cfc61abb2e5a50d36ebbc50d942a32b"
integrity sha512-+euflG6ygo4bn0JHtn4pYqcXwRtLvElQ7/nnjDu7iYG56H0+OhCd7d6Ug0IE3WcFpZozBKW2+80FUbv5QGk5AQ==

"@types/connect-history-api-fallback@^1.3.5":
version "1.3.5"
resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae"
Expand Down Expand Up @@ -3745,6 +3750,13 @@
dependencies:
"@types/unist" "*"

"@types/micromatch@^4.0.2":
version "4.0.2"
resolved "https://repo.aeb.com/artifactory/api/npm/npm/@types/micromatch/-/micromatch-4.0.2.tgz#ce29c8b166a73bf980a5727b1e4a4d099965151d"
integrity sha512-oqXqVb0ci19GtH0vOA/U2TmHTcRY9kuZl4mqUxe0QmJAlIW13kzhuK5pi1i9+ngav8FjpSb9FVS/GE00GLX1VA==
dependencies:
"@types/braces" "*"

"@types/mime@*":
version "3.0.1"
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10"
Expand Down Expand Up @@ -8259,6 +8271,11 @@ get-symbol-description@^1.0.0:
call-bind "^1.0.2"
get-intrinsic "^1.1.1"

get-tsconfig@^4.3.0:
version "4.3.0"
resolved "https://repo.aeb.com/artifactory/api/npm/npm/get-tsconfig/-/get-tsconfig-4.3.0.tgz#4c26fae115d1050e836aea65d6fe56b507ee249b"
integrity sha512-YCcF28IqSay3fqpIu5y3Krg/utCBHBeoflkZyHj/QcqI2nrLPC3ZegS9CmIo+hJb8K7aiGsuUl7PwWVjNG2HQQ==

get-value@^2.0.3, get-value@^2.0.6:
version "2.0.6"
resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28"
Expand Down Expand Up @@ -10857,7 +10874,7 @@ micromatch@^3.1.10, micromatch@^3.1.4:
snapdragon "^0.8.1"
to-regex "^3.0.2"

micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4:
micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
version "4.0.5"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6"
integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==
Expand Down

0 comments on commit 9ff696d

Please sign in to comment.