From 8b876fa49c71c434b9c5598b179a4f88cf8123e4 Mon Sep 17 00:00:00 2001 From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com> Date: Sat, 29 Apr 2023 00:01:39 +0300 Subject: [PATCH] feat: use `jiti` for typescript configurations (#649) --- .cspell.json | 3 +- package-lock.json | 8 +- package.json | 14 +-- src/utils.js | 110 +++++++----------- test/config-autoload.test.js | 19 +++ .../ts/array-mts/imports/section.css | 3 + .../config-autoload/ts/array-mts/index.css | 5 + .../config-autoload/ts/array-mts/index.js | 3 + .../ts/array-mts/postcss.config.mts | 37 ++++++ 9 files changed, 117 insertions(+), 85 deletions(-) create mode 100644 test/fixtures/config-autoload/ts/array-mts/imports/section.css create mode 100644 test/fixtures/config-autoload/ts/array-mts/index.css create mode 100644 test/fixtures/config-autoload/ts/array-mts/index.js create mode 100644 test/fixtures/config-autoload/ts/array-mts/postcss.config.mts diff --git a/.cspell.json b/.cspell.json index 300fdadf..feea67a3 100644 --- a/.cspell.json +++ b/.cspell.json @@ -12,7 +12,8 @@ "klona", "hspace", "vspace", - "commitlint" + "commitlint", + "jiti" ], "ignorePaths": [ diff --git a/package-lock.json b/package-lock.json index d1f0ea0a..05b49c80 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4314,7 +4314,8 @@ "cosmiconfig-typescript-loader": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.3.0.tgz", - "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==" + "integrity": "sha512-NTxV1MFfZDLPiBMjxbHRwSh5LaLcPMwNdCutmnHJCKoVnlvldPWlllonKwrsRJ5pYZBIBGRWWU2tfvzxgeSW5Q==", + "dev": true }, "create-require": { "version": "1.1.1", @@ -8079,6 +8080,11 @@ } } }, + "jiti": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.18.2.tgz", + "integrity": "sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==" + }, "js-base64": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.6.4.tgz", diff --git a/package.json b/package.json index 49f1d833..971360a5 100644 --- a/package.json +++ b/package.json @@ -39,21 +39,11 @@ ], "peerDependencies": { "postcss": "^7.0.0 || ^8.0.1", - "webpack": "^5.0.0", - "ts-node": ">=10", - "typescript": ">=4" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - }, - "typescript": { - "optional": true - } + "webpack": "^5.0.0" }, "dependencies": { "cosmiconfig": "^8.1.3", - "cosmiconfig-typescript-loader": "^4.3.0", + "jiti": "^1.18.2", "klona": "^2.0.6", "semver": "^7.3.8" }, diff --git a/src/utils.js b/src/utils.js index 20d00ef2..d93e50c2 100644 --- a/src/utils.js +++ b/src/utils.js @@ -50,68 +50,37 @@ async function loadConfig(loaderContext, config, postcssOptions) { throw new Error(`No PostCSS config found in: ${searchPath}`); } - let isTsNodeInstalled = false; - - try { - // eslint-disable-next-line import/no-extraneous-dependencies, global-require - require("ts-node"); - - isTsNodeInstalled = true; - } catch (_) { - // Nothing - } - const moduleName = "postcss"; - const searchPlaces = isTsNodeInstalled - ? [ - "package.json", - `.${moduleName}rc`, - `.${moduleName}rc.json`, - `.${moduleName}rc.yaml`, - `.${moduleName}rc.yml`, - `.${moduleName}rc.js`, - `.${moduleName}rc.mjs`, - `.${moduleName}rc.cjs`, - `.${moduleName}rc.ts`, - `.${moduleName}rc.mts`, - `.${moduleName}rc.cts`, - `.config/${moduleName}rc`, - `.config/${moduleName}rc.json`, - `.config/${moduleName}rc.yaml`, - `.config/${moduleName}rc.yml`, - `.config/${moduleName}rc.js`, - `.config/${moduleName}rc.mjs`, - `.config/${moduleName}rc.cjs`, - `.config/${moduleName}rc.ts`, - `.config/${moduleName}rc.mts`, - `.config/${moduleName}rc.cts`, - `${moduleName}.config.js`, - `${moduleName}.config.mjs`, - `${moduleName}.config.cjs`, - `${moduleName}.config.ts`, - `${moduleName}.config.mts`, - `${moduleName}.config.cts`, - ] - : [ - "package.json", - `.${moduleName}rc`, - `.${moduleName}rc.json`, - `.${moduleName}rc.yaml`, - `.${moduleName}rc.yml`, - `.${moduleName}rc.js`, - `.${moduleName}rc.mjs`, - `.${moduleName}rc.cjs`, - `.config/${moduleName}rc`, - `.config/${moduleName}rc.json`, - `.config/${moduleName}rc.yaml`, - `.config/${moduleName}rc.yml`, - `.config/${moduleName}rc.js`, - `.config/${moduleName}rc.mjs`, - `.config/${moduleName}rc.cjs`, - `${moduleName}.config.js`, - `${moduleName}.config.mjs`, - `${moduleName}.config.cjs`, - ]; + const searchPlaces = [ + // Prefer popular format + "package.json", + `${moduleName}.config.js`, + `${moduleName}.config.mjs`, + `${moduleName}.config.cjs`, + `${moduleName}.config.ts`, + `${moduleName}.config.mts`, + `${moduleName}.config.cts`, + `.${moduleName}rc`, + `.${moduleName}rc.json`, + `.${moduleName}rc.js`, + `.${moduleName}rc.mjs`, + `.${moduleName}rc.cjs`, + `.${moduleName}rc.ts`, + `.${moduleName}rc.mts`, + `.${moduleName}rc.cts`, + `.${moduleName}rc.yaml`, + `.${moduleName}rc.yml`, + `.config/${moduleName}rc`, + `.config/${moduleName}rc.json`, + `.config/${moduleName}rc.yaml`, + `.config/${moduleName}rc.yml`, + `.config/${moduleName}rc.js`, + `.config/${moduleName}rc.mjs`, + `.config/${moduleName}rc.cjs`, + `.config/${moduleName}rc.ts`, + `.config/${moduleName}rc.mts`, + `.config/${moduleName}rc.cts`, + ]; const loaders = { ".js": async (...args) => { @@ -167,19 +136,18 @@ async function loadConfig(loaderContext, config, postcssOptions) { }, }; - if (isTsNodeInstalled) { - if (!tsLoader) { - // eslint-disable-next-line global-require - const { TypeScriptLoader } = require("cosmiconfig-typescript-loader"); - - tsLoader = TypeScriptLoader(); - } + if (!tsLoader) { + const opts = { interopDefault: true }; + // eslint-disable-next-line global-require, import/no-extraneous-dependencies + const jiti = require("jiti")(__filename, opts); - loaders[".cts"] = tsLoader; - loaders[".mts"] = tsLoader; - loaders[".ts"] = tsLoader; + tsLoader = (filepath) => jiti(filepath); } + loaders[".cts"] = tsLoader; + loaders[".mts"] = tsLoader; + loaders[".ts"] = tsLoader; + const explorer = cosmiconfig(moduleName, { searchPlaces, loaders, diff --git a/test/config-autoload.test.js b/test/config-autoload.test.js index 4b5ab729..f91e90be 100644 --- a/test/config-autoload.test.js +++ b/test/config-autoload.test.js @@ -135,6 +135,25 @@ describe("autoload config", () => { ); }); + it('should load "postcss.config.mts" with "Array" syntax of plugins', async () => { + const loadedConfig = await loadConfig( + loaderContext, + path.resolve(testDirectory, "ts/array-mts") + ); + + expect(loadedConfig.config.map).toEqual(false); + expect(loadedConfig.config.from).toEqual( + "./test/fixtures/config-autoload/ts/object/index.css" + ); + expect(loadedConfig.config.to).toEqual( + "./test/fixtures/config-autoload/ts/object/expect/index.css" + ); + expect(Object.keys(loadedConfig.config.plugins).length).toEqual(4); + expect(loadedConfig.filepath).toEqual( + path.resolve(testDirectory, "ts/array-mts", "postcss.config.mts") + ); + }); + it('should load empty ".postcssrc"', async () => { const loadedConfig = await loadConfig( loaderContext, diff --git a/test/fixtures/config-autoload/ts/array-mts/imports/section.css b/test/fixtures/config-autoload/ts/array-mts/imports/section.css new file mode 100644 index 00000000..4568aa99 --- /dev/null +++ b/test/fixtures/config-autoload/ts/array-mts/imports/section.css @@ -0,0 +1,3 @@ +.import { + color: goldenrod; +} diff --git a/test/fixtures/config-autoload/ts/array-mts/index.css b/test/fixtures/config-autoload/ts/array-mts/index.css new file mode 100644 index 00000000..3b228825 --- /dev/null +++ b/test/fixtures/config-autoload/ts/array-mts/index.css @@ -0,0 +1,5 @@ +@import 'imports/section.css'; + +.test { + color: cyan; +} diff --git a/test/fixtures/config-autoload/ts/array-mts/index.js b/test/fixtures/config-autoload/ts/array-mts/index.js new file mode 100644 index 00000000..07bf0b31 --- /dev/null +++ b/test/fixtures/config-autoload/ts/array-mts/index.js @@ -0,0 +1,3 @@ +import style from './index.css' + +export default style diff --git a/test/fixtures/config-autoload/ts/array-mts/postcss.config.mts b/test/fixtures/config-autoload/ts/array-mts/postcss.config.mts new file mode 100644 index 00000000..f556ec98 --- /dev/null +++ b/test/fixtures/config-autoload/ts/array-mts/postcss.config.mts @@ -0,0 +1,37 @@ +import type { Config as PostCSSConfig } from 'postcss-load-config'; +import type { LoaderContext } from 'webpack'; + +type PostCSSLoaderContext = LoaderContext; + +interface PostCSSLoaderAPI { + mode: PostCSSLoaderContext['mode']; + file: PostCSSLoaderContext['resourcePath']; + webpackLoaderContext: PostCSSLoaderContext; + env: PostCSSLoaderContext['mode']; + options: PostCSSConfig; +} + +type PostCSSLoaderOptions = PostCSSConfig | ((api: PostCSSLoaderAPI) => PostCSSConfig); + +const config: PostCSSLoaderOptions = function (api) { + return { + parser: 'sugarss', + syntax: 'sugarss', + map: api.mode === 'development' ? 'inline' : false, + from: './test/fixtures/config-autoload/ts/object/index.css', + to: './test/fixtures/config-autoload/ts/object/expect/index.css', + plugins: [ + 'postcss-import', + [ + 'postcss-nested', + { + // Options + } + ], + require('postcss-nested'), + require('postcss-nested')({ /* Options */ }), + ] + } +}; + +export default config;