From 9811e013793b9fe7926b212a9fcfbf525f88270d Mon Sep 17 00:00:00 2001 From: Mehmet Can Ozdemir Date: Wed, 22 Jun 2022 16:56:29 +0300 Subject: [PATCH 1/3] fix: check if file exists in chunk after only filter --- packages/purgecss-webpack-plugin/src/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/purgecss-webpack-plugin/src/index.ts b/packages/purgecss-webpack-plugin/src/index.ts index efccb900..a85b5fa9 100644 --- a/packages/purgecss-webpack-plugin/src/index.ts +++ b/packages/purgecss-webpack-plugin/src/index.ts @@ -167,7 +167,9 @@ export class PurgeCSSPlugin { for (const chunk of compilation.chunks) { const assetsToPurge = assetsFromCompilation.filter(([name]) => { if (this.options.only) { - return this.options.only.some((only) => name.includes(only)); + if (!(this.options.only.some((only) => name.includes(only)))) { + return false; + } } return chunk.files.has(name); From e88b7d0daf6f86c519098d9a5496a32751b77a9e Mon Sep 17 00:00:00 2001 From: Mehmet Can Ozdemir Date: Wed, 22 Jun 2022 16:56:30 +0300 Subject: [PATCH 2/3] test: update simple-with-exclusion test case of purgecss-webpack-plugin to actually test for purgecss exclusion --- .../expected/{styles.css => bundle.css} | 20 ------------------- .../simple-with-exclusion/expected/legacy.css | 14 +++++++++++++ .../simple-with-exclusion/webpack.config.js | 14 ++----------- 3 files changed, 16 insertions(+), 32 deletions(-) rename packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/{styles.css => bundle.css} (51%) create mode 100644 packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/legacy.css diff --git a/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/styles.css b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/bundle.css similarity index 51% rename from packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/styles.css rename to packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/bundle.css index e0271a4f..9343bab2 100644 --- a/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/styles.css +++ b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/bundle.css @@ -5,10 +5,6 @@ color: red; } -.unused { - color: blue; -} - .safelisted { color: green; } @@ -16,19 +12,3 @@ md\:w-2\/3 { color: red; } - -/*!******************************************************************************!*\ - !*** css ../../../../../node_modules/css-loader/dist/cjs.js!./src/style.css ***! - \******************************************************************************/ -.legacy-unused-class { - color: red; -} - -.unused-too { - color: blue; -} - -.hello { - color: red; -} - diff --git a/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/legacy.css b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/legacy.css new file mode 100644 index 00000000..201f3cde --- /dev/null +++ b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/expected/legacy.css @@ -0,0 +1,14 @@ +/*!******************************************************************************!*\ + !*** css ../../../../../node_modules/css-loader/dist/cjs.js!./src/style.css ***! + \******************************************************************************/ +.legacy-unused-class { + color: red; +} + +.unused-too { + color: blue; +} + +.hello { + color: red; +} diff --git a/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/webpack.config.js b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/webpack.config.js index 7f0fa1c5..c6f183c9 100644 --- a/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/webpack.config.js +++ b/packages/purgecss-webpack-plugin/__tests__/cases/simple-with-exclusion/webpack.config.js @@ -1,7 +1,7 @@ const path = require("path"); const glob = require("glob"); const MiniCssExtractPlugin = require("mini-css-extract-plugin"); -const {PurgeCSSPlugin} = require("../../../src/"); +const { PurgeCSSPlugin } = require("../../../src/"); const customExtractor = (content) => content.match(/[A-z0-9-:/]+/g) || []; @@ -17,17 +17,7 @@ module.exports = { legacy: "./src/legacy.js", }, optimization: { - splitChunks: { - cacheGroups: { - styles: { - name: "styles", - type: "css/mini-extract", - test: /\.css$/, - chunks: "all", - enforce: true, - }, - }, - }, + splitChunks: { chunks: "all" }, }, module: { rules: [ From 955c1de63a8049a57aebb044a3b11807e6bc4731 Mon Sep 17 00:00:00 2001 From: Mehmet Can Ozdemir Date: Wed, 22 Jun 2022 17:08:08 +0300 Subject: [PATCH 3/3] docs: only option checks against chunk names instead of entrypoints --- docs/plugins/webpack.md | 91 ++++++++++++++++++++--------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/docs/plugins/webpack.md b/docs/plugins/webpack.md index 27f15839..0e1c5e74 100644 --- a/docs/plugins/webpack.md +++ b/docs/plugins/webpack.md @@ -7,7 +7,7 @@ meta: - itemprop: description content: PurgeCSS is a tool for removing CSS that you're not actually using in your project. You can use it with webpack with a plugin. - property: og:url - content: https://purgecss.com/plugins/webpack + content: https://purgecss.com/plugins/webpack - property: og:site_name content: purgecss.com - property: og:type @@ -39,55 +39,54 @@ npm i purgecss-webpack-plugin -D ### With mini-css-extract-plugin ```js -const path = require('path') -const glob = require('glob') -const MiniCssExtractPlugin = require('mini-css-extract-plugin') -const PurgecssPlugin = require('purgecss-webpack-plugin') +const path = require("path"); +const glob = require("glob"); +const MiniCssExtractPlugin = require("mini-css-extract-plugin"); +const PurgecssPlugin = require("purgecss-webpack-plugin"); const PATHS = { - src: path.join(__dirname, 'src') -} + src: path.join(__dirname, "src"), +}; module.exports = { - entry: './src/index.js', + entry: "./src/index.js", output: { - filename: 'bundle.js', - path: path.join(__dirname, 'dist') + filename: "bundle.js", + path: path.join(__dirname, "dist"), }, optimization: { splitChunks: { cacheGroups: { styles: { - name: 'styles', + name: "styles", test: /\.css$/, - chunks: 'all', - enforce: true - } - } - } + chunks: "all", + enforce: true, + }, + }, + }, }, module: { rules: [ { test: /\.css$/, - use: [ - MiniCssExtractPlugin.loader, - "css-loader" - ] - } - ] + use: [MiniCssExtractPlugin.loader, "css-loader"], + }, + ], }, plugins: [ new MiniCssExtractPlugin({ filename: "[name].css", }), new PurgecssPlugin({ - paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }), + paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }), }), - ] -} + ], +}; ``` + ### Multiple paths + If you need multiple paths use the npm package `glob-all` instead of `glob`, then you can use this syntax: ```js @@ -97,70 +96,70 @@ new PurgecssPlugin({ ]) }), ``` + to filter out directories see the glob-all documentation [here](https://www.npmjs.com/package/glob-all#filtering-out-directories). ## Options The options available in purgecss [Configuration](https://www.purgecss.com/configuration.html) are also available in the webpack plugin, with the exception of the `css` and `content` options. -* #### paths +- #### paths With the webpack plugin, you can specify the content that should be analyzed by purgecss by providing an array of filenames. These can be html, pug, blade, ... files. You can also use a module like `glob` or `glob-all` to easily get a list of files. > You likely need to pass `{ noDir: true }` as an option to `glob.sync()` as `glob.sync` is matching a dir which the plugin can't operate on. ```js -const PurgecssPlugin = require('purgecss-webpack-plugin') -const glob = require('glob') +const PurgecssPlugin = require("purgecss-webpack-plugin"); +const glob = require("glob"); const PATHS = { - src: path.join(__dirname, 'src') -} + src: path.join(__dirname, "src"), +}; // In the webpack configuration new PurgecssPlugin({ - paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }) -}) + paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }), +}); ``` If you want to regenerate the list of paths on every compilation (e.g. when using `--watch`), then you can also pass a function to the `paths` option as in the following example: ```js new PurgecssPlugin({ - paths: () => glob.sync(`${PATHS.src}/**/*`, { nodir: true }) -}) + paths: () => glob.sync(`${PATHS.src}/**/*`, { nodir: true }), +}); ``` -* #### only +- #### only -You can specify entrypoints to the purgecss-webpack-plugin with the option `only`: +You can specify chunk names to the purgecss-webpack-plugin with the option `only`: ```js new PurgecssPlugin({ paths: glob.sync(`${PATHS.src}/**/*`, { nodir: true }), - only: ['bundle', 'vendor'] -}) + only: ["bundle", "vendor"], +}); ``` -* #### safelist +- #### safelist Similar as for the `paths` option, you also can define a function for this option: ```js function collectSafelist() { return { - standard: ['safelisted', /^safelisted-/], + standard: ["safelisted", /^safelisted-/], deep: [/^safelisted-deep-/], - greedy: [/^safelisted-greedy/] - } + greedy: [/^safelisted-greedy/], + }; } // In the webpack configuration new PurgeCSSPlugin({ - safelist: collectSafelist -}) + safelist: collectSafelist, +}); ``` - -* #### rejected +- #### rejected When this option is set to `true` all removed selectors are added to the [Stats Data](https://webpack.js.org/api/stats/) as `purged`.