diff --git a/CHANGELOG.md b/CHANGELOG.md
index 33b2c44..05933b9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
## purifycss-webpack
+0.7.0 / 2017-05-16
+==================
+
+ * Breaking - Push **purify-css** as a peer dependency. #108
+
+0.6.2 / 2017-05-08
+==================
+
+ * Docs - Add **glob-all** example. #105
+
+0.6.1 / 2017-04-14
+==================
+
+ * Docs - Fix CSS Modules example (prefix has to be lowercase to work).
+
+0.6.0 / 2017-04-07
+==================
+
+ * Feature - Allow asset names to contain `?`. Example: `style.css?218aa9358a709a5a0a12`. #94
+
+0.5.0 / 2017-03-02
+==================
+
+ * Feature - Add strict validation against `paths`. #88
+
+0.4.3 / 2017-03-01
+==================
+
+ * Bug fix - Fix chunk file match dependency on [name]. #86
+
0.4.2 / 2017-01-28
==================
diff --git a/README.md b/README.md
index 9227908..078fd07 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,8 @@
+# UNMAINTAINED
+
+Please use: https://github.com/FullHuman/purgecss-webpack-plugin
+
+---
[![npm][npm]][npm-url]
[![deps][deps]][deps-url]
[![test][test]][test-url]
@@ -24,7 +29,7 @@ Without any CSS file being emitted as an asset, this plugin will do nothing. You
Install
```bash
-npm i -D purifycss-webpack
+npm i -D purifycss-webpack purify-css
```
Usage
@@ -64,6 +69,19 @@ module.exports = {
And, that's it! Your scripts and view files will be scanned for classes, and those that are unused will be stripped off your CSS - aka. "purified".
+In order to use this plugin to look into multiple paths you will need to:
+
+1. npm install --save glob-all
+2. Add `const glob = require('glob-all');` at the top of your webpack config
+3. Then you can pass your paths to an array, like so:
+
+```javascript
+paths: glob.sync([
+ path.join(__dirname, '.php'),
+ path.join(__dirname, 'partials/.php')
+]),
+```
+
> You can pass an object (` -> []`) to `paths` if you want to control the behavior per entry.
Options
@@ -81,6 +99,44 @@ This plugin, unlike the original PurifyCSS plugin, provides special features, su
> The plugin does **not** emit sourcemaps even if you enable `sourceMap` option on loaders!
+Usage with CSS Modules
+
+PurifyCSS doesn't support classes that have been namespaced with CSS Modules. However, by adding a static string to `css-loader`'s `localIdentName`, you can effectively whitelist these namespaced classes.
+
+In this example, `purify` will be our whitelisted string. **Note:** Make sure this string doesn't occur in any of your other CSS class names. Keep in mind that whatever you choose will end up in your application at runtime - try to keep it short!
+
+```javascript
+module.exports = {
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ loader: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: [
+ {
+ loader: 'css-loader',
+ options: {
+ localIdentName: 'purify_[hash:base64:5]',
+ modules: true
+ }
+ }
+ ]
+ })
+ }
+ ]
+ },
+ plugins: [
+ ...,
+ new PurifyCSSPlugin({
+ purifyOptions: {
+ whitelist: ['*purify*']
+ }
+ })
+ ]
+};
+```
+
Maintainers
diff --git a/examples/README.md b/examples/README.md
index 38f104a..daa6189 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -1,5 +1,6 @@
1. `npm install` at project root
2. `npm run build`
3. `cd examples`
-4. `npm run build`
-5. Examine `./build`
+4. `npm install`
+5. `npm run build`
+6. Examine `./build`
diff --git a/examples/webpack.parts.js b/examples/webpack.parts.js
index f905fd6..4933b1f 100644
--- a/examples/webpack.parts.js
+++ b/examples/webpack.parts.js
@@ -16,7 +16,7 @@ exports.extractCSS = function extractCSS(paths) {
]
},
plugins: [
- new ExtractTextPlugin('[name].css')
+ new ExtractTextPlugin('[name].css?[hash]')
]
};
};
diff --git a/package.json b/package.json
index bca5c90..cee2a3e 100644
--- a/package.json
+++ b/package.json
@@ -1,15 +1,15 @@
{
"name": "purifycss-webpack",
- "version": "0.4.2",
+ "version": "0.7.0",
"description": "PurifyCSS for webpack",
"main": "./dist",
"scripts": {
- "build": "babel src -d dist",
+ "build": "rimraf dist && babel src -d dist",
"build:watch": "npm-watch",
"test:all": "npm run test:coverage && npm run test:lint",
- "test": "jest --",
- "test:coverage": "jest --coverage --",
- "test:watch": "jest --watch --",
+ "test": "jest",
+ "test:coverage": "jest --coverage",
+ "test:watch": "jest --watch",
"test:lint": "eslint . --ext .js --ignore-path .gitignore --cache",
"preversion": "npm run test:all && npm run build && git commit --allow-empty -am \"Update dist\"",
"postinstall": "node lib/post_install.js"
@@ -39,17 +39,16 @@
]
},
"author": "Kenny Tran, Matthew Rourke, Phoebe Li, Kevin \"Ingwie Phoenix\" Ingwersen",
- "license": "ISC",
+ "license": "MIT",
"bugs": {
"url": "https://github.com/webpack-contrib/purifycss-webpack/issues"
},
"homepage": "https://github.com/webpack-contrib/purifycss-webpack",
"peerDependencies": {
- "webpack": "^1.9 || ^2.2.0 || ^2.1.0-beta || ^2.2.0-rc"
+ "purify-css": ">= 1.0.0 < 2.0.0"
},
"dependencies": {
"ajv": "^4.11.2",
- "purify-css": "^1.1.9",
"webpack-sources": "^0.1.4"
},
"devDependencies": {
@@ -67,7 +66,9 @@
"eslint-plugin-react": "^6.9.0",
"git-prepush-hook": "^1.0.1",
"jest": "^18.1.0",
- "npm-watch": "^0.1.8"
+ "npm-watch": "^0.1.8",
+ "purify-css": "^1.2.2",
+ "rimraf": "^2.6.1"
},
"pre-push": [
"build",
@@ -75,7 +76,9 @@
],
"watch": {
"build": {
- "patterns": ["src"],
+ "patterns": [
+ "src"
+ ],
"extensions": "js",
"quiet": false
}
diff --git a/src/index.js b/src/index.js
index f4e6977..3acdaaf 100644
--- a/src/index.js
+++ b/src/index.js
@@ -1,3 +1,4 @@
+import fs from 'fs';
import purify from 'purify-css';
import { ConcatSource } from 'webpack-sources';
import * as parse from './parse';
@@ -22,6 +23,10 @@ module.exports = function PurifyPlugin(options) {
compiler.plugin('this-compilation', (compilation) => {
const entryPaths = parse.entryPaths(options.paths);
+ parse.flatten(entryPaths).forEach((p) => {
+ if (!fs.existsSync(p)) throw new Error(`Path ${p} does not exist.`);
+ });
+
// Output debug information through a callback pattern
// to avoid unnecessary processing
const output = options.verbose ?
@@ -31,11 +36,11 @@ module.exports = function PurifyPlugin(options) {
compilation.plugin('additional-assets', (cb) => {
// Go through chunks and purify as configured
compilation.chunks.forEach(
- ({ name: chunkName, modules }) => {
+ ({ name: chunkName, files, modules }) => {
const assetsToPurify = search.assets(
compilation.assets, options.styleExtensions
).filter(
- asset => asset.name.indexOf(chunkName) >= 0
+ asset => files.indexOf(asset.name) >= 0
);
output(() => [
diff --git a/src/parse.js b/src/parse.js
index 58ffee1..0797085 100644
--- a/src/parse.js
+++ b/src/parse.js
@@ -9,6 +9,12 @@ function parseEntryPaths(paths) {
return ret;
}
+function flattenEntryPaths(paths) {
+ return Array.isArray(paths) ?
+ paths :
+ Object.keys(paths).reduce((acc, val) => [...acc, ...paths[val]], []);
+}
+
function parseEntries(paths, chunkName) {
if (Array.isArray(paths)) {
return paths;
@@ -25,5 +31,6 @@ function parseEntries(paths, chunkName) {
module.exports = {
entryPaths: parseEntryPaths,
+ flatten: flattenEntryPaths,
entries: parseEntries
};
diff --git a/src/parse.test.js b/src/parse.test.js
index 721df94..1b75d7e 100644
--- a/src/parse.test.js
+++ b/src/parse.test.js
@@ -19,6 +19,20 @@ describe('Parse entry paths', function () {
});
});
+describe('Flatten entry paths', function () {
+ it('returns an array as itself', function () {
+ const a = ['a', 'b', 'c'];
+
+ assert.deepEqual(parse.flatten(a), a);
+ });
+
+ it('returns an object of arrays as one flat array', function () {
+ const o = { a: ['a', 'b'], b: ['c', 'd'] };
+
+ assert.deepEqual(parse.flatten(o), ['a', 'b', 'c', 'd']);
+ });
+});
+
describe('Parse entries', function () {
it('returns paths if there is no chunk name', function () {
const paths = ['a', 'b', 'c'];
diff --git a/src/search.js b/src/search.js
index cab74f4..80d33e8 100644
--- a/src/search.js
+++ b/src/search.js
@@ -5,7 +5,13 @@ function searchAssets(
extensions = []
) {
return Object.keys(assets).map(
- name => extensions.indexOf(path.extname(name)) >= 0 && { name, asset: assets[name] }
+ name => (
+ extensions.indexOf(
+ path.extname(
+ name.indexOf('?') >= 0 ? name.split('?').slice(0, -1).join('') : name
+ )
+ ) >= 0 && { name, asset: assets[name] }
+ )
).filter(a => a);
}
diff --git a/src/search.test.js b/src/search.test.js
index 512b7d7..a542091 100644
--- a/src/search.test.js
+++ b/src/search.test.js
@@ -16,6 +16,17 @@ describe('Search assets', function () {
assert.deepEqual(search.assets(modules, extensions), matches);
});
+
+ it('returns matches if they have query', function () {
+ const modules = {
+ 'foobar.txt?123': {},
+ 'barbar.css': {}
+ };
+ const extensions = ['.txt'];
+ const matches = [{ name: 'foobar.txt?123', asset: {} }];
+
+ assert.deepEqual(search.assets(modules, extensions), matches);
+ });
});
describe('Search files', function () {