From 2a276635ab598bd751a139a218f295d9923ec44b Mon Sep 17 00:00:00 2001 From: Bryan Jones Date: Sun, 14 Mar 2021 16:14:27 -0700 Subject: [PATCH] Add Ability to Ignore Files/Folders (#638) * Add Skiplist Option Adds support for the "ignore" option of the glob dependency to prevent PurgeCSS from scanning specific folders (such as node_modules, etc.) * Update Readme Add description for new "skippedlist" option * Rename Option, Fix Type Replaced "skiplist" with "skippedContentGlobs" and changed the type to Array * Rename Option, Fix Type Replaced "skiplist" with "skippedContentGlobs" and changed the type to Array * Add Skipped-Content Test test for "skippedContentGlobs" added, casing on 'string' type fixed. Test passes, but only with full path to file to skip right now. * Fix test Use the correct path for the test environment * Update Docs Minor documentation tweaks Co-authored-by: Bryan Jones Co-authored-by: Floriel --- packages/postcss-purgecss/README.md | 9 +++++++ packages/postcss-purgecss/src/types/index.ts | 1 + .../__tests__/skipped-content.test.ts | 24 +++++++++++++++++++ .../test_examples/skipped-content/simple.css | 11 +++++++++ .../skippedFolder/skipped.html | 1 + .../skipped-content/unskipped.html | 2 ++ packages/purgecss/bin/purgecss.js | 8 +++++-- packages/purgecss/src/index.ts | 12 ++++++++-- packages/purgecss/src/options.ts | 1 + packages/purgecss/src/types/index.ts | 2 ++ 10 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 packages/purgecss/__tests__/skipped-content.test.ts create mode 100644 packages/purgecss/__tests__/test_examples/skipped-content/simple.css create mode 100644 packages/purgecss/__tests__/test_examples/skipped-content/skippedFolder/skipped.html create mode 100644 packages/purgecss/__tests__/test_examples/skipped-content/unskipped.html diff --git a/packages/postcss-purgecss/README.md b/packages/postcss-purgecss/README.md index 62756d18..75de58e4 100644 --- a/packages/postcss-purgecss/README.md +++ b/packages/postcss-purgecss/README.md @@ -94,6 +94,15 @@ blocklist: ['usedClass', /^nav-/] ``` Even if nav-links and usedClass are found by an extractor, they will be removed. +### `skippedContentGlobs` + +If you provide globs for the `content` parameter, you can use this option to exclude certain files or folders that would otherwise be scanned. Pass an array of globs matching items that should be excluded. (Note: this option has no effect if `content` is not globs.) + +```ts +skippedContentGlobs: ['node_modules/**', 'components/**'] +``` +Here, PurgeCSS will not scan anything in the "node_modules" and "components" folders. + ### `rejected` Type: `boolean` diff --git a/packages/postcss-purgecss/src/types/index.ts b/packages/postcss-purgecss/src/types/index.ts index 20a5352b..ad87ba7f 100644 --- a/packages/postcss-purgecss/src/types/index.ts +++ b/packages/postcss-purgecss/src/types/index.ts @@ -30,4 +30,5 @@ export interface UserDefinedOptions { variables?: boolean; safelist?: UserDefinedSafelist; blocklist?: StringRegExpArray; + skippedContentGlobs?: Array; } diff --git a/packages/purgecss/__tests__/skipped-content.test.ts b/packages/purgecss/__tests__/skipped-content.test.ts new file mode 100644 index 00000000..1ed60f66 --- /dev/null +++ b/packages/purgecss/__tests__/skipped-content.test.ts @@ -0,0 +1,24 @@ +import PurgeCSS from "./../src/index"; + +import { ROOT_TEST_EXAMPLES } from "./utils"; + +describe("skipped-content", () => { + let purgedCSS: string; + + beforeAll(async () => { + const resultsPurge = await new PurgeCSS().purge({ + content: [`${ROOT_TEST_EXAMPLES}skipped-content/**/*.html`], + css: [`${ROOT_TEST_EXAMPLES}skipped-content/simple.css`], + skippedContentGlobs: [ + `${ROOT_TEST_EXAMPLES}skipped-content/skippedFolder/**`, + ], + }); + purgedCSS = resultsPurge[0].css; + }); + + it("purges appropriate CSS rules when skippedContentGlobs is set", () => { + expect(purgedCSS.includes(".red")).toBe(true); + expect(purgedCSS.includes(".black")).toBe(true); + expect(purgedCSS.includes(".green")).toBe(false); + }); +}); diff --git a/packages/purgecss/__tests__/test_examples/skipped-content/simple.css b/packages/purgecss/__tests__/test_examples/skipped-content/simple.css new file mode 100644 index 00000000..bffcee0a --- /dev/null +++ b/packages/purgecss/__tests__/test_examples/skipped-content/simple.css @@ -0,0 +1,11 @@ +.black { + color: black; +} + +.red { + color: red; +} + +.green { + color: green; +} diff --git a/packages/purgecss/__tests__/test_examples/skipped-content/skippedFolder/skipped.html b/packages/purgecss/__tests__/test_examples/skipped-content/skippedFolder/skipped.html new file mode 100644 index 00000000..cac6fa68 --- /dev/null +++ b/packages/purgecss/__tests__/test_examples/skipped-content/skippedFolder/skipped.html @@ -0,0 +1 @@ +

anything

diff --git a/packages/purgecss/__tests__/test_examples/skipped-content/unskipped.html b/packages/purgecss/__tests__/test_examples/skipped-content/unskipped.html new file mode 100644 index 00000000..b03833da --- /dev/null +++ b/packages/purgecss/__tests__/test_examples/skipped-content/unskipped.html @@ -0,0 +1,2 @@ +

anything

+

anything

\ No newline at end of file diff --git a/packages/purgecss/bin/purgecss.js b/packages/purgecss/bin/purgecss.js index 9da3c584..df1f895b 100755 --- a/packages/purgecss/bin/purgecss.js +++ b/packages/purgecss/bin/purgecss.js @@ -35,6 +35,10 @@ program .option( "-b, --blocklist ", "list of selectors that should be removed" + ) + .option( + "-k, --skippedContentGlobs ", + "list of glob patterns for folders/files that should not be scanned" ); program.parse(process.argv); @@ -58,9 +62,9 @@ const run = async () => { if (program.keyframes) options.keyframes = program.keyframes; if (program.rejected) options.rejected = program.rejected; if (program.variables) options.variables = program.variables; - if (program.safelist) - options.safelist = standardizeSafelist(program.safelist); + if (program.safelist) options.safelist = standardizeSafelist(program.safelist); if (program.blocklist) options.blocklist = program.blocklist; + if (program.skippedContentGlobs) options.skippedContentGlobs = program.skippedContentGlobs; const purged = await new PurgeCSS().purge(options); const output = options.output || program.output; diff --git a/packages/purgecss/src/index.ts b/packages/purgecss/src/index.ts index 3339d5ac..78c84e36 100644 --- a/packages/purgecss/src/index.ts +++ b/packages/purgecss/src/index.ts @@ -368,7 +368,10 @@ class PurgeCSS { await asyncFs.access(globfile, fs.constants.F_OK); filesNames.push(globfile); } catch (err) { - filesNames = glob.sync(globfile, { nodir: true }); + filesNames = glob.sync(globfile, { + nodir: true, + ignore: this.options.skippedContentGlobs, + }); } for (const file of filesNames) { const content = await asyncFs.readFile(file, "utf-8"); @@ -510,7 +513,12 @@ class PurgeCSS { const processedOptions: Array = []; for (const option of cssOptions) { if (typeof option === "string") { - processedOptions.push(...glob.sync(option, { nodir: true })); + processedOptions.push( + ...glob.sync(option, { + nodir: true, + ignore: this.options.skippedContentGlobs, + }) + ); } else { processedOptions.push(option); } diff --git a/packages/purgecss/src/options.ts b/packages/purgecss/src/options.ts index 4eaff1df..11027f40 100644 --- a/packages/purgecss/src/options.ts +++ b/packages/purgecss/src/options.ts @@ -20,5 +20,6 @@ export const defaultOptions: Options = { keyframes: [], }, blocklist: [], + skippedContentGlobs: [], dynamicAttributes: [], }; diff --git a/packages/purgecss/src/types/index.ts b/packages/purgecss/src/types/index.ts index df30a8a8..29f0ed47 100644 --- a/packages/purgecss/src/types/index.ts +++ b/packages/purgecss/src/types/index.ts @@ -66,6 +66,7 @@ export interface UserDefinedOptions { variables?: boolean; safelist?: UserDefinedSafelist; blocklist?: StringRegExpArray; + skippedContentGlobs?: Array; dynamicAttributes?: string[]; } @@ -83,6 +84,7 @@ export interface Options { variables: boolean; safelist: Required; blocklist: StringRegExpArray; + skippedContentGlobs: Array; dynamicAttributes: string[]; }