diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..f7fd45b
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,9 @@
+{
+ "presets": [
+ "es2015"
+ ],
+ "plugins": [
+ "syntax-object-rest-spread",
+ "transform-object-rest-spread"
+ ]
+}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..52494a4
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,9 @@
+# editorconfig.org
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 0000000..2c370f0
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,16 @@
+module.exports = {
+ "extends": "airbnb",
+ "env": {
+ "browser": true,
+ "node": true,
+ "mocha": true
+ },
+ "rules": {
+ "prefer-arrow-callback": 0, // mocha tests (recommendation)
+ "func-names": 0, // mocha tests (recommendation)
+ "comma-dangle": ["error", "never"], // personal preference
+ "no-param-reassign": 0, // the plugin needs this (webpack design :( )
+ "no-use-before-define": 0, // personal preference
+ "no-console": 0 // allow logging
+ }
+};
diff --git a/.gitignore b/.gitignore
index c2658d7..9d256f2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,7 @@
node_modules/
+build/
+dist/
+coverage/
+*.log
+.eslintcache
+
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..552f221
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,2 @@
+node_modules/
+*.log
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..33fce7f
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,11 @@
+language: node_js
+node_js:
+ - "4"
+ - "5"
+ - "6"
+script:
+ - (cd examples && npm i)
+ - npm run build
+ - npm run test:all
+after_success:
+ - bash <(curl -s https://codecov.io/bash)
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..05933b9
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,90 @@
+## 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
+==================
+
+ * Feature - Show nicer errors if there are extra fields.
+
+0.4.1 / 2017-01-28
+==================
+
+ * Bug fix - If an entry name does not match while processing, skip it. #72
+
+0.4.0 / 2017-01-27
+==================
+
+ * Bug fix - Support `Install
+
+```bash
+npm i -D purifycss-webpack purify-css
```
-Now, all we add, is another plugin definition. Please note: Plugins seem to be executed in order, so make sure that this plugin comes _after_ the extract plugin, if you use it.
+Usage
+
+Configure as follows:
```javascript
-var extractor = require("extract-text-webpack-plugin");
-var purify = require("bird3-purifycss-webpack-plugin");
+const path = require('path');
+const glob = require('glob');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const PurifyCSSPlugin = require('purifycss-webpack');
+
module.exports = {
- entry: "app.js",
- output: {
- // ...
- },
- module: {
- loaders: [
- { test: /\.css$/, loader: extractor.loader("style","css") }
- ]
- },
- plugins: [
- new extractor("[name].css"),
- new purify({
- basePath: __dirname,
- paths: [
- "app/views/*.html",
- "app/layout/*.html"
- ]
+ entry: {...},
+ output: {...},
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ loader: ExtractTextPlugin.extract({
+ fallbackLoader: 'style-loader',
+ loader: 'css-loader'
})
+ }
]
-}
+ },
+ plugins: [
+ new ExtractTextPlugin('[name].[contenthash].css'),
+ // Make sure this is after ExtractTextPlugin!
+ new PurifyCSSPlugin({
+ // Give paths to parse for rules. These should be absolute!
+ paths: glob.sync(path.join(__dirname, 'app/*.html')),
+ })
+ ]
+};
```
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".
-## Options
-This plugin, unlike the original PurifyCSS plugin, provides special features, such as scanning the dependency files and all kinds of files. To configure such behaviours, I will show you the options.
+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 (`Options
+
+This plugin, unlike the original PurifyCSS plugin, provides special features, such as scanning the dependency files. You can configure using the following fields:
| Property | Description
|---------------------|------------
-| `basePath` | The path from which all the other paths will start. Required.
-| `resolveExtensions` | An array of extensions that should be given to PurifyCSS when determining classes. (defaults to webpack `resolve.extensions` config)
-| `paths` | An array of globs that reveal all your files. See [glob](http://npmjs.org/glob)'s documentation to see what kind of paths you can pass in this array. Use this array to pass files that won't be known to WebPack.
-| `purifyOptions` | Pass these options to PurifyCSS. See [here](https://github.com/purifycss/purifycss#options-optional). Note: `output` is always `false`.
+| `styleExtensions` | An array of file extensions for determining used classes within style files. Defaults to `['.css']`.
+| `moduleExtensions` | An array of file extensions for determining used classes within `node_modules`. Defaults to `[]`, but `['.html']` can be useful here.
+| `minimize` | Enable CSS minification. Alias to `purifyOptions.minify`. Disabled by default.
+| `paths` | An array of absolute paths or a path to traverse. This also accepts an object (`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
+
+
+
+
+
+
+[npm]: https://img.shields.io/npm/v/purifycss-webpack.svg
+[npm-url]: https://npmjs.com/package/purifycss-webpack
+
+[deps]: https://david-dm.org/webpack-contrib/purifycss-webpack.svg
+[deps-url]: https://david-dm.org/webpack-contrib/purifycss-webpack
+
+[chat]: https://img.shields.io/badge/gitter-webpack%2Fwebpack-brightgreen.svg
+[chat-url]: https://gitter.im/webpack/webpack
+
+[test]: https://secure.travis-ci.org/webpack-contrib/purifycss-webpack.svg
+[test-url]: http://travis-ci.org/webpack-contrib/purifycss-webpack
+
+[cover]: https://codecov.io/gh/webpack-contrib/purifycss-webpack/branch/master/graph/badge.svg
+[cover-url]: https://codecov.io/gh/webpack-contrib/purifycss-webpack
-## Notes
-This plugin is NOT a fork of [the offical plugin](https://github.com/purifycss/purifycss-webpack-plugin)! Instead, this is it's own. I prefixed it with `bird3`, since it was created within my [BIRD3](https://github.com/DragonsInn/BIRD3) project and to make an obvious separation to the offical version.
+[quality]: https://www.bithound.io/github/webpack-contrib/purifycss-webpack/badges/score.svg
+[quality-url]: https://www.bithound.io/github/webpack-contrib/purifycss-webpack
diff --git a/examples/README.md b/examples/README.md
new file mode 100644
index 0000000..daa6189
--- /dev/null
+++ b/examples/README.md
@@ -0,0 +1,6 @@
+1. `npm install` at project root
+2. `npm run build`
+3. `cd examples`
+4. `npm install`
+5. `npm run build`
+6. Examine `./build`
diff --git a/examples/another/component.js b/examples/another/component.js
new file mode 100644
index 0000000..859f06b
--- /dev/null
+++ b/examples/another/component.js
@@ -0,0 +1,8 @@
+export default function () {
+ const element = document.createElement('h1');
+
+ element.className = 'pure-table';
+ element.innerHTML = 'Hello world Again';
+
+ return element;
+}
diff --git a/examples/another/index.js b/examples/another/index.js
new file mode 100644
index 0000000..960ad6b
--- /dev/null
+++ b/examples/another/index.js
@@ -0,0 +1,5 @@
+import 'purecss';
+import './main.css';
+import component from './component';
+
+document.body.appendChild(component());
diff --git a/examples/another/main.css b/examples/another/main.css
new file mode 100644
index 0000000..b1645d6
--- /dev/null
+++ b/examples/another/main.css
@@ -0,0 +1,7 @@
+body {
+ background: cornsilk;
+}
+
+body div {
+ background-color: deepskyblue;
+}
diff --git a/examples/app/component.js b/examples/app/component.js
new file mode 100644
index 0000000..54d7e41
--- /dev/null
+++ b/examples/app/component.js
@@ -0,0 +1,8 @@
+export default function () {
+ const element = document.createElement('h1');
+
+ element.className = 'pure-button';
+ element.innerHTML = 'Hello world';
+
+ return element;
+}
diff --git a/examples/app/index.js b/examples/app/index.js
new file mode 100644
index 0000000..960ad6b
--- /dev/null
+++ b/examples/app/index.js
@@ -0,0 +1,5 @@
+import 'purecss';
+import './main.css';
+import component from './component';
+
+document.body.appendChild(component());
diff --git a/examples/app/main.css b/examples/app/main.css
new file mode 100644
index 0000000..b1645d6
--- /dev/null
+++ b/examples/app/main.css
@@ -0,0 +1,7 @@
+body {
+ background: cornsilk;
+}
+
+body div {
+ background-color: deepskyblue;
+}
diff --git a/examples/package.json b/examples/package.json
new file mode 100644
index 0000000..5469eec
--- /dev/null
+++ b/examples/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "examples",
+ "scripts": {
+ "build": "webpack"
+ },
+ "dependencies": {
+ "css-loader": "^0.26.1",
+ "extract-text-webpack-plugin": "^2.0.0-beta.5",
+ "glob": "^7.1.1",
+ "purecss": "^0.6.2",
+ "style-loader": "^0.13.1",
+ "webpack": "^2.2.0-rc.3",
+ "webpack-merge": "^2.4.0"
+ }
+}
diff --git a/examples/webpack.config.js b/examples/webpack.config.js
new file mode 100644
index 0000000..aacb91d
--- /dev/null
+++ b/examples/webpack.config.js
@@ -0,0 +1,52 @@
+const path = require('path');
+const merge = require('webpack-merge');
+const glob = require('glob');
+
+const parts = require('./webpack.parts');
+
+const PATHS = {
+ app: path.join(__dirname, 'app'),
+ another: path.join(__dirname, 'another'),
+ build: path.join(__dirname, 'build')
+};
+
+module.exports = [
+ merge(
+ {
+ entry: {
+ app: PATHS.app
+ },
+ output: {
+ path: path.join(PATHS.build, 'first'),
+ filename: '[name].js'
+ }
+ },
+ parts.extractCSS(),
+ parts.purifyCSS({
+ verbose: true,
+ minimize: true,
+ paths: glob.sync(`${PATHS.app}/*`),
+ styleExtensions: ['.css']
+ })
+ ),
+ merge(
+ {
+ entry: {
+ first: PATHS.app,
+ second: PATHS.another
+ },
+ output: {
+ path: path.join(PATHS.build, 'second'),
+ filename: '[name].js'
+ }
+ },
+ parts.extractCSS(),
+ parts.purifyCSS({
+ paths: {
+ first: glob.sync(`${PATHS.app}/*`),
+ second: glob.sync(`${PATHS.another}/*`)
+ },
+ styleExtensions: ['.css']
+ })
+ )
+];
diff --git a/examples/webpack.parts.js b/examples/webpack.parts.js
new file mode 100644
index 0000000..4933b1f
--- /dev/null
+++ b/examples/webpack.parts.js
@@ -0,0 +1,30 @@
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+const PurifyCSSPlugin = require('../');
+
+exports.extractCSS = function extractCSS(paths) {
+ return {
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ include: paths,
+ loader: ExtractTextPlugin.extract({
+ fallbackLoader: 'style-loader',
+ loader: 'css-loader?sourceMap'
+ })
+ }
+ ]
+ },
+ plugins: [
+ new ExtractTextPlugin('[name].css?[hash]')
+ ]
+ };
+};
+
+exports.purifyCSS = function purifyCSS(options) {
+ return {
+ plugins: [
+ new PurifyCSSPlugin(options)
+ ]
+ };
+};
diff --git a/index.js b/index.js
deleted file mode 100644
index 3265401..0000000
--- a/index.js
+++ /dev/null
@@ -1,59 +0,0 @@
-var purify = require("purify-css");
-var glob = require("glob").sync;
-var path = require("path");
-var ConcatSource = require("webpack/lib/ConcatSource");
-
-module.exports = function PurifyPlugin(options) {
- // Store the user's options
- this.userOptions = options;
-}
-
-module.exports.prototype.apply = function(compiler) {
- // Keep a reference to self
- var self = this;
-
- // Bind the plugin into this compilation.
- compiler.plugin("this-compilation", function(compilation) {
- // WebPack options
- var wpOptions = compilation.compiler.options;
- // Base path
- self.basePath = self.userOptions.basePath || wpOptions.context || process.cwd();
- // Purify options
- self.purifyOptions = self.userOptions.purifyOptions || {
- minify: false,
- info: wpOptions.debug || false
- };
- self.purifyOptions.output = false;
- // Path/files to check. If none supplied, an empty array will do.
- self.paths = self.userOptions.paths || [];
- // Additional extensions to scan for. This is kept minimal, for obvious reasons.
- // We are not opinionated...
- self.resolveExtensions = self.userOptions.resolveExtensions || compiler.options.resolve.extensions;
-
- var files = self.paths.reduce(function(results, p) {
- return results.concat(glob(path.join(self.basePath, p)));
- }, []);
-
- compilation.plugin("additional-assets", function(cb){
- // Look for additional JS/HTML stuff.
- for(var key in compilation.fileDependencies) {
- var file = compilation.fileDependencies[key];
- var ext = path.extname(file);
- if (self.resolveExtensions.indexOf(ext) > -1) files.push(file);
- }
-
- // Look for purifyable CSs...
- for(var key in compilation.assets) {
- if(/\.css$/i.test(key)) {
- // We found a CSS. So purify it.
- var asset = compilation.assets[key];
- var css = asset.source();
- var newCss = new ConcatSource();
- newCss.add(purify(files, css, self.purifyOptions));
- compilation.assets[key] = newCss;
- }
- }
- cb();
- });
- });
-}
diff --git a/lib/post_install.js b/lib/post_install.js
new file mode 100644
index 0000000..8d6218c
--- /dev/null
+++ b/lib/post_install.js
@@ -0,0 +1,23 @@
+/* eslint-disable */
+// adapted based on rackt/history (MIT)
+// Node 4+
+var execSync = require('child_process').execSync;
+var stat = require('fs').stat;
+
+function exec(command) {
+ execSync(command, {
+ stdio: [0, 1, 2]
+ });
+}
+
+stat('dist', function(error, stat) {
+ // Skip building on Travis
+ if (process.env.TRAVIS) {
+ return;
+ }
+
+ if (error || !stat.isDirectory()) {
+ exec('npm i babel-cli babel-preset-es2015 babel-plugin-syntax-object-rest-spread babel-plugin-transform-object-rest-spread');
+ exec('npm run build');
+ }
+});
diff --git a/package.json b/package.json
index 585bbfd..cee2a3e 100644
--- a/package.json
+++ b/package.json
@@ -1,31 +1,86 @@
{
- "name": "bird3-purifycss-webpack-plugin",
- "version": "1.0.9",
- "description": "BIRD3's PurifyCSS WebPack plugin. Time to clean your styles!",
- "main": "index.js",
+ "name": "purifycss-webpack",
+ "version": "0.7.0",
+ "description": "PurifyCSS for webpack",
+ "main": "./dist",
"scripts": {
- "test": "echo 'No test command available, yet.' && exit 1"
+ "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: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"
},
"repository": {
"type": "git",
- "url": "git+https://github.com/DragonsInn/bird3-purifycss-webpack-plugin.git"
+ "url": "https://github.com/webpack-contrib/purifycss-webpack.git"
},
"keywords": [
- "purify-css",
- "purifycss",
"webpack",
+ "uncss",
"plugin",
- "purify",
- "css"
+ "purify"
],
- "author": "Ingwie Phoenix
+
+
+
+
+
+
+ Juho Vepsäläinen
+
+
+
+
+ Joshua Wiens
+
+
+
+
+ Kees Kluskens
+
+
+
+
+ Sean Larkin
+