Skip to content

Commit 8b876fa

Browse files
feat: use jiti for typescript configurations (#649)
1 parent 54c195e commit 8b876fa

File tree

9 files changed

+117
-85
lines changed

9 files changed

+117
-85
lines changed

.cspell.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@
1212
"klona",
1313
"hspace",
1414
"vspace",
15-
"commitlint"
15+
"commitlint",
16+
"jiti"
1617
],
1718

1819
"ignorePaths": [

package-lock.json

+7-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-12
Original file line numberDiff line numberDiff line change
@@ -39,21 +39,11 @@
3939
],
4040
"peerDependencies": {
4141
"postcss": "^7.0.0 || ^8.0.1",
42-
"webpack": "^5.0.0",
43-
"ts-node": ">=10",
44-
"typescript": ">=4"
45-
},
46-
"peerDependenciesMeta": {
47-
"ts-node": {
48-
"optional": true
49-
},
50-
"typescript": {
51-
"optional": true
52-
}
42+
"webpack": "^5.0.0"
5343
},
5444
"dependencies": {
5545
"cosmiconfig": "^8.1.3",
56-
"cosmiconfig-typescript-loader": "^4.3.0",
46+
"jiti": "^1.18.2",
5747
"klona": "^2.0.6",
5848
"semver": "^7.3.8"
5949
},

src/utils.js

+39-71
Original file line numberDiff line numberDiff line change
@@ -50,68 +50,37 @@ async function loadConfig(loaderContext, config, postcssOptions) {
5050
throw new Error(`No PostCSS config found in: ${searchPath}`);
5151
}
5252

53-
let isTsNodeInstalled = false;
54-
55-
try {
56-
// eslint-disable-next-line import/no-extraneous-dependencies, global-require
57-
require("ts-node");
58-
59-
isTsNodeInstalled = true;
60-
} catch (_) {
61-
// Nothing
62-
}
63-
6453
const moduleName = "postcss";
65-
const searchPlaces = isTsNodeInstalled
66-
? [
67-
"package.json",
68-
`.${moduleName}rc`,
69-
`.${moduleName}rc.json`,
70-
`.${moduleName}rc.yaml`,
71-
`.${moduleName}rc.yml`,
72-
`.${moduleName}rc.js`,
73-
`.${moduleName}rc.mjs`,
74-
`.${moduleName}rc.cjs`,
75-
`.${moduleName}rc.ts`,
76-
`.${moduleName}rc.mts`,
77-
`.${moduleName}rc.cts`,
78-
`.config/${moduleName}rc`,
79-
`.config/${moduleName}rc.json`,
80-
`.config/${moduleName}rc.yaml`,
81-
`.config/${moduleName}rc.yml`,
82-
`.config/${moduleName}rc.js`,
83-
`.config/${moduleName}rc.mjs`,
84-
`.config/${moduleName}rc.cjs`,
85-
`.config/${moduleName}rc.ts`,
86-
`.config/${moduleName}rc.mts`,
87-
`.config/${moduleName}rc.cts`,
88-
`${moduleName}.config.js`,
89-
`${moduleName}.config.mjs`,
90-
`${moduleName}.config.cjs`,
91-
`${moduleName}.config.ts`,
92-
`${moduleName}.config.mts`,
93-
`${moduleName}.config.cts`,
94-
]
95-
: [
96-
"package.json",
97-
`.${moduleName}rc`,
98-
`.${moduleName}rc.json`,
99-
`.${moduleName}rc.yaml`,
100-
`.${moduleName}rc.yml`,
101-
`.${moduleName}rc.js`,
102-
`.${moduleName}rc.mjs`,
103-
`.${moduleName}rc.cjs`,
104-
`.config/${moduleName}rc`,
105-
`.config/${moduleName}rc.json`,
106-
`.config/${moduleName}rc.yaml`,
107-
`.config/${moduleName}rc.yml`,
108-
`.config/${moduleName}rc.js`,
109-
`.config/${moduleName}rc.mjs`,
110-
`.config/${moduleName}rc.cjs`,
111-
`${moduleName}.config.js`,
112-
`${moduleName}.config.mjs`,
113-
`${moduleName}.config.cjs`,
114-
];
54+
const searchPlaces = [
55+
// Prefer popular format
56+
"package.json",
57+
`${moduleName}.config.js`,
58+
`${moduleName}.config.mjs`,
59+
`${moduleName}.config.cjs`,
60+
`${moduleName}.config.ts`,
61+
`${moduleName}.config.mts`,
62+
`${moduleName}.config.cts`,
63+
`.${moduleName}rc`,
64+
`.${moduleName}rc.json`,
65+
`.${moduleName}rc.js`,
66+
`.${moduleName}rc.mjs`,
67+
`.${moduleName}rc.cjs`,
68+
`.${moduleName}rc.ts`,
69+
`.${moduleName}rc.mts`,
70+
`.${moduleName}rc.cts`,
71+
`.${moduleName}rc.yaml`,
72+
`.${moduleName}rc.yml`,
73+
`.config/${moduleName}rc`,
74+
`.config/${moduleName}rc.json`,
75+
`.config/${moduleName}rc.yaml`,
76+
`.config/${moduleName}rc.yml`,
77+
`.config/${moduleName}rc.js`,
78+
`.config/${moduleName}rc.mjs`,
79+
`.config/${moduleName}rc.cjs`,
80+
`.config/${moduleName}rc.ts`,
81+
`.config/${moduleName}rc.mts`,
82+
`.config/${moduleName}rc.cts`,
83+
];
11584

