From aa18204dc1991bf7f8292c0ae77c99024e920073 Mon Sep 17 00:00:00 2001 From: Brody McKee Date: Sat, 11 Mar 2023 18:34:08 +1100 Subject: [PATCH 1/4] feat: add support for TypeScript 5.x (#211) --- package.json | 4 +- pnpm-lock.yaml | 60 ++++---- src/helpers/getDtsSnapshot.ts | 14 +- src/helpers/logger.ts | 4 +- src/index.ts | 250 +++++++++++++++++++--------------- 5 files changed, 177 insertions(+), 155 deletions(-) diff --git a/package.json b/package.json index 00ff202..dcceefa 100644 --- a/package.json +++ b/package.json @@ -88,10 +88,10 @@ "prettier": "^2.8.4", "sass-svg": "^1.2.0", "ts-jest": "^29.0.5", - "typescript": "^4.9.5" + "typescript": "5.0.1-rc" }, "peerDependencies": { - "typescript": ">=3.9.0" + "typescript": ">=4.0.0" }, "pnpm": { "peerDependencyRules": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 12a0a25..3fdf686 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,7 +41,7 @@ specifiers: stylus: ^0.59.0 ts-jest: ^29.0.5 tsconfig-paths: ^4.1.2 - typescript: ^4.9.5 + typescript: 5.0.1-rc dependencies: '@types/postcss-modules-local-by-default': 4.0.0 @@ -71,8 +71,8 @@ devDependencies: '@types/reserved-words': 0.1.0 '@types/sass': 1.43.1 '@types/stylus': 0.48.38 - '@typescript-eslint/eslint-plugin': 5.52.0_6cfvjsbua5ptj65675bqcn6oza - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/eslint-plugin': 5.52.0_33une6q4pekq4oqyxswvgaojau + '@typescript-eslint/parser': 5.52.0_fza5zxhga7jm57t3nlmf434qle bootstrap: 5.2.3 eslint: 8.34.0 eslint-config-prettier: 8.6.0_eslint@8.34.0 @@ -85,8 +85,8 @@ devDependencies: postcss-preset-env: 8.0.1_postcss@8.4.21 prettier: 2.8.4 sass-svg: 1.2.0 - ts-jest: 29.0.5_orzzknleilowtsz34rkaotjvzm - typescript: 4.9.5 + ts-jest: 29.0.5_aklba2ajlv45ppanivltqizwqi + typescript: 5.0.1-rc packages: @@ -1196,7 +1196,7 @@ packages: '@types/yargs-parser': 13.1.0 dev: true - /@typescript-eslint/eslint-plugin/5.52.0_6cfvjsbua5ptj65675bqcn6oza: + /@typescript-eslint/eslint-plugin/5.52.0_33une6q4pekq4oqyxswvgaojau: resolution: {integrity: sha512-lHazYdvYVsBokwCdKOppvYJKaJ4S41CgKBcPvyd0xjZNbvQdhn/pnJlGtQksQ/NhInzdaeaSarlBjDXHuclEbg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1207,10 +1207,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/parser': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/parser': 5.52.0_fza5zxhga7jm57t3nlmf434qle '@typescript-eslint/scope-manager': 5.52.0 - '@typescript-eslint/type-utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm - '@typescript-eslint/utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/type-utils': 5.52.0_fza5zxhga7jm57t3nlmf434qle + '@typescript-eslint/utils': 5.52.0_fza5zxhga7jm57t3nlmf434qle debug: 4.3.4 eslint: 8.34.0 grapheme-splitter: 1.0.4 @@ -1218,13 +1218,13 @@ packages: natural-compare-lite: 1.4.0 regexpp: 3.2.0 semver: 7.3.8 - tsutils: 3.21.0_typescript@4.9.5 - typescript: 4.9.5 + tsutils: 3.21.0_typescript@5.0.1-rc + typescript: 5.0.1-rc transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.52.0_7kw3g6rralp5ps6mg3uyzz6azm: + /@typescript-eslint/parser/5.52.0_fza5zxhga7jm57t3nlmf434qle: resolution: {integrity: sha512-e2KiLQOZRo4Y0D/b+3y08i3jsekoSkOYStROYmPUnGMEoA0h+k2qOH5H6tcjIc68WDvGwH+PaOrP1XRzLJ6QlA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1236,10 +1236,10 @@ packages: dependencies: '@typescript-eslint/scope-manager': 5.52.0 '@typescript-eslint/types': 5.52.0 - '@typescript-eslint/typescript-estree': 5.52.0_typescript@4.9.5 + '@typescript-eslint/typescript-estree': 5.52.0_typescript@5.0.1-rc debug: 4.3.4 eslint: 8.34.0 - typescript: 4.9.5 + typescript: 5.0.1-rc transitivePeerDependencies: - supports-color dev: true @@ -1252,7 +1252,7 @@ packages: '@typescript-eslint/visitor-keys': 5.52.0 dev: true - /@typescript-eslint/type-utils/5.52.0_7kw3g6rralp5ps6mg3uyzz6azm: + /@typescript-eslint/type-utils/5.52.0_fza5zxhga7jm57t3nlmf434qle: resolution: {integrity: sha512-tEKuUHfDOv852QGlpPtB3lHOoig5pyFQN/cUiZtpw99D93nEBjexRLre5sQZlkMoHry/lZr8qDAt2oAHLKA6Jw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1262,12 +1262,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.52.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.52.0_7kw3g6rralp5ps6mg3uyzz6azm + '@typescript-eslint/typescript-estree': 5.52.0_typescript@5.0.1-rc + '@typescript-eslint/utils': 5.52.0_fza5zxhga7jm57t3nlmf434qle debug: 4.3.4 eslint: 8.34.0 - tsutils: 3.21.0_typescript@4.9.5 - typescript: 4.9.5 + tsutils: 3.21.0_typescript@5.0.1-rc + typescript: 5.0.1-rc transitivePeerDependencies: - supports-color dev: true @@ -1277,7 +1277,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.52.0_typescript@4.9.5: + /@typescript-eslint/typescript-estree/5.52.0_typescript@5.0.1-rc: resolution: {integrity: sha512-WeWnjanyEwt6+fVrSR0MYgEpUAuROxuAH516WPjUblIrClzYJj0kBbjdnbQXLpgAN8qbEuGywiQsXUVDiAoEuQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1292,13 +1292,13 @@ packages: globby: 11.1.0 is-glob: 4.0.3 semver: 7.3.8 - tsutils: 3.21.0_typescript@4.9.5 - typescript: 4.9.5 + tsutils: 3.21.0_typescript@5.0.1-rc + typescript: 5.0.1-rc transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.52.0_7kw3g6rralp5ps6mg3uyzz6azm: + /@typescript-eslint/utils/5.52.0_fza5zxhga7jm57t3nlmf434qle: resolution: {integrity: sha512-As3lChhrbwWQLNk2HC8Ree96hldKIqk98EYvypd3It8Q1f8d5zWyIoaZEp2va5667M4ZyE7X8UUR+azXrFl+NA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1308,7 +1308,7 @@ packages: '@types/semver': 7.3.13 '@typescript-eslint/scope-manager': 5.52.0 '@typescript-eslint/types': 5.52.0 - '@typescript-eslint/typescript-estree': 5.52.0_typescript@4.9.5 + '@typescript-eslint/typescript-estree': 5.52.0_typescript@5.0.1-rc eslint: 8.34.0 eslint-scope: 5.1.1 eslint-utils: 3.0.0_eslint@8.34.0 @@ -4342,7 +4342,7 @@ packages: dependencies: is-number: 7.0.0 - /ts-jest/29.0.5_orzzknleilowtsz34rkaotjvzm: + /ts-jest/29.0.5_aklba2ajlv45ppanivltqizwqi: resolution: {integrity: sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} hasBin: true @@ -4371,7 +4371,7 @@ packages: lodash.memoize: 4.1.2 make-error: 1.3.5 semver: 7.3.8 - typescript: 4.9.5 + typescript: 5.0.1-rc yargs-parser: 21.1.1 dev: true @@ -4391,14 +4391,14 @@ packages: /tslib/2.4.1: resolution: {integrity: sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==} - /tsutils/3.21.0_typescript@4.9.5: + /tsutils/3.21.0_typescript@5.0.1-rc: resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} engines: {node: '>= 6'} peerDependencies: typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' dependencies: tslib: 1.11.0 - typescript: 4.9.5 + typescript: 5.0.1-rc dev: true /type-check/0.4.0: @@ -4423,8 +4423,8 @@ packages: engines: {node: '>=10'} dev: true - /typescript/4.9.5: - resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + /typescript/5.0.1-rc: + resolution: {integrity: sha512-zh75jY8gPo/y7fpmlTVN2bb2MigoLx4hGk+Cla9pY6lgSTvzJrmQQrRt5S80VTsEt6biWPZJgLK2nm6f0Ya+mA==} engines: {node: '>=4.2.0'} hasBin: true dev: true diff --git a/src/helpers/getDtsSnapshot.ts b/src/helpers/getDtsSnapshot.ts index a14ca7f..f1cd601 100644 --- a/src/helpers/getDtsSnapshot.ts +++ b/src/helpers/getDtsSnapshot.ts @@ -1,3 +1,4 @@ +import { readFileSync } from 'fs'; import tsModule from 'typescript/lib/tsserverlibrary'; import { Options } from '../options'; import { getCssExports } from './getCssExports'; @@ -9,23 +10,12 @@ export const getDtsSnapshot = ( ts: typeof tsModule, processor: Processor, fileName: string, - scriptSnapshot: ts.IScriptSnapshot, options: Options, logger: Logger, compilerOptions: tsModule.CompilerOptions, directory: string, ): tsModule.IScriptSnapshot => { - const css = scriptSnapshot.getText(0, scriptSnapshot.getLength()); - - /* - * TODO: Temporary workaround for: - * https://github.com/mrmckeb/typescript-plugin-css-modules/issues/41 - * Needs investigation for a more elegant solution. - */ - if (css.includes('export default classes')) { - return scriptSnapshot; - } - + const css = readFileSync(fileName, 'utf-8'); const cssExports = getCssExports({ css, fileName, diff --git a/src/helpers/logger.ts b/src/helpers/logger.ts index a877f86..11a1a39 100644 --- a/src/helpers/logger.ts +++ b/src/helpers/logger.ts @@ -1,9 +1,11 @@ +import { server } from 'typescript/lib/tsserverlibrary'; + export interface Logger { log: (message: string) => void; error: (error: unknown) => void; } -export const createLogger = (info: ts.server.PluginCreateInfo): Logger => { +export const createLogger = (info: server.PluginCreateInfo): Logger => { const log = (message: string) => { info.project.projectService.logger.info( `[typescript-plugin-css-modules] ${message}`, diff --git a/src/index.ts b/src/index.ts index 06fa531..6aa2f5b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import path from 'path'; import dotenv from 'dotenv'; import { AcceptedPlugin } from 'postcss'; import postcssrc from 'postcss-load-config'; -import tsModule from 'typescript/lib/tsserverlibrary'; +import { server } from 'typescript/lib/tsserverlibrary'; import { Options } from './options'; import { createMatchers } from './helpers/createMatchers'; import { isCSSFn } from './helpers/cssExtensions'; @@ -11,6 +11,14 @@ import { getDtsSnapshot } from './helpers/getDtsSnapshot'; import { createLogger } from './helpers/logger'; import { getProcessor } from './helpers/getProcessor'; import { filterPlugins } from './helpers/filterPlugins'; +import { + createLanguageService, + Extension, + LanguageService, + LanguageServiceHost, + ResolvedModuleFull, + ScriptKind, +} from 'typescript'; const getPostCssConfigPlugins = (directory: string) => { try { @@ -20,14 +28,26 @@ const getPostCssConfigPlugins = (directory: string) => { } }; -function init({ typescript: ts }: { typescript: typeof tsModule }) { +const init: server.PluginModuleFactory = ({ typescript: ts }) => { let _isCSS: isCSSFn; - function create(info: ts.server.PluginCreateInfo) { + function create(info: server.PluginCreateInfo): LanguageService { const logger = createLogger(info); const directory = info.project.getCurrentDirectory(); const compilerOptions = info.project.getCompilerOptions(); + const languageServiceHost = {} as Partial; + + const languageServiceHostProxy = new Proxy(info.languageServiceHost, { + get(target, key: keyof LanguageServiceHost) { + return languageServiceHost[key] + ? languageServiceHost[key] + : target[key]; + }, + }); + + const languageService = createLanguageService(languageServiceHostProxy); + // TypeScript plugins have a `cwd` of `/`, which causes issues with import resolution. process.chdir(directory); @@ -101,73 +121,136 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) { const { isCSS, isRelativeCSS } = createMatchers(logger, options); _isCSS = isCSS; - // Creates new virtual source files for the CSS modules. - const _createLanguageServiceSourceFile = ts.createLanguageServiceSourceFile; - ts.createLanguageServiceSourceFile = ( - fileName, - scriptSnapshot, - ...rest - ): ts.SourceFile => { - if (isCSS(fileName)) { - scriptSnapshot = getDtsSnapshot( - ts, - processor, - fileName, - scriptSnapshot, - options, - logger, - compilerOptions, - directory, - ); + languageServiceHost.getScriptKind = (fileName) => { + if (!info.languageServiceHost.getScriptKind) { + return ScriptKind.Unknown; } - const sourceFile = _createLanguageServiceSourceFile( - fileName, - scriptSnapshot, - ...rest, - ); if (isCSS(fileName)) { - sourceFile.isDeclarationFile = true; + return ScriptKind.TS; } - return sourceFile; + return info.languageServiceHost.getScriptKind(fileName); }; - // Updates virtual source files as files update. - const _updateLanguageServiceSourceFile = ts.updateLanguageServiceSourceFile; - ts.updateLanguageServiceSourceFile = ( - sourceFile, - scriptSnapshot, - ...rest - ): ts.SourceFile => { - if (isCSS(sourceFile.fileName)) { - scriptSnapshot = getDtsSnapshot( + languageServiceHost.getScriptSnapshot = (fileName) => { + if (isCSS(fileName)) { + return getDtsSnapshot( ts, processor, - sourceFile.fileName, - scriptSnapshot, + fileName, options, logger, compilerOptions, directory, ); } - sourceFile = _updateLanguageServiceSourceFile( - sourceFile, - scriptSnapshot, - ...rest, - ); - if (isCSS(sourceFile.fileName)) { - sourceFile.isDeclarationFile = true; - } - return sourceFile; + return info.languageServiceHost.getScriptSnapshot(fileName); }; - if (info.languageServiceHost.resolveModuleNames) { + const createModuleResolver = + (containingFile: string) => + (moduleName: string): ResolvedModuleFull | undefined => { + if (isRelativeCSS(moduleName)) { + return { + extension: Extension.Dts, + isExternalLibraryImport: false, + resolvedFileName: path.resolve( + path.dirname(containingFile), + moduleName, + ), + }; + } else if ( + isCSS(moduleName) && + languageServiceHost.getResolvedModuleWithFailedLookupLocationsFromCache + ) { + // TODO: Move this section to a separate file and add basic tests. + // Attempts to locate the module using TypeScript's previous search paths. These include "baseUrl" and "paths". + const failedModule = + languageServiceHost.getResolvedModuleWithFailedLookupLocationsFromCache( + moduleName, + containingFile, + ); + const baseUrl = info.project.getCompilerOptions().baseUrl; + const match = '/index.ts'; + + // An array of paths TypeScript searched for the module. All include .ts, .tsx, .d.ts, or .json extensions. + // NOTE: TypeScript doesn't expose this in their interfaces, which is why the type is unknown. + // https://github.com/microsoft/TypeScript/issues/28770 + const failedLocations: readonly string[] = ( + failedModule as unknown as { + failedLookupLocations: readonly string[]; + } + ).failedLookupLocations; + + // Filter to only one extension type, and remove that extension. This leaves us with the actual file name. + // Example: "usr/person/project/src/dir/File.module.css/index.d.ts" > "usr/person/project/src/dir/File.module.css" + const normalizedLocations = failedLocations.reduce( + (locations, location) => { + if ( + (baseUrl ? location.includes(baseUrl) : true) && + location.endsWith(match) + ) { + return [...locations, location.replace(match, '')]; + } + return locations; + }, + [], + ); + + // Find the imported CSS module, if it exists. + const cssModulePath = normalizedLocations.find((location) => + fs.existsSync(location), + ); + + if (cssModulePath) { + return { + extension: Extension.Dts, + isExternalLibraryImport: false, + resolvedFileName: path.resolve(cssModulePath), + }; + } + } + }; + + // TypeScript 5.x + if (info.languageServiceHost.resolveModuleNameLiterals) { + const _resolveModuleNameLiterals = + info.languageServiceHost.resolveModuleNameLiterals.bind( + info.languageServiceHost, + ); + + languageServiceHost.resolveModuleNameLiterals = ( + moduleNames, + containingFile, + ...rest + ) => { + const resolvedModules = _resolveModuleNameLiterals( + moduleNames, + containingFile, + ...rest, + ); + + const moduleResolver = createModuleResolver(containingFile); + + return moduleNames.map(({ text: moduleName }, index) => { + try { + const resolvedModule = moduleResolver(moduleName); + if (resolvedModule) return { resolvedModule }; + } catch (e) { + logger.error(e); + return resolvedModules[index]; + } + return resolvedModules[index]; + }); + }; + } + // TypeScript 4.x + else if (info.languageServiceHost.resolveModuleNames) { const _resolveModuleNames = info.languageServiceHost.resolveModuleNames.bind( info.languageServiceHost, ); - info.languageServiceHost.resolveModuleNames = ( + languageServiceHost.resolveModuleNames = ( moduleNames, containingFile, ...rest @@ -178,65 +261,12 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) { ...rest, ); + const moduleResolver = createModuleResolver(containingFile); + return moduleNames.map((moduleName, index) => { try { - if (isRelativeCSS(moduleName)) { - return { - extension: tsModule.Extension.Dts, - isExternalLibraryImport: false, - resolvedFileName: path.resolve( - path.dirname(containingFile), - moduleName, - ), - }; - } else if (isCSS(moduleName)) { - // TODO: Move this section to a separate file and add basic tests. - // Attempts to locate the module using TypeScript's previous search paths. These include "baseUrl" and "paths". - const failedModule = - info.project.getResolvedModuleWithFailedLookupLocationsFromCache( - moduleName, - containingFile, - ); - const baseUrl = info.project.getCompilerOptions().baseUrl; - const match = '/index.ts'; - - // An array of paths TypeScript searched for the module. All include .ts, .tsx, .d.ts, or .json extensions. - // NOTE: TypeScript doesn't expose this in their interfaces, which is why the type is unkown. - // https://github.com/microsoft/TypeScript/issues/28770 - const failedLocations: readonly string[] = ( - failedModule as unknown as { - failedLookupLocations: readonly string[]; - } - ).failedLookupLocations; - - // Filter to only one extension type, and remove that extension. This leaves us with the actual filename. - // Example: "usr/person/project/src/dir/File.module.css/index.d.ts" > "usr/person/project/src/dir/File.module.css" - const normalizedLocations = failedLocations.reduce( - (locations, location) => { - if ( - (baseUrl ? location.includes(baseUrl) : true) && - location.endsWith(match) - ) { - return [...locations, location.replace(match, '')]; - } - return locations; - }, - [], - ); - - // Find the imported CSS module, if it exists. - const cssModulePath = normalizedLocations.find((location) => - fs.existsSync(location), - ); - - if (cssModulePath) { - return { - extension: tsModule.Extension.Dts, - isExternalLibraryImport: false, - resolvedFileName: path.resolve(cssModulePath), - }; - } - } + const resolvedModule = moduleResolver(moduleName); + if (resolvedModule) return resolvedModule; } catch (e) { logger.error(e); return resolvedModules[index]; @@ -246,14 +276,14 @@ function init({ typescript: ts }: { typescript: typeof tsModule }) { }; } - return info.languageService; + return languageService; } - function getExternalFiles(project: tsModule.server.ConfiguredProject) { + function getExternalFiles(project: server.ConfiguredProject): string[] { return project.getFileNames().filter(_isCSS); } return { create, getExternalFiles }; -} +}; export = init; From 5bf7d10f77239939bb038757c42a33e2774902a8 Mon Sep 17 00:00:00 2001 From: Brody McKee Date: Sat, 11 Mar 2023 18:36:42 +1100 Subject: [PATCH 2/4] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dcceefa..247d8e4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-plugin-css-modules", - "version": "4.2.3", + "version": "5.0.0-beta.0", "main": "dist/index.js", "author": "Brody McKee ", "license": "MIT", From 19bb10d2677ac28b9597ff75ac726668a1215291 Mon Sep 17 00:00:00 2001 From: Jake Bailey <5341706+jakebailey@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:51:37 -0700 Subject: [PATCH 3/4] refactor: use TypeScript-provided lib and consistent imports (#213) --- src/helpers/__tests__/getDtsSnapshot.test.ts | 2 +- src/helpers/getCssExports.ts | 2 +- src/helpers/getDtsSnapshot.ts | 2 +- src/helpers/logger.ts | 6 ++-- src/index.ts | 36 +++++++++----------- src/options.ts | 2 +- 6 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/helpers/__tests__/getDtsSnapshot.test.ts b/src/helpers/__tests__/getDtsSnapshot.test.ts index 91f98a8..fbd34be 100644 --- a/src/helpers/__tests__/getDtsSnapshot.test.ts +++ b/src/helpers/__tests__/getDtsSnapshot.test.ts @@ -2,7 +2,7 @@ import { readFileSync } from 'fs'; import { join } from 'path'; import postcssImportSync from 'postcss-import-sync2'; import postcssPresetEnv from 'postcss-preset-env'; -import tsModule from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; import { CSSExportsWithSourceMap, getCssExports } from '../getCssExports'; import { createDtsExports } from '../createDtsExports'; import { Logger } from '../logger'; diff --git a/src/helpers/getCssExports.ts b/src/helpers/getCssExports.ts index 530245a..6eb91ba 100644 --- a/src/helpers/getCssExports.ts +++ b/src/helpers/getCssExports.ts @@ -5,7 +5,7 @@ import sass from 'sass'; import stylus from 'stylus'; import { CSSExports, extractICSS } from 'icss-utils'; import { RawSourceMap } from 'source-map-js'; -import tsModule from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; import { createMatchPath } from 'tsconfig-paths'; import { sassTildeImporter } from '../importers/sassTildeImporter'; import { Options, CustomRenderer } from '../options'; diff --git a/src/helpers/getDtsSnapshot.ts b/src/helpers/getDtsSnapshot.ts index f1cd601..02b6790 100644 --- a/src/helpers/getDtsSnapshot.ts +++ b/src/helpers/getDtsSnapshot.ts @@ -1,5 +1,5 @@ import { readFileSync } from 'fs'; -import tsModule from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; import { Options } from '../options'; import { getCssExports } from './getCssExports'; import { createDtsExports } from './createDtsExports'; diff --git a/src/helpers/logger.ts b/src/helpers/logger.ts index 11a1a39..ed97584 100644 --- a/src/helpers/logger.ts +++ b/src/helpers/logger.ts @@ -1,11 +1,13 @@ -import { server } from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; export interface Logger { log: (message: string) => void; error: (error: unknown) => void; } -export const createLogger = (info: server.PluginCreateInfo): Logger => { +export const createLogger = ( + info: tsModule.server.PluginCreateInfo, +): Logger => { const log = (message: string) => { info.project.projectService.logger.info( `[typescript-plugin-css-modules] ${message}`, diff --git a/src/index.ts b/src/index.ts index 6aa2f5b..772a204 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ import path from 'path'; import dotenv from 'dotenv'; import { AcceptedPlugin } from 'postcss'; import postcssrc from 'postcss-load-config'; -import { server } from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; import { Options } from './options'; import { createMatchers } from './helpers/createMatchers'; import { isCSSFn } from './helpers/cssExtensions'; @@ -11,14 +11,6 @@ import { getDtsSnapshot } from './helpers/getDtsSnapshot'; import { createLogger } from './helpers/logger'; import { getProcessor } from './helpers/getProcessor'; import { filterPlugins } from './helpers/filterPlugins'; -import { - createLanguageService, - Extension, - LanguageService, - LanguageServiceHost, - ResolvedModuleFull, - ScriptKind, -} from 'typescript'; const getPostCssConfigPlugins = (directory: string) => { try { @@ -28,25 +20,27 @@ const getPostCssConfigPlugins = (directory: string) => { } }; -const init: server.PluginModuleFactory = ({ typescript: ts }) => { +const init: tsModule.server.PluginModuleFactory = ({ typescript: ts }) => { let _isCSS: isCSSFn; - function create(info: server.PluginCreateInfo): LanguageService { + function create( + info: tsModule.server.PluginCreateInfo, + ): tsModule.LanguageService { const logger = createLogger(info); const directory = info.project.getCurrentDirectory(); const compilerOptions = info.project.getCompilerOptions(); - const languageServiceHost = {} as Partial; + const languageServiceHost = {} as Partial; const languageServiceHostProxy = new Proxy(info.languageServiceHost, { - get(target, key: keyof LanguageServiceHost) { + get(target, key: keyof tsModule.LanguageServiceHost) { return languageServiceHost[key] ? languageServiceHost[key] : target[key]; }, }); - const languageService = createLanguageService(languageServiceHostProxy); + const languageService = ts.createLanguageService(languageServiceHostProxy); // TypeScript plugins have a `cwd` of `/`, which causes issues with import resolution. process.chdir(directory); @@ -123,10 +117,10 @@ const init: server.PluginModuleFactory = ({ typescript: ts }) => { languageServiceHost.getScriptKind = (fileName) => { if (!info.languageServiceHost.getScriptKind) { - return ScriptKind.Unknown; + return ts.ScriptKind.Unknown; } if (isCSS(fileName)) { - return ScriptKind.TS; + return ts.ScriptKind.TS; } return info.languageServiceHost.getScriptKind(fileName); }; @@ -148,10 +142,10 @@ const init: server.PluginModuleFactory = ({ typescript: ts }) => { const createModuleResolver = (containingFile: string) => - (moduleName: string): ResolvedModuleFull | undefined => { + (moduleName: string): tsModule.ResolvedModuleFull | undefined => { if (isRelativeCSS(moduleName)) { return { - extension: Extension.Dts, + extension: ts.Extension.Dts, isExternalLibraryImport: false, resolvedFileName: path.resolve( path.dirname(containingFile), @@ -203,7 +197,7 @@ const init: server.PluginModuleFactory = ({ typescript: ts }) => { if (cssModulePath) { return { - extension: Extension.Dts, + extension: ts.Extension.Dts, isExternalLibraryImport: false, resolvedFileName: path.resolve(cssModulePath), }; @@ -279,7 +273,9 @@ const init: server.PluginModuleFactory = ({ typescript: ts }) => { return languageService; } - function getExternalFiles(project: server.ConfiguredProject): string[] { + function getExternalFiles( + project: tsModule.server.ConfiguredProject, + ): string[] { return project.getFileNames().filter(_isCSS); } diff --git a/src/options.ts b/src/options.ts index 85a2f1c..de1f8be 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,5 +1,5 @@ import { Options as SassOptions } from 'sass'; -import tsModule from 'typescript/lib/tsserverlibrary'; +import type tsModule from 'typescript/lib/tsserverlibrary'; import { DotenvConfigOptions } from 'dotenv'; import { CSSExports } from 'icss-utils'; import stylus from 'stylus'; From d722951ca79564e3768af04c76abab48ef637bcd Mon Sep 17 00:00:00 2001 From: Brody McKee Date: Wed, 22 Mar 2023 08:41:34 +1100 Subject: [PATCH 4/4] chore: bump version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 247d8e4..772902c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "typescript-plugin-css-modules", - "version": "5.0.0-beta.0", + "version": "5.0.0", "main": "dist/index.js", "author": "Brody McKee ", "license": "MIT",