Skip to content

Commit

Permalink
feat: use jiti for typescript configurations (#649)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akait committed Apr 28, 2023
1 parent 54c195e commit 8b876fa
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 85 deletions.
3 changes: 2 additions & 1 deletion .cspell.json
Expand Up @@ -12,7 +12,8 @@
"klona",
"hspace",
"vspace",
"commitlint"
"commitlint",
"jiti"
],

"ignorePaths": [
Expand Down
8 changes: 7 additions & 1 deletion package-lock.json

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

14 changes: 2 additions & 12 deletions package.json
Expand Up @@ -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"
},
Expand Down
110 changes: 39 additions & 71 deletions src/utils.js
Expand Up @@ -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) => {
Expand Down Expand Up @@ -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,
Expand Down
19 changes: 19 additions & 0 deletions test/config-autoload.test.js
Expand Up @@ -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,
Expand Down
@@ -0,0 +1,3 @@
.import {
color: goldenrod;
}
5 changes: 5 additions & 0 deletions test/fixtures/config-autoload/ts/array-mts/index.css
@@ -0,0 +1,5 @@
@import 'imports/section.css';

.test {
color: cyan;
}
3 changes: 3 additions & 0 deletions test/fixtures/config-autoload/ts/array-mts/index.js
@@ -0,0 +1,3 @@
import style from './index.css'

export default style
37 changes: 37 additions & 0 deletions 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<PostCSSConfig>;

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;

0 comments on commit 8b876fa

Please sign in to comment.