svelte-preprocess
Version:
A Svelte preprocessor wrapper with baked in support for common used preprocessors
198 lines (197 loc) • 8.02 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sveltePreprocess = exports.runTransformer = void 0;
const utils_1 = require("./modules/utils");
const tagInfo_1 = require("./modules/tagInfo");
const language_1 = require("./modules/language");
const prepareContent_1 = require("./modules/prepareContent");
const ALIAS_OPTION_OVERRIDES = {
sass: {
indentedSyntax: true,
},
};
exports.runTransformer = async (name, options, { content, map, filename, attributes }) => {
if (options === false) {
return { code: content };
}
if (typeof options === 'function') {
return options({ content, map, filename, attributes });
}
const { transformer } = await Promise.resolve().then(() => __importStar(require(`./transformers/${name}`)));
return transformer({
content,
filename,
map,
attributes,
options: typeof options === 'boolean' ? null : options,
});
};
function sveltePreprocess({ aliases, markupTagName = 'template', preserve = [], defaults, sourceMap = false, ...rest } = {}) {
markupTagName = markupTagName.toLocaleLowerCase();
const defaultLanguages = Object.freeze({
markup: 'html',
style: 'css',
script: 'javascript',
...defaults,
});
const transformers = rest;
const markupPattern = new RegExp(`<${markupTagName}([\\s\\S]*?)(?:>([\\s\\S]*)<\\/${markupTagName}>|/>)`);
if (aliases === null || aliases === void 0 ? void 0 : aliases.length) {
language_1.addLanguageAlias(aliases);
}
const getTransformerOptions = (name, alias) => {
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 = {};
if (typeof nameOpts === 'object') {
Object.assign(opts, nameOpts);
}
if (name !== alias) {
Object.assign(opts, ALIAS_OPTION_OVERRIDES[alias] || null);
if (typeof aliasOpts === 'object') {
Object.assign(opts, aliasOpts);
}
}
if (sourceMap && name in language_1.SOURCE_MAP_PROP_MAP) {
const [propName, value] = language_1.SOURCE_MAP_PROP_MAP[name];
opts[propName] = value;
}
return opts;
};
const getTransformerTo = (type, targetLanguage) => async (svelteFile) => {
let { content, filename, lang, alias, dependencies, attributes, } = await tagInfo_1.getTagInfo(svelteFile);
if (lang == null || alias == null) {
alias = defaultLanguages[type];
lang = language_1.getLanguageFromAlias(alias);
}
if (preserve.includes(lang) || preserve.includes(alias)) {
return { code: content };
}
const transformerOptions = getTransformerOptions(lang, alias);
content = prepareContent_1.prepareContent({
options: transformerOptions,
content,
});
if (lang === targetLanguage) {
return { code: content, dependencies };
}
const transformed = await exports.runTransformer(lang, transformerOptions, {
content,
filename,
attributes,
});
return {
...transformed,
dependencies: utils_1.concat(dependencies, transformed.dependencies),
};
};
const scriptTransformer = getTransformerTo('script', 'javascript');
const cssTransformer = getTransformerTo('style', 'css');
const markupTransformer = getTransformerTo('markup', 'html');
const markup = async ({ content, filename }) => {
if (transformers.replace) {
const transformed = await exports.runTransformer('replace', transformers.replace, { content, filename });
content = transformed.code;
}
const templateMatch = content.match(markupPattern);
/** If no <template> was found, just return the original markup */
if (!templateMatch) {
return markupTransformer({ content, attributes: {}, filename });
}
const [fullMatch, attributesStr, templateCode] = templateMatch;
/** Transform an attribute string into a key-value object */
const attributes = attributesStr
.split(/\s+/)
.filter(Boolean)
.reduce((acc, attr) => {
const [name, value] = attr.split('=');
// istanbul ignore next
acc[name] = value ? value.replace(/['"]/g, '') : true;
return acc;
}, {});
/** Transform the found template code */
let { code, map, dependencies } = await markupTransformer({
content: templateCode,
attributes,
filename,
});
code =
content.slice(0, templateMatch.index) +
code +
content.slice(templateMatch.index + fullMatch.length);
return { code, map, dependencies };
};
const script = async ({ content, attributes, filename, }) => {
const transformResult = await scriptTransformer({
content,
attributes,
filename,
});
let { code, map, dependencies, diagnostics } = transformResult;
if (transformers.babel) {
const transformed = await exports.runTransformer('babel', getTransformerOptions('babel'), {
content: code,
map,
filename,
attributes,
});
code = transformed.code;
map = transformed.map;
dependencies = utils_1.concat(dependencies, transformed.dependencies);
diagnostics = utils_1.concat(diagnostics, transformed.diagnostics);
}
return { code, map, dependencies, diagnostics };
};
const style = async ({ content, attributes, filename, }) => {
const transformResult = await cssTransformer({
content,
attributes,
filename,
});
let { code, map, dependencies } = transformResult;
// istanbul ignore else
if (await utils_1.hasDepInstalled('postcss')) {
if (transformers.postcss) {
const transformed = await exports.runTransformer('postcss', getTransformerOptions('postcss'), { content: code, map, filename, attributes });
code = transformed.code;
map = transformed.map;
dependencies = utils_1.concat(dependencies, transformed.dependencies);
}
const transformed = await exports.runTransformer('globalStyle', getTransformerOptions('globalStyle'), { content: code, map, filename, attributes });
code = transformed.code;
map = transformed.map;
}
return { code, map, dependencies };
};
return {
defaultLanguages,
markup,
script,
style,
};
}
exports.sveltePreprocess = sveltePreprocess;