Skip to content

Commit

Permalink
fix: 🐛 language custom transformer overriding postcss
Browse files Browse the repository at this point in the history
Closes: #309
  • Loading branch information
kaisermann committed Feb 10, 2021
1 parent 607bcab commit b59b495
Show file tree
Hide file tree
Showing 3 changed files with 103 additions and 47 deletions.
69 changes: 46 additions & 23 deletions src/autoProcess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
SOURCE_MAP_PROP_MAP,
getLanguage,
getLanguageDefaults,
isAliasOf,
} from './modules/language';
import { prepareContent } from './modules/prepareContent';
import { transformMarkup } from './modules/markup';
Expand Down Expand Up @@ -104,16 +105,8 @@ export function sveltePreprocess(
addLanguageAlias(aliases);
}

const getTransformerOptions = (
name: string,
alias?: string,
): TransformerOptions<unknown> => {
function resolveLanguageArgs(name: string, alias?: string) {
const { [name]: nameOpts, [alias]: aliasOpts } = transformers;

if (typeof aliasOpts === 'function') return aliasOpts;
if (typeof nameOpts === 'function') return nameOpts;
if (aliasOpts === false || nameOpts === false) return false;

const opts: Record<string, any> = {};

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

if (sourceMap && name in SOURCE_MAP_PROP_MAP) {
setProp(opts, ...SOURCE_MAP_PROP_MAP[name]);
const [path, value] = SOURCE_MAP_PROP_MAP[name];

setProp(opts, path, value);
}

return opts;
};
}

function getTransformerOptions(
lang: string,
alias?: string,
{ ignoreAliasOverride }: { ignoreAliasOverride?: boolean } = {},
): TransformerOptions<unknown> {
const { [lang]: langOpts, [alias]: aliasOpts } = transformers;

if (!ignoreAliasOverride && typeof aliasOpts === 'function') {
return aliasOpts;
}

if (typeof langOpts === 'function') return langOpts;
if (aliasOpts === false || langOpts === false) return false;

return resolveLanguageArgs(lang, alias);
}

const getTransformerTo = (
type: 'markup' | 'script' | 'style',
Expand Down Expand Up @@ -163,6 +175,13 @@ export function sveltePreprocess(
});

if (lang === targetLanguage) {
// has override method for alias
// example: sugarss override should work apart from postcss
if (typeof transformerOptions === 'function' && alias !== lang) {
return transformerOptions({ content, filename, attributes });
}

// otherwise, we're done here
return { code: content, dependencies };
}

Expand Down Expand Up @@ -216,12 +235,7 @@ export function sveltePreprocess(
const transformed = await transform(
'babel',
getTransformerOptions('babel'),
{
content: code,
map,
filename,
attributes,
},
{ content: code, map, filename, attributes },
);

code = transformed.code;
Expand All @@ -246,17 +260,26 @@ export function sveltePreprocess(

let { code, map, dependencies } = transformResult;

const hasPostcss = await hasDepInstalled('postcss');

// istanbul ignore else
if (await hasDepInstalled('postcss')) {
if (hasPostcss) {
if (transformers.postcss) {
const { alias } = getLanguage(attributes);

const transformed = await transform(
const { alias, lang } = getLanguage(attributes);
const postcssOptions = getTransformerOptions(
'postcss',
getTransformerOptions('postcss', alias),
{ content: code, map, filename, attributes },
isAliasOf(alias, lang) ? alias : null,
// todo: this seems wrong and ugly
{ ignoreAliasOverride: true },
);

const transformed = await transform('postcss', postcssOptions, {
content: code,
map,
filename,
attributes,
});

code = transformed.code;
map = transformed.map;
dependencies = concat(dependencies, transformed.dependencies);
Expand Down
53 changes: 29 additions & 24 deletions src/modules/language.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,16 +25,16 @@ const LANGUAGE_DEFAULTS: Record<string, any> = {
}),
};

export function getLanguageDefaults(lang: string): null | Record<string, any> {
const defaults = LANGUAGE_DEFAULTS[lang];

if (!defaults) return null;
if (typeof defaults === 'function') {
return defaults();
}

return defaults;
}
export const ALIAS_MAP = new Map([
['pcss', 'css'],
['postcss', 'css'],
['sugarss', 'css'],
['sass', 'scss'],
['styl', 'stylus'],
['js', 'javascript'],
['coffee', 'coffeescript'],
['ts', 'typescript'],
]);

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

export const ALIAS_MAP = new Map([
['pcss', 'css'],
['postcss', 'css'],
['sugarss', 'css'],
['sass', 'scss'],
['styl', 'stylus'],
['js', 'javascript'],
['coffee', 'coffeescript'],
['ts', 'typescript'],
]);
export function getLanguageDefaults(lang: string): null | Record<string, any> {
const defaults = LANGUAGE_DEFAULTS[lang];

if (!defaults) return null;
if (typeof defaults === 'function') {
return defaults();
}

export const addLanguageAlias = (entries: Array<[string, string]>) =>
entries.forEach((entry) => ALIAS_MAP.set(...entry));
return defaults;
}

export const getLanguageFromAlias = (alias: string | null) => {
export function addLanguageAlias(entries: Array<[string, string]>) {
return entries.forEach((entry) => ALIAS_MAP.set(...entry));
}

export function getLanguageFromAlias(alias: string | null) {
return ALIAS_MAP.get(alias) || alias;
};
}

export function isAliasOf(alias: string, lang: string) {
return lang !== alias && getLanguageFromAlias(alias) === lang;
}

export const getLanguage = (attributes: PreprocessorArgs['attributes']) => {
let alias = null;
Expand Down
28 changes: 28 additions & 0 deletions test/transformers/postcss.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,31 @@ test('automatically removes indentation for lang=sugarss', async () => {
}</style>"
`);
});

test('should not override postcss with custom style language', async () => {
const custom = jest.fn(({ content }) => ({ code: content }));
const postcss = jest.fn(({ content }) => ({ code: content }));
const opts = sveltePreprocess({ custom, postcss });

await preprocess(
`<div></div><style lang="custom">div{color:red}</style>`,
opts,
);

expect(custom).toHaveBeenCalledTimes(1);
expect(postcss).toHaveBeenCalledTimes(1);
});

test('should execute postcss alias override before postcss', async () => {
const sugarss = jest.fn(({ content }) => ({ code: content }));
const postcss = jest.fn(({ content }) => ({ code: content }));
const opts = sveltePreprocess({ sugarss, postcss });

await preprocess(
`<div></div><style lang="sugarss">div{color:red}</style>`,
opts,
);

expect(sugarss).toHaveBeenCalledTimes(1);
expect(postcss).toHaveBeenCalledTimes(1);
});

0 comments on commit b59b495

Please sign in to comment.