Installation
Install it as a “dev” dependency:
npm i -D gulp-email-remove-unused-css
Example
import gulp from "gulp";
import remove from "gulp-email-remove-unused-css";
gulp.task("default", function () {
return gulp
.src("src/*.html")
.pipe(
remove({
whitelist: [
".ExternalClass",
".ReadMsgBody",
".yshortcuts",
".Mso*",
".maxwidth-apple-mail-fix",
"#outlook",
".module-*",
],
})
)
.pipe(gulp.dest("./dist"));
});
Options
Since the main purpose of this library is to clean email HTML, it needs to cater for email code specifics. One of them is that CSS styles will contain fix or hack styles, meant for email software. For example:
#outlook a { padding:0; } .ExternalClass, .ReadMsgBody { width:100%; }
Such CSS styles will not be “used” by your template and email-comb
(which drives this plugin) will remove them. To prevent this, you need to whitelist all CSS hack classes and id’s:
.pipe(remove({
whitelist: ['.ExternalClass', '.ReadMsgBody', '.yshortcuts', '.Mso*', '.maxwidth-apple-mail-fix', '#outlook']
}))
You can also use a glob, for example in order to whitelist classes module-1
, module-2
… module-99
, module-100
, you can simply whitelist them as module-*
:
.pipe(remove({
whitelist: ['.ExternalClass', '.ReadMsgBody', '.yshortcuts', '.Mso*', '.maxwidth-apple-mail-fix', '#outlook', '.module-*']
}))
// => all class names that begin with ".module-" will not be touched by this library.
The next level
If you start to overgrow the plugin’s baby shirt and want to work with HTML directly, as string, stop using this library and use the email-comb
, the API of this Gulp plugin directly.
The idea is the following: in Gulp, everything flows as a vinyl Buffer streams. You tap the stream, convert it to string
, perform the operations, then convert it back to Buffer and place it back. We wanted to come up with a visual analogy example using waste pipes but thought we’d rather won’t.
Code-wise, here’s the idea:
import tap from 'gulp-tap';
import { comb } from 'email-comb';
import util from 'gulp-util';
const whitelist = ['.External*', '.ReadMsgBody', '.yshortcuts', '.Mso*', '#outlook', '.module*'];
gulp.task('build', () => {
return gulp.src('emails/*.html')
.pipe(tap((file) => {
const cleanedHtmlResult = comb(file.contents.toString(), { whitelist });
util.log(util.colors.green(`\nremoved ${cleanedHtmlResult.deletedFromHead.length} from head: ${cleanedHtmlResult.deletedFromHead.join(' ')}`));
util.log(util.colors.green(`\nremoved ${cleanedHtmlResult.deletedFromBody.length} from body: ${cleanedHtmlResult.deletedFromBody.join(' ')}`));
file.contents = Buffer.from(cleanedHtmlResult.result);
}))
There are many benefits for tapping npm packages directly, without gulp plugins:
- You can add more functions, wrap them over
comb()
and Buffer-String-Buffer conversion will happen only once. If each of those functions was a Gulp plugin and did their Buffer-String-Buffer conversions that would be less efficient. Yes, all packages should be in streams but it adds complexity. - Gulp plugins can only be same or worse maintained than their API packages which drive them. Often it’s the latter case.
- Gulp plugins might be misconfigured and fail — even though the API package will work fine. Bigger surface to test, maintain and report bugs is worse than just one npm package.