From bdfbc11af15440a3f0df09251c32617b87091943 Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Tue, 5 Jun 2018 16:05:31 -0400 Subject: [PATCH 1/2] feat: postcss support --- generators/app/constants.js | 1 + generators/app/index.js | 11 ++ generators/app/package-json.js | 23 ++++ .../app/templates/scripts/_postcss.config.js | 14 ++ .../templates/scripts/_postcss.min.config.js | 12 ++ generators/app/templates/src/_plugin.css | 13 ++ generators/app/templates/test/_karma.conf.js | 1 + package-lock.json | 126 +++++------------- package.json | 5 + test/app.test.js | 81 ++++------- test/libs.js | 6 + 11 files changed, 151 insertions(+), 142 deletions(-) create mode 100644 generators/app/templates/scripts/_postcss.config.js create mode 100644 generators/app/templates/scripts/_postcss.min.config.js create mode 100644 generators/app/templates/src/_plugin.css diff --git a/generators/app/constants.js b/generators/app/constants.js index 24033370..18b458c0 100644 --- a/generators/app/constants.js +++ b/generators/app/constants.js @@ -50,6 +50,7 @@ module.exports = { PROMPT_DEFAULTS: { docs: false, + css: false, husky: 'lint', lang: false, license: LICENSE_DEFAULT, diff --git a/generators/app/index.js b/generators/app/index.js index c67f5324..465c8c6c 100644 --- a/generators/app/index.js +++ b/generators/app/index.js @@ -143,6 +143,11 @@ module.exports = yeoman.generators.Base.extend({ message: 'Choose a type for your plugin', default: defaults.pluginType, choices: constants.PLUGIN_TYPE_CHOICES + }, { + type: 'confirm', + name: 'css', + message: 'Do you want to use css tooling?', + default: defaults.css }, { type: 'confirm', name: 'docs', @@ -285,6 +290,12 @@ module.exports = yeoman.generators.Base.extend({ if (this.context.lang) { this._filesToCopy.push('lang/_en.json'); } + + if (this.context.css) { + this._templatesToCopy.push('src/_plugin.css'); + this._templatesToCopy.push('scripts/_postcss.config.js'); + this._templatesToCopy.push('scripts/_postcss.min.config.js'); + } }, /** diff --git a/generators/app/package-json.js b/generators/app/package-json.js index 2ac13d78..3d44d261 100644 --- a/generators/app/package-json.js +++ b/generators/app/package-json.js @@ -253,6 +253,29 @@ const packageJSON = (current, context) => { _.assign(result.devDependencies, getGeneratorVersions(['doctoc', 'jsdoc'])); } + if (context.css) { + + _.assign(result.scripts, { + 'build:css': 'npm-run-all build:css:postcss build:css:minify', + 'build:css:postcss': 'postcss --config scripts/postcss.config.js', + 'build:css:minify': 'postcss --config scripts/postcss.min.config.js', + 'watch:css': 'npm run build:css:postcss -- -w' + }); + + if (context.husky !== 'none') { + result.scripts.precommit = 'npm run docs:toc && git add README.md'; + } + + _.assign(result.devDependencies, getGeneratorVersions([ + 'postcss-cli', + 'postcss-banner', + 'postcss-import', + 'autoprefixer', + 'cssnano' + ])); + + } + // Include language support. Note that `mkdirs` does not need to change // here because the videojs-languages package will create the destination // directory if needed. diff --git a/generators/app/templates/scripts/_postcss.config.js b/generators/app/templates/scripts/_postcss.config.js new file mode 100644 index 00000000..c7dff58d --- /dev/null +++ b/generators/app/templates/scripts/_postcss.config.js @@ -0,0 +1,14 @@ +const banner = require('./banner'); +const path = require('path'); + +module.exports = function(context) { + return { + from: path.join(__dirname, '..', 'src', 'plugin.css'), + to: path.join(__dirname, '..', 'dest', '<%= pluginName %>.css'), + plugins: [ + require('postcss-banner')({important: true, banner}), + require('postcss-import')(), + require('autoprefixer')(['defaults', 'ie11']), + ] + } +} diff --git a/generators/app/templates/scripts/_postcss.min.config.js b/generators/app/templates/scripts/_postcss.min.config.js new file mode 100644 index 00000000..01b0c3b9 --- /dev/null +++ b/generators/app/templates/scripts/_postcss.min.config.js @@ -0,0 +1,12 @@ +const banner = require('./banner'); +const path = require('path'); + +module.exports = function(context) { + return { + from: path.join(__dirname, '..', 'dest', '<%= pluginName %>.css'), + to: path.join(__dirname, '..', 'dest', '<%= pluginName %>.min.css'), + plugins: [ + require('cssnano')({safe: true}), + ] + } +} diff --git a/generators/app/templates/src/_plugin.css b/generators/app/templates/src/_plugin.css new file mode 100644 index 00000000..3b975a4a --- /dev/null +++ b/generators/app/templates/src/_plugin.css @@ -0,0 +1,13 @@ +// css for <%= pluginName %> +// postcss allows you to +// - @import relative files, they will be inlined during build +// - not have to worry about prefixes, as the last 2 versions of all major browsers +// and ie 11 will be automatically prefixed + +.video-js { + + // This class is added to the video.js element by the plugin by default. + &.<%= className %> { + display: block; + } +} diff --git a/generators/app/templates/test/_karma.conf.js b/generators/app/templates/test/_karma.conf.js index 73b40f2f..19e412ea 100644 --- a/generators/app/templates/test/_karma.conf.js +++ b/generators/app/templates/test/_karma.conf.js @@ -20,6 +20,7 @@ module.exports = function(config) { frameworks: ['qunit', 'detectBrowsers'], files: [ 'node_modules/video.js/dist/video-js.css', + <% if (css) { %><% } %> 'node_modules/sinon/pkg/sinon.js', 'node_modules/video.js/dist/video.js', 'test/dist/bundle.js' diff --git a/package-lock.json b/package-lock.json index aed4396e..97ddf4f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -685,21 +685,21 @@ } }, "conventional-changelog": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-2.0.0.tgz", - "integrity": "sha512-hbwyYn7uZJ2IB7o/h9xGVQeoNzdpZn+eQZ31GSh/S8tj3eEzdJcOInnMBQU6l+207pQ3bEZzjU3ZVehH2Mnuqw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-2.0.1.tgz", + "integrity": "sha512-WeWcEcR7uBtRZ/uG6DRIlVqsm7UTnxrixaAPoPvfQP7FRPf1qIXL76nGKy4wXq+wO3zOpqYubWUqrYLIL3+xww==", "dev": true, "requires": { "conventional-changelog-angular": "1.6.6", - "conventional-changelog-atom": "1.0.0", - "conventional-changelog-codemirror": "1.0.0", + "conventional-changelog-atom": "2.0.0", + "conventional-changelog-codemirror": "2.0.0", "conventional-changelog-core": "3.0.0", - "conventional-changelog-ember": "1.0.0", - "conventional-changelog-eslint": "2.0.0", - "conventional-changelog-express": "1.0.0", + "conventional-changelog-ember": "2.0.0", + "conventional-changelog-eslint": "3.0.0", + "conventional-changelog-express": "2.0.0", "conventional-changelog-jquery": "0.1.0", "conventional-changelog-jscs": "0.1.0", - "conventional-changelog-jshint": "1.0.0", + "conventional-changelog-jshint": "2.0.0", "conventional-changelog-preset-loader": "2.0.0" } }, @@ -714,22 +714,22 @@ } }, "conventional-changelog-atom": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-1.0.0.tgz", - "integrity": "sha512-HswSKDz4+fHc832OczcgGrsWEnMkjjFc3xuvNcG/HsBxwL6+gFhhSmPjAWrZuJt/YuVmtiEK5S/W4rakLEoJqw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.0.tgz", + "integrity": "sha512-ygwkwyTQYAm4S0tsDt+1yg8tHhRrv7qu9SOWPhNQlVrInFLsfKc0FActCA3de2ChknxpVPY2B53yhKvCAtkBCg==", "dev": true, "requires": { "q": "1.5.1" } }, "conventional-changelog-cli": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-2.0.0.tgz", - "integrity": "sha512-tFLPdjlPBqH2XOdoFBHj/O1lbNdK6A+LfL0jzNUP+J3mEFSyGL3T+6F6/jansPQOmm1GVNhlo9OO3BYF0nr/4w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-cli/-/conventional-changelog-cli-2.0.1.tgz", + "integrity": "sha512-gQzMbLyPNYymbzJncJNBapLZTXEtXrq6qmQOJH0w/jVX9fxIli4sLalQgzEPjD7M1noLJd1cIdQAP1R++TkGxg==", "dev": true, "requires": { "add-stream": "1.0.0", - "conventional-changelog": "2.0.0", + "conventional-changelog": "2.0.1", "lodash": "4.17.10", "meow": "4.0.1", "tempfile": "1.1.1" @@ -879,9 +879,9 @@ } }, "conventional-changelog-codemirror": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-1.0.0.tgz", - "integrity": "sha512-OchwAltFTS4jyLsAO21YsJazMlTuRRCawEeq7jq1t6vQR08DNNdeMYfcddWVD++d9a+coZEYqIQ0wDtoeFpVLA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.0.tgz", + "integrity": "sha512-pZt/YynJ5m8C9MGV5wkBuhM1eX+8a84fmNrdOylxg/lJV+lgtAiNhnpskNuixtf71iKVWSlEqMQ6z6CH7/Uo5A==", "dev": true, "requires": { "q": "1.5.1" @@ -917,27 +917,27 @@ } }, "conventional-changelog-ember": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-1.0.0.tgz", - "integrity": "sha512-5yT3hXNgy0VrAsUjKMUq2khlHeRmusglGligAcF+WRlzdI95bBPKgBT5r6UJ/D9vsITgMb7SnNUlknvFl6HgEw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.0.tgz", + "integrity": "sha512-s9ZYf3VMdYe8ca8bw1X+he050HZNy9Pm3dBpYA+BunDGFE4Fy7whOvYhWah2U9+j9l6y/whfa0+eHANvZytE9A==", "dev": true, "requires": { "q": "1.5.1" } }, "conventional-changelog-eslint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-2.0.0.tgz", - "integrity": "sha512-8qzbgeHXOCf1XNDSNivBjmpeDd+OJeHsEbqipryO86VHGVOoJ9WYNWYG2Bc0c7mWMD4oNadNBg1JkXs82uZ1tQ==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.0.tgz", + "integrity": "sha512-Acn20v+13c+o1OAWKvc9sCCl73Nj2vOMyn+G82euiMZwgYNE9CcBkTnw/GKdBi9KiZMK9uy+SCQ/QyAEE+8vZA==", "dev": true, "requires": { "q": "1.5.1" } }, "conventional-changelog-express": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-1.0.0.tgz", - "integrity": "sha512-OMFBXTPiYbuJFOCgy5yzSTG7+wBtumGy/w7m8ts19ePcP+Zd7NSINgrexw0oNsVtgFDT7kbBpaIhUYoquRR35Q==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.0.tgz", + "integrity": "sha512-2svPjeXCrjwwqnzu/f3qU5LWoLO0jmUIEbtbbSRXAAP9Ag+137b484eJsiRt9DPYXSVzog0Eoek3rvCzfHcphQ==", "dev": true, "requires": { "q": "1.5.1" @@ -962,9 +962,9 @@ } }, "conventional-changelog-jshint": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-1.0.0.tgz", - "integrity": "sha512-TZSCzg+cmzkJjV6paBBO26g6P0cy+jVTQq3rm2Y4IvNGjCpOkR3lrJPEXcPV3vszIvC5CENBv+PCmwIiD1u/0g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.0.tgz", + "integrity": "sha512-+4fCln755N0ZzRUEdcDWR5Due71Dsqkbov6K/UmVCnljZvhVh0/wpT4YROoSsAnhfZO8shyWDPFKm6EP20pLQg==", "dev": true, "requires": { "compare-func": "1.3.2", @@ -2348,7 +2348,8 @@ "exit": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=" + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true }, "exit-hook": { "version": "1.1.1", @@ -2580,11 +2581,6 @@ "write": "0.2.1" } }, - "flatten": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz", - "integrity": "sha1-VURAdm2goNYDmZ9DNFP2wvxqdcE=" - }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", @@ -4755,9 +4751,9 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-limit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", "dev": true, "requires": { "p-try": "1.0.0" @@ -4769,7 +4765,7 @@ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", "dev": true, "requires": { - "p-limit": "1.2.0" + "p-limit": "1.3.0" } }, "p-try": { @@ -5878,54 +5874,6 @@ "unist-util-stringify-position": "1.1.2" } }, - "videojs-languages": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/videojs-languages/-/videojs-languages-1.0.0.tgz", - "integrity": "sha1-PBX30beXHmkjbwJznctdRktC+3k=", - "requires": { - "cli": "0.11.3", - "flatten": "0.0.1", - "globby": "4.1.0", - "mkdirp": "0.5.1" - }, - "dependencies": { - "cli": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/cli/-/cli-0.11.3.tgz", - "integrity": "sha1-ewzT3pkORSklZnwNuv/cn38qmhU=", - "requires": { - "exit": "0.1.2", - "glob": "7.1.2" - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - } - } - }, "videojs-standard": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/videojs-standard/-/videojs-standard-6.0.1.tgz", diff --git a/package.json b/package.json index 4eebd1fe..d45e8f0c 100644 --- a/package.json +++ b/package.json @@ -51,10 +51,12 @@ "videojs-standard": "^6.0.0" }, "optionalDependencies": { + "autoprefixer": "^8.6.0", "babel-plugin-external-helpers": "^6.22.0", "babel-plugin-transform-object-assign": "^6.22.0", "babel-preset-es2015": "^6.24.1", "bannerize": "^1.1.3", + "cssnano": "^3.10.0", "global": "^4.3.2", "in-publish": "^2.0.0", "jsdoc": "^3.4.3", @@ -69,6 +71,9 @@ "node-static": "^0.7.10", "npm-run-all": "^4.1.2", "portscanner": "^2.1.1", + "postcss-banner": "^3.0.0", + "postcss-cli": "^5.0.0", + "postcss-import": "^11.1.0", "qunit": "^2.5.1", "rimraf": "^2.6.2", "rollup": "^0.53.4", diff --git a/test/app.test.js b/test/app.test.js index 00027ef7..f6c4c4fc 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -11,7 +11,6 @@ const helpers = require('yeoman-generator').test; const libs = require('./libs'); const packageJSON = require('../generators/app/package-json'); const generatorVersion = require('../generators/app/generator-version'); -const generatorPkg = require('../package.json'); describe('videojs-plugin:app', function() { const scripts = [ @@ -63,56 +62,6 @@ describe('videojs-plugin:app', function() { it('creates common default set of files', function() { libs.fileList('common', 'oss').forEach(f => assert.file(f)); }); - - it('creates the expected plugin.js contents', function() { - assert.fileContent('src/plugin.js', /class Wat extends Plugin/); - }); - - }); - - describe('basic', function() { - - before(function(done) { - helpers.run(libs.GENERATOR_PATH) - .withOptions(libs.options()) - .withPrompts({ - name: 'wat', - author: 'John Doe', - description: 'wat is the plugin', - pluginType: 'basic' - }) - .on('end', () => libs.onEnd(this, done)); - }); - - it('sets basic package properties', function() { - const p = this.pkg; - - assert.strictEqual(p.author, 'John Doe'); - assert.strictEqual(p.license, 'MIT'); - assert.strictEqual(p.name, 'videojs-wat'); - assert.strictEqual(p.description, 'wat is the plugin'); - assert.strictEqual(p.version, '0.0.0'); - assert.strictEqual(p.main, 'dist/videojs-wat.cjs.js'); - assert.strictEqual(p.module, 'dist/videojs-wat.es.js'); - assert.ok(_.isArray(p.keywords)); - assert.ok(_.isPlainObject(p.vjsstandard)); - assert.ok(_.isPlainObject(p.devDependencies)); - assert.strictEqual(p.scripts.prepush, 'npm run lint'); - assert.ok(_.isPlainObject(p['generator-videojs-plugin'])); - assert.strictEqual(p['generator-videojs-plugin'].version, generatorVersion()); - }); - - it('has all scripts, even if they are empty', function() { - libs.allAreNonEmpty(this.pkg.scripts, scripts); - }); - - it('creates common default set of files', function() { - libs.fileList('common', 'oss').forEach(f => assert.file(f)); - }); - - it('creates the expected plugin.js contents', function() { - assert.fileContent('src/plugin.js', /const wat = function/); - }); }); describe('scoped package support', function() { @@ -206,6 +155,33 @@ describe('videojs-plugin:app', function() { }); }); + describe('css', function() { + before(function(done) { + helpers.run(libs.GENERATOR_PATH) + .withOptions(libs.options()) + .withPrompts({ + name: 'wat', + author: 'John Doe', + description: 'wat is the plugin', + css: true + }) + .on('end', () => libs.onEnd(this, done)); + }); + + it('populates otherwise empty npm scripts', function() { + libs.allAreNonEmpty(this.pkg.scripts, scripts.concat([ + 'build:css', + 'build:css:postcss', + 'build:css:minify', + 'watch:css' + ])); + }); + + it('creates css specific files default set of files', function() { + libs.fileList('common', 'oss', 'css').forEach(f => assert.file(f)); + }); + }); + describe('existing package.json with author object', function() { before(function(done) { @@ -273,8 +249,7 @@ describe('videojs-plugin:app', function() { className: 'vjs-test', description: 'This is the description', docs: false, - pluginFunctionName: 'test', - pluginClassName: 'Test', + functionName: 'test', isPrivate: false, lang: false, licenseName: 'MIT', diff --git a/test/libs.js b/test/libs.js index 01c0e13d..be1b274f 100644 --- a/test/libs.js +++ b/test/libs.js @@ -37,6 +37,12 @@ const FILES = { docs: [ 'jsdoc.json' + ], + + css: [ + 'src/plugin.css', + 'scripts/postcss.config.js', + 'scripts/postcss.min.config.js' ] }; From 61d49c333b3f3e2d1c625ac5b21436f499a775f8 Mon Sep 17 00:00:00 2001 From: brandonocasey Date: Wed, 6 Jun 2018 14:21:20 -0400 Subject: [PATCH 2/2] finished --- generators/app/index.js | 3 +- generators/app/package-json.js | 6 +- generators/app/templates/scripts/_banner.js | 8 +++ .../app/templates/scripts/_postcss.config.js | 35 ++++++++++-- .../templates/scripts/_postcss.min.config.js | 12 ---- generators/app/templates/src/_plugin.css | 12 ++-- test/app.test.js | 57 ++++++++++++++++++- test/libs.js | 5 +- 8 files changed, 104 insertions(+), 34 deletions(-) create mode 100644 generators/app/templates/scripts/_banner.js delete mode 100644 generators/app/templates/scripts/_postcss.min.config.js diff --git a/generators/app/index.js b/generators/app/index.js index 465c8c6c..4c98acef 100644 --- a/generators/app/index.js +++ b/generators/app/index.js @@ -217,7 +217,7 @@ module.exports = yeoman.generators.Base.extend({ '_.gitignore', '_.npmignore', '_.nvmrc', - 'scripts/_banner.ejs', + 'scripts/_banner.js', 'scripts/_server.js', 'scripts/_version.js' ]; @@ -294,7 +294,6 @@ module.exports = yeoman.generators.Base.extend({ if (this.context.css) { this._templatesToCopy.push('src/_plugin.css'); this._templatesToCopy.push('scripts/_postcss.config.js'); - this._templatesToCopy.push('scripts/_postcss.min.config.js'); } }, diff --git a/generators/app/package-json.js b/generators/app/package-json.js index 3d44d261..580bb4d4 100644 --- a/generators/app/package-json.js +++ b/generators/app/package-json.js @@ -256,10 +256,8 @@ const packageJSON = (current, context) => { if (context.css) { _.assign(result.scripts, { - 'build:css': 'npm-run-all build:css:postcss build:css:minify', - 'build:css:postcss': 'postcss --config scripts/postcss.config.js', - 'build:css:minify': 'postcss --config scripts/postcss.min.config.js', - 'watch:css': 'npm run build:css:postcss -- -w' + 'build:css': 'postcss -o dist/videojs-test.css --config scripts/postcss.config.js src/plugin.css', + 'watch:css': 'npm run build:css -- -w' }); if (context.husky !== 'none') { diff --git a/generators/app/templates/scripts/_banner.js b/generators/app/templates/scripts/_banner.js new file mode 100644 index 00000000..66ada79b --- /dev/null +++ b/generators/app/templates/scripts/_banner.js @@ -0,0 +1,8 @@ +const pkg = require('../package.json'); + +const bannerString = `@name ${pkg.name} @version ${pkg.version} @copyright ${pkg.author} @license ${pkg.license}`; + +module.exports = { + string: bannerString, + comment: `/*! ${bannerString} */` +}; diff --git a/generators/app/templates/scripts/_postcss.config.js b/generators/app/templates/scripts/_postcss.config.js index c7dff58d..5263a332 100644 --- a/generators/app/templates/scripts/_postcss.config.js +++ b/generators/app/templates/scripts/_postcss.config.js @@ -1,14 +1,39 @@ const banner = require('./banner'); +const postcss = require('postcss'); const path = require('path'); +const fs = require('fs'); + +const browserList = ['defaults', 'ie 11']; + +/** + * A postcss plugin that should be run before minification plugins. + * it will write to the `to` from the command line with the current + * output. Then it will change the extension of the `to` from + * whatever it is to `.min.css` + */ +const unminifiedOutput = postcss.plugin('postcss-unminified-output', function(opts) { + opts = opts || {}; + + return function(root, result) { + fs.writeFileSync(result.opts.to, root.toString()); + + result.opts.to = result.opts.to.replace(path.extname(result.opts.to), '.min.css'); + }; +}); module.exports = function(context) { return { - from: path.join(__dirname, '..', 'src', 'plugin.css'), - to: path.join(__dirname, '..', 'dest', '<%= pluginName %>.css'), plugins: [ require('postcss-banner')({important: true, banner}), require('postcss-import')(), - require('autoprefixer')(['defaults', 'ie11']), + require('autoprefixer')(browserList), + unminifiedOutput(), + require('cssnano')({ + safe: true, + preset: ['default', { + autoprefixer: browserList + }] + }) ] - } -} + }; +}; diff --git a/generators/app/templates/scripts/_postcss.min.config.js b/generators/app/templates/scripts/_postcss.min.config.js deleted file mode 100644 index 01b0c3b9..00000000 --- a/generators/app/templates/scripts/_postcss.min.config.js +++ /dev/null @@ -1,12 +0,0 @@ -const banner = require('./banner'); -const path = require('path'); - -module.exports = function(context) { - return { - from: path.join(__dirname, '..', 'dest', '<%= pluginName %>.css'), - to: path.join(__dirname, '..', 'dest', '<%= pluginName %>.min.css'), - plugins: [ - require('cssnano')({safe: true}), - ] - } -} diff --git a/generators/app/templates/src/_plugin.css b/generators/app/templates/src/_plugin.css index 3b975a4a..6b8dd990 100644 --- a/generators/app/templates/src/_plugin.css +++ b/generators/app/templates/src/_plugin.css @@ -1,8 +1,10 @@ -// css for <%= pluginName %> -// postcss allows you to -// - @import relative files, they will be inlined during build -// - not have to worry about prefixes, as the last 2 versions of all major browsers -// and ie 11 will be automatically prefixed +/** + * css for <%= pluginName %> + * postcss allows you to + * - @import relative files, they will be inlined during build + * - not have to worry about prefixes, as the last 2 versions of all major browsers + * and ie 11 will be automatically prefixed + */ .video-js { diff --git a/test/app.test.js b/test/app.test.js index f6c4c4fc..fdbd2984 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -11,6 +11,7 @@ const helpers = require('yeoman-generator').test; const libs = require('./libs'); const packageJSON = require('../generators/app/package-json'); const generatorVersion = require('../generators/app/generator-version'); +const generatorPkg = require('../package.json'); describe('videojs-plugin:app', function() { const scripts = [ @@ -62,6 +63,56 @@ describe('videojs-plugin:app', function() { it('creates common default set of files', function() { libs.fileList('common', 'oss').forEach(f => assert.file(f)); }); + + it('creates the expected plugin.js contents', function() { + assert.fileContent('src/plugin.js', /class Wat extends Plugin/); + }); + + }); + + describe('basic', function() { + + before(function(done) { + helpers.run(libs.GENERATOR_PATH) + .withOptions(libs.options()) + .withPrompts({ + name: 'wat', + author: 'John Doe', + description: 'wat is the plugin', + pluginType: 'basic' + }) + .on('end', () => libs.onEnd(this, done)); + }); + + it('sets basic package properties', function() { + const p = this.pkg; + + assert.strictEqual(p.author, 'John Doe'); + assert.strictEqual(p.license, 'MIT'); + assert.strictEqual(p.name, 'videojs-wat'); + assert.strictEqual(p.description, 'wat is the plugin'); + assert.strictEqual(p.version, '0.0.0'); + assert.strictEqual(p.main, 'dist/videojs-wat.cjs.js'); + assert.strictEqual(p.module, 'dist/videojs-wat.es.js'); + assert.ok(_.isArray(p.keywords)); + assert.ok(_.isPlainObject(p.vjsstandard)); + assert.ok(_.isPlainObject(p.devDependencies)); + assert.strictEqual(p.scripts.prepush, 'npm run lint'); + assert.ok(_.isPlainObject(p['generator-videojs-plugin'])); + assert.strictEqual(p['generator-videojs-plugin'].version, generatorVersion()); + }); + + it('has all scripts, even if they are empty', function() { + libs.allAreNonEmpty(this.pkg.scripts, scripts); + }); + + it('creates common default set of files', function() { + libs.fileList('common', 'oss').forEach(f => assert.file(f)); + }); + + it('creates the expected plugin.js contents', function() { + assert.fileContent('src/plugin.js', /const wat = function/); + }); }); describe('scoped package support', function() { @@ -117,6 +168,7 @@ describe('videojs-plugin:app', function() { description: 'wat is the plugin', docs: true, lang: true, + css: true, husky: 'test' }) .on('end', () => libs.onEnd(this, done)); @@ -171,8 +223,6 @@ describe('videojs-plugin:app', function() { it('populates otherwise empty npm scripts', function() { libs.allAreNonEmpty(this.pkg.scripts, scripts.concat([ 'build:css', - 'build:css:postcss', - 'build:css:minify', 'watch:css' ])); }); @@ -249,7 +299,8 @@ describe('videojs-plugin:app', function() { className: 'vjs-test', description: 'This is the description', docs: false, - functionName: 'test', + pluginFunctionName: 'test', + pluginClassName: 'Test', isPrivate: false, lang: false, licenseName: 'MIT', diff --git a/test/libs.js b/test/libs.js index be1b274f..cd974f8d 100644 --- a/test/libs.js +++ b/test/libs.js @@ -9,7 +9,7 @@ const assert = require('yeoman-generator').assert; const FILES = { common: [ - 'scripts/banner.ejs', + 'scripts/banner.js', 'scripts/modules.rollup.config.js', 'scripts/test.rollup.config.js', 'scripts/umd.rollup.config.js', @@ -41,8 +41,7 @@ const FILES = { css: [ 'src/plugin.css', - 'scripts/postcss.config.js', - 'scripts/postcss.min.config.js' + 'scripts/postcss.config.js' ] };