@twstyled/babel-preset
Version:
Babel plugin for twstyled -- the full-featured Tailwind CSS + CSS in JS Compiler
112 lines (111 loc) • 4.64 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.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = __importStar(require("path"));
const fs = __importStar(require("fs"));
const core_1 = require("@babel/core");
const source_map_1 = require("source-map");
const mkdirp_1 = __importDefault(require("mkdirp"));
const babel_preset_1 = require("@linaria/babel-preset");
const util_1 = require("./util");
const cache = new Map();
function babelPluginWriteCss(babel, options) {
return {
name: 'babel-plugin-write-css',
visitor: {
Program: {
enter(nodePath, state) {
const filename = state.file.opts.filename;
const hash = util_1.getHash(state.file.code);
state.mappings = [];
const cached = cache.get(filename);
if (cached && cached.hash === hash) {
if (cached.cssFilename) {
const importUseStyling = core_1.template.ast `import '${cached.cssFilename}';`;
nodePath.unshiftContainer('body', importUseStyling);
}
return;
}
cache.set(filename, { hash });
state.hash = hash;
state.cssText = '';
babel_preset_1.EvalCache.clearForFile(filename);
},
exit(nodePath, state) {
if (!state.cssText) {
return;
}
writeCss(state, options);
if (state.file.metadata.cssFilename) {
cache.set(state.file.opts.filename, {
hash: state.hash,
cssFilename: state.file.metadata.cssFilename
});
const importUseStyling = core_1.template.ast `import '${state.file.metadata.cssFilename}';`;
nodePath.unshiftContainer('body', importUseStyling);
}
}
}
}
};
}
exports.default = babelPluginWriteCss;
/**
* Write all linaria-generated CSS to the linaria cache folder, with source maps
*/
function writeCss(state, options) {
if (state.outputFilename) {
let { cssText } = state;
const { outputFilename } = state;
if (options.sourceMap) {
cssText += `/*# sourceMappingURL=data:application/json;base64,${Buffer.from(getMappingText(state)).toString('base64')}*/`;
}
// Read the file first to compare the content
// Write the new content only if it's changed
// This will prevent unnecessary WDS reloads
let currentCssText;
try {
mkdirp_1.default.sync(path.dirname(outputFilename));
currentCssText = fs.readFileSync(outputFilename, 'utf-8');
}
catch (e) {
// Ignore error
}
if (currentCssText !== cssText) {
fs.writeFileSync(outputFilename, cssText);
}
}
}
function getMappingText(state) {
const { mappings } = state;
if (mappings === null || mappings === void 0 ? void 0 : mappings.length) {
const generator = new source_map_1.SourceMapGenerator({
file: `./${state.resourceFileName.replace(/\.(js|jsx|ts|tsx)$/, '.css')}`
});
mappings.forEach((mapping) => generator.addMapping(Object.assign(mapping)));
generator.setSourceContent(`./${state.resourceFileName}`, state.file.code);
return generator.toString();
}
return '';
}