UNPKG

@morfeo/compiler

Version:

![Morfeo logo](https://morfeo.dev/img/morfeo.png)

125 lines 5.44 kB
import { __awaiter } from "tslib"; import * as fs from 'fs'; import * as path from 'path'; import * as chokidar from 'chokidar'; import { glob } from 'glob'; import * as babel from '@babel/core'; import morfeoBabelPlugin from '@morfeo/babel-plugin'; import { morfeo, resolveMultiThemeValue } from '@morfeo/web'; import { getStyles } from '@morfeo/jss'; import { deepMerge } from '@morfeo/utils'; import { createWriter } from './writer'; import { logger } from './logger'; const DEFAULT_BABEL_PRESETS = ['@babel/preset-env', '@babel/preset-typescript']; const DEFAULT_BABEL_PLUGINS = ['@babel/plugin-syntax-jsx']; const DEFAULT_OPTIONS = { emojis: false, classNamePrefix: '', entryPoints: [path.join('.', '**/*.{ts,tsx,js,jsx}')], output: path.join(__dirname, '..', 'css', 'morfeo.css'), theme: {}, watch: false, }; function createCollector() { const cache = new Map(); let options = DEFAULT_OPTIONS; let writer = createWriter({ output: DEFAULT_OPTIONS.output, }); function init(pluginOptions) { var _a, _b, _c, _d; options = Object.assign(Object.assign(Object.assign({}, DEFAULT_OPTIONS), pluginOptions), { babel: Object.assign(Object.assign({}, pluginOptions.babel), { presets: Array.from(new Set([ ...DEFAULT_BABEL_PRESETS, ...(((_a = options.babel) === null || _a === void 0 ? void 0 : _a.presets) || []), ...(((_b = pluginOptions.babel) === null || _b === void 0 ? void 0 : _b.presets) || []), ])), plugins: Array.from(new Set([ ...DEFAULT_BABEL_PLUGINS, ...(((_c = options.babel) === null || _c === void 0 ? void 0 : _c.plugins) || []), ...(((_d = pluginOptions.babel) === null || _d === void 0 ? void 0 : _d.plugins) || []), [morfeoBabelPlugin, {}], ])) }) }); morfeo.theme.set(options.theme); writer = createWriter({ delay: 10, output: pluginOptions.output || DEFAULT_OPTIONS.output, }); } function write() { return __awaiter(this, void 0, void 0, function* () { function onWrite() { const { light = {}, dark = {} } = morfeo.theme.getMetadata(); const variables = getStyles({ '@global': { ':root': light, [resolveMultiThemeValue('dark')]: { ':root': dark, }, }, }).sheet.toString(); const mergedCss = Array.from(cache.entries()).reduce((acc, [, { globalStyles, styles }]) => { return { globalStyles: deepMerge(acc.globalStyles, globalStyles), styles: deepMerge(acc.styles, styles), }; }, { globalStyles: {}, styles: {} }); const css = [ ...Object.values(mergedCss.globalStyles), ...Object.values(mergedCss.styles), ].join('\n'); return `${variables}\n${css}`; } return writer(onWrite); }); } function extract(fileName) { return __awaiter(this, void 0, void 0, function* () { const fileContent = fs.readFileSync(fileName, { encoding: 'utf-8' }); const result = yield babel.transformAsync(fileContent, Object.assign(Object.assign({}, options.babel), { sourceFileName: fileName, filename: path.basename(fileName), sourceMaps: false, code: false, ast: false })); // @ts-ignore if (!result || !result.metadata || !result.metadata.morfeo) { return { globalStyles: {}, styles: {} }; } // @ts-ignore return result.metadata.morfeo; }); } function collectFile(fileName) { return __awaiter(this, void 0, void 0, function* () { const css = yield extract(fileName); cache.set(fileName, css); write(); }); } function watch(entryPoints) { const watcher = chokidar.watch(entryPoints, { ignoreInitial: true, }); watcher.add(entryPoints).on('add', fileName => { logger.debug(`${path.basename(fileName)} added`); collectFile(fileName); }); watcher.add(entryPoints).on('change', fileName => { logger.debug(`${path.basename(fileName)} changed`); collectFile(fileName); }); } function collect() { return __awaiter(this, void 0, void 0, function* () { const entryPoints = options.entryPoints || DEFAULT_OPTIONS.entryPoints; logger.debug(`Start extracting CSS from ${entryPoints}`); const fileNames = yield glob(entryPoints); logger.startTimer('css extraction'); Promise.all(fileNames.map(collectFile)).then(() => { const diff = logger.endTimer('css extraction'); logger.debug(`CSS extracted in ${diff} seconds.`); }); if (options.watch) { logger.debug('Watching for file changes'); watch(entryPoints); } }); } return { init, collect }; } export const collector = createCollector(); //# sourceMappingURL=collector.js.map