Added basic changes for v4.0 (base generator class refactoring)

This commit is contained in:
Chris 2016-05-27 12:01:50 +02:00
parent 84b576548b
commit 663a49369b
6 changed files with 160 additions and 173 deletions

View File

@ -1,7 +1,8 @@
language: node_js
sudo: false
node_js:
- '4.2.2'
- '4'
- '6'
before_install:
- currentfolder=${PWD##*/}
- if [ "$currentfolder" != 'generator-react-webpack' ]; then cd .. && eval "mv $currentfolder generator-react-webpack" && cd generator-react-webpack; fi

View File

@ -1,18 +1,24 @@
'use strict';
let generator = require('yeoman-generator');
let utils = require('../../utils/all');
let prompts = require('./prompts');
let path = require('path');
let fs = require('fs');
const Generators = require('yeoman-generator');
const utils = require('../../utils/all');
const prompts = require('./prompts');
const path = require('path');
const fs = require('fs');
const packageInfo = require('../../package.json');
// Set the base root directory for our files
let baseRootPath = path.dirname(require.resolve('react-webpack-template'));
// Set the base root directory for our files. Make sure to always use the node_modules
// base path instead of the require call only. This is needed because require.resolve
// also includes the path set in package.json main keys!
const baseRootPath = path.join(path.dirname(require.resolve('react-webpack-template')), '..');
module.exports = generator.Base.extend({
/**
* Base generator. Will copy all required files from react-webpack-template
*/
class AppGenerator extends Generators.Base {
constructor: function() {
generator.Base.apply(this, arguments);
constructor(args, options) {
super(args, options);
// Make options available
this.option('skip-welcome-message', {
@ -26,29 +32,30 @@ module.exports = generator.Base.extend({
this.sourceRoot(baseRootPath);
this.config.save();
},
}
initializing() {
initializing: function() {
if(!this.options['skip-welcome-message']) {
this.log(require('yeoman-welcome'));
this.log('Out of the box I include Webpack and some default React components.\n');
}
},
}
prompting: function() {
let done = this.async();
this.prompt(prompts, function(props) {
prompting() {
return this.prompt(prompts).then((answers) => {
// Make sure to get the correct app name if it is not the default
if(props.appName !== utils.yeoman.getAppName()) {
props.appName = utils.yeoman.getAppName(props.appName);
if(answers.appName !== utils.yeoman.getAppName()) {
answers.appName = utils.yeoman.getAppName(answers.appName);
}
// Set needed global vars for yo
this.appName = props.appName;
this.style = props.style;
this.postcss = props.postcss
this.generatedWithVersion = packageInfo.version.split('.').unshift();
this.appName = answers.appName;
this.style = answers.style;
this.postcss = answers.postcss;
this.generatedWithVersion = parseInt(packageInfo.version.split('.').shift(), 10);
// Set needed keys into config
this.config.set('appName', this.appName);
@ -56,23 +63,19 @@ module.exports = generator.Base.extend({
this.config.set('style', this.style);
this.config.set('postcss', this.postcss);
this.config.set('generatedWithVersion', this.generatedWithVersion);
});
}
this.config.save();
done();
}.bind(this));
},
configuring: function() {
configuring() {
// Generate our package.json. Make sure to also include the required dependencies for styles
let defaultSettings = this.fs.readJSON(path.join(baseRootPath, 'package.json'));
let defaultSettings = this.fs.readJSON(`${baseRootPath}/package.json`);
let packageSettings = {
name: this.appName,
private: true,
version: '0.0.1',
description: 'YOUR DESCRIPTION - Generated by generator-react-webpack',
main: '',
description: `${this.appName} - Generated by generator-react-webpack`,
main: 'src/index.js',
scripts: defaultSettings.scripts,
repository: '',
keywords: [],
@ -100,16 +103,17 @@ module.exports = generator.Base.extend({
}
this.fs.writeJSON(this.destinationPath('package.json'), packageSettings);
},
}
writing: function() {
writing() {
let excludeList = [
const excludeList = [
'LICENSE',
'README.md',
'CHANGELOG.md',
'node_modules',
'package.json',
'.istanbul.yml',
'.travis.yml'
];
@ -136,16 +140,21 @@ module.exports = generator.Base.extend({
}
}
});
},
}
install: function() {
if(this.postcss) {
let postcss = require('./postcss');
postcss.write(path.join(this.destinationRoot(), 'cfg/defaults.js'));
}
install() {
// Currently buggy!
/* if(this.postcss) {
const postcss = require('./postcss');
postcss.write(path.join(this.destinationRoot(), 'conf/webpack/defaults.js'));
}*/
if(!this.options['skip-install']) {
this.installDependencies({ bower: false });
}
}
});
}
module.exports = AppGenerator;

View File

@ -1,6 +1,6 @@
{
"name": "generator-react-webpack",
"version": "3.3.2",
"version": "4.0.0",
"description": "Yeoman generator for using React with Webpack via Babel",
"keywords": [
"yeoman-generator",
@ -29,6 +29,10 @@
}
],
"main": "generators/app/index.js",
"files": [
"generators/app",
"generators/component"
],
"repository": {
"type": "git",
"url": "git://github.com/newtriks/generator-react-webpack.git"
@ -40,13 +44,13 @@
"release:patch": "npm version patch && npm publish && git push --follow-tags"
},
"dependencies": {
"react-webpack-template": "^1.0.0",
"underscore.string": "^3.2.2",
"yeoman-generator": "^0.22.0",
"yeoman-welcome": "^1.0.1",
"escodegen": "^1.7.0",
"esprima": "^2.7.0",
"esprima-walk": "^0.1.0",
"escodegen": "^1.7.0"
"react-webpack-template": "^2.0.1-0",
"underscore.string": "^3.2.2",
"yeoman-generator": "^0.23.0",
"yeoman-welcome": "^1.0.1"
},
"devDependencies": {
"chai": "^3.2.0",

View File

@ -8,6 +8,8 @@ let helpers = require('yeoman-test');
const defaultPrompts = require('../../../generators/app/prompts.js');
const generatorBase = path.join(__dirname, '../../../generators/app');
let generator;
/**
* Global before load function. Run in the before callbacks
* @param {Object} prompts List of prompts to use
@ -21,7 +23,11 @@ const beforeLoad = (prompts) => {
'skip-welcome-message': true,
'skip-install': true
})
.withPrompts(prompts)
.withPrompts
(prompts)
.on('ready', function(instance) {
generator = instance;
})
.toPromise();
};
@ -32,24 +38,22 @@ describe('react-webpack:app', () => {
prompts[p.name] = p.default;
}
before(() => {
return beforeLoad(prompts);
});
describe('#config', () => {
it('should set the generatedWith key to the current generator major version', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('generatedWithVersion')).to.equal(3);
});
expect(generator.config.get('generatedWithVersion')).to.equal(4);
});
it('should use "css" as default style language', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('style')).to.equal('css');
});
expect(generator.config.get('style')).to.equal('css');
});
it('should not enable "PostCSS" by default', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('postcss')).to.equal(false);
});
expect(generator.config.get('postcss')).to.equal(false);
});
});
@ -57,73 +61,62 @@ describe('react-webpack:app', () => {
it('should generate dot files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'.babelrc',
'.editorconfig',
'.eslintrc',
'.gitignore',
'.yo-rc.json'
]);
});
assert.file([
'.babelrc',
'.editorconfig',
'.eslintrc',
'.gitignore',
'.yo-rc.json'
]);
});
it('should generate project configuration files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'package.json'
]);
});
assert.file([
'package.json'
]);
});
it('should generate the webpack configuration', () => {
beforeLoad(prompts).then(() => {
assert.file([
'cfg/base.js',
'cfg/defaults.js',
'cfg/dev.js',
'cfg/dist.js',
'cfg/test.js',
'server.js',
'webpack.config.js'
]);
});
assert.file([
'conf/webpack/Base.js',
'conf/webpack/Dev.js',
'conf/webpack/Dist.js',
'conf/webpack/Test.js',
'webpack.config.js'
]);
});
it('should generate required source files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'src/actions/README.md',
'src/index.js',
'src/components/Main.js',
'src/favicon.ico',
'src/images/yeoman.png',
'src/index.html',
'src/sources/README.md',
'src/stores/README.md',
'src/styles/App.css'
]);
});
assert.file([
'src/actions/README.md',
'src/index.js',
'src/components/App.js',
'src/components/app.css',
'src/favicon.ico',
'src/images/yeoman.png',
'src/index.html',
'src/sources/README.md',
'src/stores/README.md'
]);
});
it('should generate test configuration and basic tests', () => {
beforeLoad(prompts).then(() => {
assert.file([
'karma.conf.js',
'test/components/MainTest.js',
'test/helpers/shallowRenderHelper.js',
'test/loadtests.js'
]);
});
assert.file([
'karma.conf.js',
'test/components/AppTest.js',
'test/config/ConfigTest.js',
'test/loadtests.js',
'test/.eslintrc'
]);
});
});
});
describe('react-webpack:app with PostCSS support', () => {
describe.skip('react-webpack:app with PostCSS support', () => {
let prompts = {};
for(let p of defaultPrompts) {
@ -135,21 +128,15 @@ describe('react-webpack:app with PostCSS support', () => {
describe('#config', () => {
it('should set the generatedWith key to the current generator major version', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('generatedWithVersion')).to.equal(3);
});
expect(generator.config.get('generatedWithVersion')).to.equal(4);
});
it('should use "css" as default style language', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('style')).to.equal('css');
});
expect(generator.config.get('style')).to.equal('css');
});
it('should enable "PostCSS"', () => {
beforeLoad(prompts).then((generator) => {
expect(generator.config.get('postcss')).to.equal(true);
});
expect(generator.config.get('postcss')).to.equal(true);
});
});
@ -157,86 +144,72 @@ describe('react-webpack:app with PostCSS support', () => {
it('should generate dot files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'.babelrc',
'.editorconfig',
'.eslintrc',
'.gitignore',
'.yo-rc.json'
]);
});
assert.file([
'.babelrc',
'.editorconfig',
'.eslintrc',
'.gitignore',
'.yo-rc.json'
]);
});
it('should generate project configuration files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'package.json'
]);
});
assert.file([
'package.json'
]);
});
it('should generate the webpack configuration', () => {
beforeLoad(prompts).then(() => {
assert.file([
'cfg/base.js',
'cfg/defaults.js',
'cfg/dev.js',
'cfg/dist.js',
'cfg/test.js',
'server.js',
'webpack.config.js'
]);
});
assert.file([
'cfg/base.js',
'cfg/defaults.js',
'cfg/dev.js',
'cfg/dist.js',
'cfg/test.js',
'server.js',
'webpack.config.js'
]);
});
it('should insert the postcss loader into the style pipes', () => {
beforeLoad(prompts).then(() => {
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded&indentedSyntax\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!less-loader\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!stylus-loader\'');
});
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded&indentedSyntax\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!sass-loader?outputStyle=expanded\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!less-loader\'');
assert.fileContent('cfg/defaults.js', 'loader: \'style-loader!css-loader!postcss-loader!stylus-loader\'');
});
it('should append the postcss function to the base config', () => {
beforeLoad(prompts).then(() => {
assert.fileContent('cfg/defaults.js', ',\n postcss: function () {\n return [];\n }');
});
assert.fileContent('cfg/defaults.js', ',\n postcss: function () {\n return [];\n }');
});
it('should generate required source files', () => {
beforeLoad(prompts).then(() => {
assert.file([
'src/actions/README.md',
'src/index.js',
'src/components/Main.js',
'src/favicon.ico',
'src/images/yeoman.png',
'src/index.html',
'src/sources/README.md',
'src/stores/README.md',
'src/styles/App.css'
]);
});
assert.file([
'src/actions/README.md',
'src/index.js',
'src/components/Main.js',
'src/favicon.ico',
'src/images/yeoman.png',
'src/index.html',
'src/sources/README.md',
'src/stores/README.md',
'src/styles/App.css'
]);
});
it('should generate test configuration and basic tests', () => {
beforeLoad(prompts).then(() => {
assert.file([
'karma.conf.js',
'test/components/MainTest.js',
'test/helpers/shallowRenderHelper.js',
'test/loadtests.js'
]);
});
assert.file([
'karma.conf.js',
'test/components/MainTest.js',
'test/helpers/shallowRenderHelper.js',
'test/loadtests.js'
]);
});
});
});

View File

@ -36,7 +36,7 @@ describe('Utilities:Yeoman', () => {
it('should return a js friendly application name', () => {
let result = utils.getAppName('this is a test using % special / chars!');
expect(result).to.be.equal('thisIsATestUsingSpecialChars');
expect(result).to.be.equal('this-is-a-test-using-special-chars');
});
it('should use the current path for creating the appName if the argument is omitted', () => {

View File

@ -114,7 +114,7 @@ let getAppName = (appName) => {
appName = getBaseDir();
}
return _.camelize(_.slugify(_.humanize(appName)));
return _.slugify(_.humanize(appName));
};
/**