Skip to content

Instantly share code, notes, and snippets.

@teebot
Created February 11, 2018 16:40
Show Gist options
  • Save teebot/1441c906a0e6c8a49f0f8c254fb70ae7 to your computer and use it in GitHub Desktop.
Save teebot/1441c906a0e6c8a49f0f8c254fb70ae7 to your computer and use it in GitHub Desktop.
A typescript koa 2 sass middleware
import * as fs from 'fs';
import * as Koa from 'koa';
import * as sass from 'node-sass';
import * as path from 'path';
import * as url from 'url';
import * as util from 'util';
const sassRenderAsync = util.promisify(sass.render);
const fileExistsAsync = util.promisify(fs.exists);
export default (options: ISassOptions) => {
return async (context: Koa.Context, next: () => Promise<any>) => {
if (!context.req.url || !/\.css/.test(context.req.url)) {
return await next();
}
const scssFile = cssToLocalScssPath(context.req.url, options);
if (!await fileExistsAsync(scssFile)) {
context.throw(404, 'Cannot find file');
return;
}
const sassOptions: sass.Options = { file: scssFile };
const result = await sassRenderAsync(sassOptions);
await next();
context.res.writeHead(200, {
'Cache-Control': 'max-age=0',
'Content-Type': 'text/css',
});
context.body = result.css.toString('utf8');
};
};
function cssToLocalScssPath(cssUrl: string, options: ISassOptions): string {
const pathname = url.parse(cssUrl, true, true).pathname;
if (!pathname) {
throw new Error('No path could be found');
}
const relativePath = path.relative(options.publicPath, pathname);
const file = path.join(options.src, relativePath).replace('.css', '.scss');
return file;
}
export interface ISassOptions {
publicPath: string;
src: string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment