Skip to content

Commit 2a188bc

Browse files
committed
fix: 🐛 language custom transformer overriding postcss
Closes: #309
1 parent 607bcab commit 2a188bc

File tree

3 files changed

+100
-46
lines changed

3 files changed

+100
-46
lines changed

Diff for: src/autoProcess.ts

+43-22
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
SOURCE_MAP_PROP_MAP,
1616
getLanguage,
1717
getLanguageDefaults,
18+
isAliasOf,
1819
} from './modules/language';
1920
import { prepareContent } from './modules/prepareContent';
2021
import { transformMarkup } from './modules/markup';
@@ -104,16 +105,8 @@ export function sveltePreprocess(
104105
addLanguageAlias(aliases);
105106
}
106107

107-
const getTransformerOptions = (
108-
name: string,
109-
alias?: string,
110-
): TransformerOptions<unknown> => {
108+
function resolveLanguageArgs(name: string, alias?: string) {
111109
const { [name]: nameOpts, [alias]: aliasOpts } = transformers;
112-
113-
if (typeof aliasOpts === 'function') return aliasOpts;
114-
if (typeof nameOpts === 'function') return nameOpts;
115-
if (aliasOpts === false || nameOpts === false) return false;
116-
117110
const opts: Record<string, any> = {};
118111

119112
if (typeof nameOpts === 'object') {
@@ -127,11 +120,30 @@ export function sveltePreprocess(
127120
}
128121

129122
if (sourceMap && name in SOURCE_MAP_PROP_MAP) {
130-
setProp(opts, ...SOURCE_MAP_PROP_MAP[name]);
123+
const [path, value] = SOURCE_MAP_PROP_MAP[name];
124+
125+
setProp(opts, path, value);
131126
}
132127

133128
return opts;
134-
};
129+
}
130+
131+
function getTransformerOptions(
132+
lang: string,
133+
alias?: string,
134+
{ ignoreAliasOverride }: { ignoreAliasOverride?: boolean } = {},
135+
): TransformerOptions<unknown> {
136+
const { [lang]: langOpts, [alias]: aliasOpts } = transformers;
137+
138+
if (!ignoreAliasOverride && typeof aliasOpts === 'function') {
139+
return aliasOpts;
140+
}
141+
142+
if (typeof langOpts === 'function') return langOpts;
143+
if (aliasOpts === false || langOpts === false) return false;
144+
145+
return resolveLanguageArgs(lang, alias);
146+
}
135147

136148
const getTransformerTo = (
137149
type: 'markup' | 'script' | 'style',
@@ -163,6 +175,13 @@ export function sveltePreprocess(
163175
});
164176

165177
if (lang === targetLanguage) {
178+
// has override method for alias
179+
// example: sugarss override should work apart from postcss
180+
if (typeof transformerOptions === 'function' && alias !== lang) {
181+
return transformerOptions({ content, filename, attributes });
182+
}
183+
184+
// otherwise, we're done here
166185
return { code: content, dependencies };
167186
}
168187

@@ -216,12 +235,7 @@ export function sveltePreprocess(
216235
const transformed = await transform(
217236
'babel',
218237
getTransformerOptions('babel'),
219-
{
220-
content: code,
221-
map,
222-
filename,
223-
attributes,
224-
},
238+
{ content: code, map, filename, attributes },
225239
);
226240

227241
code = transformed.code;
@@ -249,14 +263,21 @@ export function sveltePreprocess(
249263
// istanbul ignore else
250264
if (await hasDepInstalled('postcss')) {
251265
if (transformers.postcss) {
252-
const { alias } = getLanguage(attributes);
253-
254-
const transformed = await transform(
266+
const { alias, lang } = getLanguage(attributes);
267+
const postcssOptions = getTransformerOptions(
255268
'postcss',
256-
getTransformerOptions('postcss', alias),
257-
{ content: code, map, filename, attributes },
269+
isAliasOf(alias, lang) ? alias : null,
270+
// todo: this seems wrong and ugly
271+
{ ignoreAliasOverride: true },
258272
);
259273

274+
const transformed = await transform('postcss', postcssOptions, {
275+
content: code,
276+
map,
277+
filename,
278+
attributes,
279+
});
280+
260281
code = transformed.code;
261282
map = transformed.map;
262283
dependencies = concat(dependencies, transformed.dependencies);

Diff for: src/modules/language.ts

+29-24
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,16 @@ const LANGUAGE_DEFAULTS: Record<string, any> = {
2525
}),
2626
};
2727

28-
export function getLanguageDefaults(lang: string): null | Record<string, any> {
29-
const defaults = LANGUAGE_DEFAULTS[lang];
30-
31-
if (!defaults) return null;
32-
if (typeof defaults === 'function') {
33-
return defaults();
34-
}
35-
36-
return defaults;
37-
}
28+
export const ALIAS_MAP = new Map([
29+
['pcss', 'css'],
30+
['postcss', 'css'],
31+
['sugarss', 'css'],
32+
['sass', 'scss'],
33+
['styl', 'stylus'],
34+
['js', 'javascript'],
35+
['coffee', 'coffeescript'],
36+
['ts', 'typescript'],
37+
]);
3838

3939
export const SOURCE_MAP_PROP_MAP: Record<string, [string[], any]> = {
4040
babel: [['sourceMaps'], true],
@@ -47,23 +47,28 @@ export const SOURCE_MAP_PROP_MAP: Record<string, [string[], any]> = {
4747
globalStyle: [['sourceMap'], true],
4848
};
4949

50-
export const ALIAS_MAP = new Map([
51-
['pcss', 'css'],
52-
['postcss', 'css'],
53-
['sugarss', 'css'],
54-
['sass', 'scss'],
55-
['styl', 'stylus'],
56-
['js', 'javascript'],
57-
['coffee', 'coffeescript'],
58-
['ts', 'typescript'],
59-
]);
50+
export function getLanguageDefaults(lang: string): null | Record<string, any> {
51+
const defaults = LANGUAGE_DEFAULTS[lang];
52+
53+
if (!defaults) return null;
54+
if (typeof defaults === 'function') {
55+
return defaults();
56+
}
6057

61-
export const addLanguageAlias = (entries: Array<[string, string]>) =>
62-
entries.forEach((entry) => ALIAS_MAP.set(...entry));
58+
return defaults;
59+
}
6360

64-
export const getLanguageFromAlias = (alias: string | null) => {
61+
export function addLanguageAlias(entries: Array<[string, string]>) {
62+
return entries.forEach((entry) => ALIAS_MAP.set(...entry));
63+
}
64+
65+
export function getLanguageFromAlias(alias: string | null) {
6566
return ALIAS_MAP.get(alias) || alias;
66-
};
67+
}
68+
69+
export function isAliasOf(alias: string, lang: string) {
70+
return lang !== alias && getLanguageFromAlias(alias) === lang;
71+
}
6772

6873
export const getLanguage = (attributes: PreprocessorArgs['attributes']) => {
6974
let alias = null;

Diff for: test/transformers/postcss.test.ts

+28
Original file line numberDiff line numberDiff line change
@@ -149,3 +149,31 @@ test('automatically removes indentation for lang=sugarss', async () => {
149149
}</style>"
150150
`);
151151
});
152+
153+
test('should not override postcss with custom style language', async () => {
154+
const custom = jest.fn(({ content }) => ({ code: content }));
155+
const postcss = jest.fn(({ content }) => ({ code: content }));
156+
const opts = sveltePreprocess({ custom, postcss });
157+
158+
await preprocess(
159+
`<div></div><style lang="custom">div{color:red}</style>`,
160+
opts,
161+
);
162+
163+
expect(custom).toHaveBeenCalledTimes(1);
164+
expect(postcss).toHaveBeenCalledTimes(1);
165+
});
166+
167+
test('should execute postcss alias override before postcss', async () => {
168+
const sugarss = jest.fn(({ content }) => ({ code: content }));
169+
const postcss = jest.fn(({ content }) => ({ code: content }));
170+
const opts = sveltePreprocess({ sugarss, postcss });
171+
172+
await preprocess(
173+
`<div></div><style lang="sugarss">div{color:red}</style>`,
174+
opts,
175+
);
176+
177+
expect(sugarss).toHaveBeenCalledTimes(1);
178+
expect(postcss).toHaveBeenCalledTimes(1);
179+
});

0 commit comments

Comments
 (0)