silki
Version:
Cli tool for build react app, based on generator-react-multipage, create-react-app, roadhog. Support react multiple pages app develop.
221 lines (185 loc) • 6.38 kB
JavaScript
'use strict';
const Generators = require('yeoman-generator');
const fs = require('fs');
const path = require('path');
const utils = require('../../utils/all');
const prompts = require('./prompts');
const C = utils.constants;
const getAllSettingsFromComponentName = utils.yeoman.getAllSettingsFromComponentName;
const baseRootPath = path.join(__dirname, 'templates/independent');
class ComponentGenerator extends Generators.Base {
constructor(args, options) {
super(args, options);
/**
* Flag indicating whether the component should be created with associated style files.
* @type {boolean}
*/
this.useStyles = false;
/**
* Flag indicating whether the component should make use of css modules.
* @type {boolean}
*/
this.useCssModules = false;
/**
* A string to prepended to the `className` attribute of generated components.
* @type {string}
*/
this._cssClsPrefix = '';
/**
* Flag indicating if stateful components should extends from React.PureComponent
* @type {boolean}
*/
this.usePureComponent = false;
/**
* Filename of the template that will be used to create the component.
* @type {?string}
*/
this.componentTemplateName = null;
/**
* Generator and template version to create the component from.
* @type {?number}
*/
this.generatorVersion = null;
this.argument('name', { type: String, required: true });
this.option('stateless', {
desc: 'Create a stateless component instead of a full one',
defaults: false
});
this.option('nostyle', {
desc: 'Create a component without creating an associated style',
defaults: false
});
this.option('pure', {
desc: 'Create a pure component instead of a "regular" one. Will use React.PureComponent as a base instead of React.Component',
defaults: false
});
}
get cssClsPrefix() {
return this._cssClsPrefix;
}
set cssClsPrefix(val) {
this._cssClsPrefix = (val === '') ? '' : `${val}-`;
}
prompting() {
return this.prompt(prompts).then((answers) => {
// Set needed keys into config
this.type = answers.type;
});
}
configuring() {
// Read the requested major version or default it to the latest stable
this.generatorVersion = this.config.get('generatedWithVersion') || 3;
if (!C.SUPPORTED_GEN_VERSIONS.some(x => x === this.generatorVersion)) {
this.env.error('Unsupported generator version');
}
this.useStyles = !this.options.nostyle;
this.useCssModules = this.config.get('cssmodules') || false;
this.cssClsPrefix = this.config.get('cssClsPrefix') || '';
// Make sure we don't try to use template v3 with cssmodules
//if (this.generatorVersion < 4 && this.useStyles && this.useCssModules) {
// this.env.error('Creating components with cssmodules is only supported in generator versions 4+');
//}
// Get the filename of the component template to be copied during this run
this.componentTemplateName =
utils.yeoman.getComponentTemplateName(this.options.stateless, this.useStyles, false);
}
writing() {
const settings =
getAllSettingsFromComponentName(
this.name,
this.config.get('style'),
this.useCssModules,
this.options.pure,
this.generatorVersion,
this.cssClsPrefix
);
settings.cpntName = this.name;
console.log('this.type:', this.type);
const independent = this.type == 'independent';
if (independent) {
const excludeList = [
'LICENSE',
'CHANGELOG.md',
'node_modules',
'.istanbul.yml',
'.travis.yml'
];
const tplList = [
'README.md',
'package.json'
];
const srcTplList = [
'src/index.js',
'src/index.less',
'src/index.test.js'
];
// Get all files in our repo and copy the ones we should
fs.readdir(baseRootPath, (err, items) => {
for(let item of items) {
// Skip the item if it is in our exclude list
if(excludeList.indexOf(item) !== -1) {
continue;
}
console.log(item);
// Copy all items to our root
let fullPath = path.join(baseRootPath, item);
if(fs.lstatSync(fullPath).isDirectory()) {
this.bulkDirectory(`./independent/${item}`, item);
} else {
if (tplList.indexOf(item) !== -1) {
this.fs.copyTpl(
this.templatePath(`./independent/${item}`),
this.destinationPath(item),
settings
);
} else {
this.copy(`./independent/${item}`, item);
}
}
}
});
srcTplList.map(item => {
this.fs.copyTpl(
this.templatePath(`./independent/${item}`),
this.destinationPath(item),
settings
);
});
} else {
const isPureRc = this.type == 'pure' ? true : false;
// Create the style template. Skipped if nostyle is set as command line flag
if(this.useStyles) {
this.fs.copyTpl(
this.templatePath('style.less'),
this.destinationPath('src/' + settings.style.fileName.split('/')[0] + '/index.less'),
settings
);
}
// Create the component
this.fs.copyTpl(
isPureRc ? this.templatePath('component-pure.js') : this.templatePath('component.js'),
this.destinationPath('src/' + settings.component.fileName.split('/')[0] + '/index.js'),
settings
);
// Create the demo
this.fs.copyTpl(
isPureRc ? this.templatePath('demo-pure.js') : this.templatePath('demo.js'),
this.destinationPath('src/' + settings.component.fileName.split('/')[0] + '/index.test.js'),
settings
);
// Create the README.md
this.fs.copyTpl(
this.templatePath('README.md'),
this.destinationPath('src/' + settings.component.fileName.split('/')[0] + '/README.md'),
settings
);
// Create the unit test
this.fs.copyTpl(
this.templatePath('test.js'),
this.destinationPath(settings.test.path + settings.test.fileName),
settings
);
}
}
}
module.exports = ComponentGenerator;