11685
const loaders = {
11786
".js": async (...args) => {
@@ -167,19 +136,18 @@ async function loadConfig(loaderContext, config, postcssOptions) {
167136
},
168137
};
169138

170-
if (isTsNodeInstalled) {
171-
if (!tsLoader) {
172-
// eslint-disable-next-line global-require
173-
const { TypeScriptLoader } = require("cosmiconfig-typescript-loader");
174-
175-
tsLoader = TypeScriptLoader();
176-
}
139+
if (!tsLoader) {
140+
const opts = { interopDefault: true };
141+
// eslint-disable-next-line global-require, import/no-extraneous-dependencies
142+
const jiti = require("jiti")(__filename, opts);
177143

178-
loaders[".cts"] = tsLoader;
179-
loaders[".mts"] = tsLoader;
180-
loaders[".ts"] = tsLoader;
144+
tsLoader = (filepath) => jiti(filepath);
181145
}
182146

147+
loaders[".cts"] = tsLoader;
148+
loaders[".mts"] = tsLoader;
149+
loaders[".ts"] = tsLoader;
150+
183151
const explorer = cosmiconfig(moduleName, {
184152
searchPlaces,
185153
loaders,

test/config-autoload.test.js

+19
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,25 @@ describe("autoload config", () => {
135135
);
136136
});
137137

138+
it('should load "postcss.config.mts" with "Array" syntax of plugins', async () => {
139+
const loadedConfig = await loadConfig(
140+
loaderContext,
141+
path.resolve(testDirectory, "ts/array-mts")
142+
);
143+
144+
expect(loadedConfig.config.map).toEqual(false);
145+
expect(loadedConfig.config.from).toEqual(
146+
"./test/fixtures/config-autoload/ts/object/index.css"
147+
);
148+
expect(loadedConfig.config.to).toEqual(
149+
"./test/fixtures/config-autoload/ts/object/expect/index.css"
150+
);
151+
expect(Object.keys(loadedConfig.config.plugins).length).toEqual(4);
152+
expect(loadedConfig.filepath).toEqual(
153+
path.resolve(testDirectory, "ts/array-mts", "postcss.config.mts")
154+
);
155+
});
156+
138157
it('should load empty ".postcssrc"', async () => {
139158
const loadedConfig = await loadConfig(
140159
loaderContext,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.import {
2+
color: goldenrod;
3+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@import 'imports/section.css';
2+
3+
.test {
4+
color: cyan;
5+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import style from './index.css'
2+
3+
export default style
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type { Config as PostCSSConfig } from 'postcss-load-config';
2+
import type { LoaderContext } from 'webpack';
3+
4+
type PostCSSLoaderContext = LoaderContext<PostCSSConfig>;
5+
6+
interface PostCSSLoaderAPI {
7+
mode: PostCSSLoaderContext['mode'];
8+
file: PostCSSLoaderContext['resourcePath'];
9+
webpackLoaderContext: PostCSSLoaderContext;
10+
env: PostCSSLoaderContext['mode'];
11+
options: PostCSSConfig;
12+
}
13+
14+
type PostCSSLoaderOptions = PostCSSConfig | ((api: PostCSSLoaderAPI) => PostCSSConfig);
15+
16+
const config: PostCSSLoaderOptions = function (api) {
17+
return {
18+
parser: 'sugarss',
19+
syntax: 'sugarss',
20+
map: api.mode === 'development' ? 'inline' : false,
21+
from: './test/fixtures/config-autoload/ts/object/index.css',
22+
to: './test/fixtures/config-autoload/ts/object/expect/index.css',
23+
plugins: [
24+
'postcss-import',
25+
[
26+
'postcss-nested',
27+
{
28+
// Options
29+
}
30+
],
31+
require('postcss-nested'),
32+
require('postcss-nested')({ /* Options */ }),
33+
]
34+
}
35+
};
36+
37+
export default config;

0 commit comments

Comments
 (0)