UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

169 lines (167 loc) • 6.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const Utils_1 = require("../../Utils"); const path = require("path"); const realm_utils_1 = require("realm-utils"); const fs = require("fs"); const PostCSSResourcePlugin_1 = require("../../lib/postcss/PostCSSResourcePlugin"); const SVG2Base64_1 = require("../../lib/SVG2Base64"); const base64Img = require("base64-img"); const postcss = require("postcss"); const IMG_CACHE = {}; let resourceFolderChecked = false; const copyFile = (source, target) => { return new Promise((resolve, reject) => { fs.exists(source, (exists) => { if (!exists) { return resolve(); } let rd = fs.createReadStream(source); rd.on("error", (err) => { return reject(err); }); let wr = fs.createWriteStream(target); wr.on("error", (err) => { return reject(err); }); wr.on("close", (ex) => { return resolve(); }); rd.pipe(wr); }); }); }; const generateNewFileName = (str) => { let s = str.split("node_modules"); const ext = path.extname(str); if (s[1]) { str = s[1]; } let hash = 0; let i; let chr; let len; if (str.length === 0) { return hash.toString() + ext; } for (i = 0, len = str.length; i < len; i++) { chr = str.charCodeAt(i); hash = ((hash << 5) - hash) + chr; hash |= 0; } let fname = hash.toString() + ext; if (fname.charAt(0) === "-") { fname = "_" + fname.slice(1); } return fname; }; class CSSResourcePluginClass { constructor(opts = {}) { this.test = /\.css$/; this.resolveFn = (p) => path.join("/css-resources", p); if (opts.dist) { this.distFolder = Utils_1.ensureDir(opts.dist); } if (opts.inline) { this.inlineImages = opts.inline; } if (opts.macros) { this.macros = opts.macros; } if (realm_utils_1.utils.isFunction(opts.resolve)) { this.resolveFn = opts.resolve; } if (realm_utils_1.utils.isFunction(opts.resolveMissing)) { this.resolveMissingFn = opts.resolveMissing; } } init(context) { context.allowExtension(".css"); } createResouceFolder(file) { if (resourceFolderChecked === false) { resourceFolderChecked = true; if (this.distFolder) { return; } this.distFolder = Utils_1.ensureDir(path.join(file.context.output.dir, "css-resources")); } } transform(file) { file.addStringDependency("fuse-box-css"); file.loadContents(); let contents = file.contents; if (this.distFolder) { this.createResouceFolder(file); } const currentFolder = file.info.absDir; const files = {}; const tasks = []; return postcss([PostCSSResourcePlugin_1.PostCSSResourcePlugin({ fn: (url) => { if (this.macros) { for (let key in this.macros) { url = url.replace('$' + key, this.macros[key]); } } let urlFile = path.isAbsolute(url) ? url : path.resolve(currentFolder, url); urlFile = urlFile.replace(/[?\#].*$/, ""); if (this.inlineImages) { if (IMG_CACHE[urlFile]) { return IMG_CACHE[urlFile]; } if (!fs.existsSync(urlFile)) { if (this.resolveMissingFn) { urlFile = this.resolveMissingFn(urlFile, this); if (!urlFile || !fs.existsSync(urlFile)) { file.context.debug("CSSResourcePlugin", `Can't find (resolved) file ${urlFile}`); return; } } else { file.context.debug("CSSResourcePlugin", `Can't find file ${urlFile}`); return; } } const ext = path.extname(urlFile); let fontsExtensions = { ".woff": "application/font-woff", ".woff2": "application/font-woff2", ".eot": "application/vnd.ms-fontobject", ".ttf": "application/x-font-ttf", ".otf": "font/opentype", }; if (fontsExtensions[ext]) { let content = new Buffer(fs.readFileSync(urlFile)).toString("base64"); return `data:${fontsExtensions[ext]};charset=utf-8;base64,${content}`; } if (ext === ".svg") { let content = SVG2Base64_1.SVG2Base64.get(fs.readFileSync(urlFile).toString()); IMG_CACHE[urlFile] = content; return content; } let result = base64Img.base64Sync(urlFile); IMG_CACHE[urlFile] = result; return result; } if (this.distFolder) { let newFileName = generateNewFileName(urlFile); if (!files[urlFile]) { let newPath = path.join(this.distFolder, newFileName); tasks.push(copyFile(urlFile, newPath)); files[urlFile] = true; } return this.resolveFn(newFileName); } }, })]).process(contents).then(result => { file.contents = result.css; return Promise.all(tasks); }); } } exports.CSSResourcePluginClass = CSSResourcePluginClass; exports.CSSResourcePlugin = (options) => { return new CSSResourcePluginClass(options); }; //# sourceMappingURL=CSSResourcePlugin.js.map