@lusito/require-libs
Version:
Some libraries to setup require hooks
98 lines (97 loc) • 4.13 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createScssCompiler = createScssCompiler;
const sass_1 = __importDefault(require("sass"));
const path_1 = require("path");
const fs_1 = require("fs");
const transformTokens_1 = require("./transformTokens");
const scopedNameGenerator_1 = require("./scopedNameGenerator");
const addScopes_1 = require("./addScopes");
const extractGlobals_1 = require("./extractGlobals");
const identity = (value) => value;
function getNodeModules() {
const result = [];
let path = process.cwd();
for (;;) {
const abs = (0, path_1.resolve)(path, "node_modules");
if ((0, fs_1.existsSync)(abs) && (0, fs_1.statSync)(abs).isDirectory()) {
result.push(abs);
}
const newPath = (0, path_1.dirname)(path);
if (newPath === path) {
break;
}
path = newPath;
}
return result;
}
function createScssCompiler({ generateScopedNames = true, preprocessCss = identity, processCss = identity, mapFileUrl, style, transformToken = { transform: transformTokens_1.camelCaseTokenTransformer }, }) {
const nodeModulesPaths = getNodeModules();
function getNodeModulesFile(file) {
for (const path of nodeModulesPaths) {
const abs = (0, path_1.resolve)(path, file);
if ((0, fs_1.existsSync)(abs)) {
return abs;
}
}
return null;
}
return (code, filename) => {
try {
const extracted = (0, extractGlobals_1.extractGlobals)(code);
const sassResult = sass_1.default.compileString(preprocessCss(extracted.code, filename), {
loadPaths: [(0, path_1.dirname)(filename), ...nodeModulesPaths],
style,
charset: false,
});
const fileMappings = [];
const getFileSource = (dir, file) => {
const source = file.startsWith("~") ? getNodeModulesFile(file.substring(1)) : (0, path_1.resolve)(dir, file);
if (source && (0, fs_1.existsSync)(source)) {
return source;
}
throw new Error(`Could not locate url "${file}" from "${dir}"`);
};
const postProcessCss = (css) => {
css = extracted.reinsert(css);
if (mapFileUrl) {
const dir = (0, path_1.dirname)(filename);
css = css.replace(/url\(([^)]+)\)/g, (_, urlString) => {
const source = getFileSource(dir, JSON.parse(urlString.replace(/'/g, '"')));
const destination = mapFileUrl(source);
fileMappings.push({ source, destination });
return `url(${JSON.stringify(destination)})`;
});
}
return processCss(css, filename);
};
let { css } = sassResult;
let tokens = {};
// only .module.(s)css files need tokens
if (filename.includes(".module.")) {
const generateScopedName = (0, scopedNameGenerator_1.getScopedNameGenerator)(code, filename, generateScopedNames);
if (generateScopedName) {
const exports = (0, addScopes_1.addScopes)(css, generateScopedName);
css = exports.css;
tokens = { ...exports.keyframes, ...exports.classes };
if (transformToken)
tokens = (0, transformTokens_1.transformTokens)(tokens, transformToken);
}
}
else {
css = css.replaceAll("@-global-", "@");
}
return {
css: postProcessCss(css),
tokens,
fileMappings,
};
}
catch (e) {
throw new Error(`Error compiling ${filename}: ${String(e)}`);
}
};
}