UNPKG

fuse-box

Version:

Fuse-Box a bundler that does it right

120 lines (100 loc) 3.64 kB
import { File } from "../../core/File"; import { WorkFlowContext, Plugin } from "../../core/WorkflowContext"; import * as path from "path"; import { Config } from "../../Config"; export interface SassPluginOptions { includePaths?: string[]; macros?: { [key: string]: string }; importer?: boolean | ImporterFunc; cache?: boolean; functions?: { [key: string]: (...args: any[]) => any } } export interface ImporterFunc { (url: string, prev: string, done: (opts: { url?: string; file?: string; }) => any): any; } let sass; /** * @export * @class SassPlugin * @implements {Plugin} */ export class SassPluginClass implements Plugin { public test: RegExp = /\.(scss|sass)$/; public context: WorkFlowContext; constructor(public options: SassPluginOptions = {}) { } public init(context: WorkFlowContext) { context.allowExtension(".scss"); context.allowExtension(".sass"); this.context = context; } public transform(file: File): Promise<any> { file.addStringDependency("fuse-box-css"); const context = file.context; if (context.useCache && this.options.cache) { let cached = context.cache.getStaticCache(file); if (cached) { if (cached.sourceMap) { file.sourceMap = cached.sourceMap; } file.isLoaded = true; file.contents = cached.contents; return; } } file.loadContents(); if (!file.contents) { return; } if (!sass) { sass = require("node-sass"); } const defaultMacro = { "$homeDir": file.context.homeDir, "$appRoot": context.appRoot, "~": Config.NODE_MODULES_DIR + "/", }; const options = Object.assign({ data: file.contents, sourceMap: true, outFile: file.info.fuseBoxPath, sourceMapContents: true }, this.options); options.includePaths = []; if (typeof this.options.includePaths !== "undefined") { this.options.includePaths.forEach((path) => { options.includePaths.push(path); }); } options.macros = Object.assign(defaultMacro, this.options.macros || {}, ); if (this.options.importer === true) { options.importer = (url, prev, done) => { if (/https?:/.test(url)) { return done({ url }); } for (let key in options.macros) { if (options.macros.hasOwnProperty(key)) { url = url.replace(key, options.macros[key]); } } done({ file: path.normalize(url) }); }; } options.includePaths.push(file.info.absDir); return new Promise((resolve, reject) => { return sass.render(options, (err, result) => { if (err) { file.contents = ""; console.log(err.stack || err) return resolve(); } file.sourceMap = result.map && result.map.toString(); file.contents = result.css.toString(); if (context.useCache && this.options.cache) { context.cache.writeStaticCache(file, file.sourceMap); } return resolve(); }); }); } } export const SassPlugin = (options?: SassPluginOptions) => { return new SassPluginClass(options); };