diff --git a/generators/component/index.js b/generators/component/index.js index 79bfde9..05cb71b 100644 --- a/generators/component/index.js +++ b/generators/component/index.js @@ -1,12 +1,39 @@ 'use strict'; const Generators = require('yeoman-generator'); -let utils = require('../../utils/all'); +const utils = require('../../utils/all'); +const C = utils.constants; +const getAllSettingsFromComponentName = utils.yeoman.getAllSettingsFromComponentName; + 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; + + /** + * 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', { @@ -20,27 +47,37 @@ class ComponentGenerator extends Generators.Base { }); } - writing() { - // Set the template base. If it cannot be guessed, - // use files from the default directory. In this case, - // assume we have something REALLY REALLY old here... - let generatorVersion = this.config.get('generatedWithVersion'); - if(!generatorVersion) { - generatorVersion = 3; + 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'); } - const componentType = this.options.stateless ? 'Stateless' : 'Base'; - const componentHasStyles = !this.options.nostyle; + this.useStyles = !this.options.nostyle; + this.useCssModules = this.config.get('cssmodules') || false; - // Get the - const settings = utils.yeoman.getAllSettingsFromComponentName(this.name, this.config.get('style'), generatorVersion); - settings.componentHasStyles = componentHasStyles; + // 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, this.useCssModules); + } + + + writing() { + const settings = + getAllSettingsFromComponentName(this.name, this.config.get('style'), this.useCssModules, this.generatorVersion); // Create the style template. Skipped if nostyle is set as command line flag - if(componentHasStyles) { + if(this.useStyles) { this.fs.copyTpl( - this.templatePath(`${generatorVersion}/styles/Component${settings.style.suffix}`), + this.templatePath(`${this.generatorVersion}/styles/Component${settings.style.suffix}`), this.destinationPath(settings.style.path + settings.style.fileName), settings ); @@ -48,14 +85,14 @@ class ComponentGenerator extends Generators.Base { // Create the component this.fs.copyTpl( - this.templatePath(`${generatorVersion}/components/${componentType}.js`), + this.templatePath(`${this.generatorVersion}/components/${this.componentTemplateName}`), this.destinationPath(settings.component.path + settings.component.fileName), settings ); // Create the unit test this.fs.copyTpl( - this.templatePath(`${generatorVersion}/tests/Base.js`), + this.templatePath(`${this.generatorVersion}/tests/Base.js`), this.destinationPath(settings.test.path + settings.test.fileName), settings ); diff --git a/generators/component/templates/3/components/StatefulNoStyles.js b/generators/component/templates/3/components/StatefulNoStyles.js new file mode 100644 index 0000000..9eae5b0 --- /dev/null +++ b/generators/component/templates/3/components/StatefulNoStyles.js @@ -0,0 +1,21 @@ +'use strict'; + +import React from 'react'; + +class <%= component.className %> extends React.Component { + render() { + return ( +
+ Please edit <%= component.path %>/<%= component.fileName %> to update this component! +
+ ); + } +} + +<%= component.className %>.displayName = '<%= component.displayName %>'; + +// Uncomment properties you need +// <%= component.className %>.propTypes = {}; +// <%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/generators/component/templates/3/components/Base.js b/generators/component/templates/3/components/StatefulWithStyles.js similarity index 100% rename from generators/component/templates/3/components/Base.js rename to generators/component/templates/3/components/StatefulWithStyles.js diff --git a/generators/component/templates/3/components/StatelessNoStyles.js b/generators/component/templates/3/components/StatelessNoStyles.js new file mode 100644 index 0000000..f2ad07d --- /dev/null +++ b/generators/component/templates/3/components/StatelessNoStyles.js @@ -0,0 +1,17 @@ +'use strict'; + +import React from 'react'; + +let <%= component.className %> = () => ( +
+ Please edit <%= component.path %>/<%= component.fileName %> to update this component! +
+); + +<%= component.className %>.displayName = '<%= component.displayName %>'; + +// Uncomment properties you need +// <%= component.className %>.propTypes = {}; +// <%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/generators/component/templates/3/components/Stateless.js b/generators/component/templates/3/components/StatelessWithStyles.js similarity index 91% rename from generators/component/templates/3/components/Stateless.js rename to generators/component/templates/3/components/StatelessWithStyles.js index a73c647..7f85c2d 100644 --- a/generators/component/templates/3/components/Stateless.js +++ b/generators/component/templates/3/components/StatelessWithStyles.js @@ -4,7 +4,7 @@ import React from 'react'; require('<%= style.webpackPath %>'); -let <%= component.className %> = (props) => ( +let <%= component.className %> = () => (
Please edit <%= component.path %>/<%= component.fileName %> to update this component!
diff --git a/generators/component/templates/4/components/Base.js b/generators/component/templates/4/components/StatefulCssModules.js similarity index 61% rename from generators/component/templates/4/components/Base.js rename to generators/component/templates/4/components/StatefulCssModules.js index f0ebe8d..c4f57ec 100644 --- a/generators/component/templates/4/components/Base.js +++ b/generators/component/templates/4/components/StatefulCssModules.js @@ -1,9 +1,8 @@ -import React from 'react';<% if(componentHasStyles) { %> +import React from 'react'; import cssmodules from 'react-css-modules'; -import styles from '<%= style.webpackPath %>';<% } %> +import styles from '<%= style.webpackPath %>'; -<% if(componentHasStyles) { %>@cssmodules(styles) -<% } %>class <%= component.className %> extends React.Component { +class <%= component.className %> extends React.Component { render() { return ( @@ -18,4 +17,4 @@ import styles from '<%= style.webpackPath %>';<% } %> <%= component.className %>.propTypes = {}; <%= component.className %>.defaultProps = {}; -export default <%= component.className %>; +export default cssmodules(<%= component.className %>, styles); diff --git a/generators/component/templates/4/components/StatefulNoStyles.js b/generators/component/templates/4/components/StatefulNoStyles.js new file mode 100644 index 0000000..2773aaf --- /dev/null +++ b/generators/component/templates/4/components/StatefulNoStyles.js @@ -0,0 +1,18 @@ +import React from 'react'; + +class <%= component.className %> extends React.Component { + + render() { + return ( +
+ Please edit <%= component.path %><%= component.fileName %> to update this component! +
+ ); + } +} + +<%= component.className %>.displayName = '<%= component.displayName %>'; +<%= component.className %>.propTypes = {}; +<%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/generators/component/templates/4/components/StatefulWithStyles.js b/generators/component/templates/4/components/StatefulWithStyles.js new file mode 100644 index 0000000..8a291a1 --- /dev/null +++ b/generators/component/templates/4/components/StatefulWithStyles.js @@ -0,0 +1,19 @@ +import React from 'react'; +import '<%= style.webpackPath %>'; + +class <%= component.className %> extends React.Component { + + render() { + return ( +
+ Please edit <%= component.path %><%= component.fileName %> to update this component! +
+ ); + } +} + +<%= component.className %>.displayName = '<%= component.displayName %>'; +<%= component.className %>.propTypes = {}; +<%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/generators/component/templates/4/components/Stateless.js b/generators/component/templates/4/components/Stateless.js deleted file mode 100644 index cb38a6c..0000000 --- a/generators/component/templates/4/components/Stateless.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react';<% if(componentHasStyles) { %> -import cssmodules from 'react-css-modules'; -import styles from '<%= style.webpackPath %>';<% } %> - -const <%= component.className %> = () => { - - return ( -
- Please edit <%= component.path %><%= component.fileName %> to update this component! -
- ); -}; - -<%= component.className %>.displayName = '<%= component.displayName %>'; -<%= component.className %>.propTypes = {}; -<%= component.className %>.defaultProps = {}; - -<% if(componentHasStyles) { %>export default cssmodules(<%= component.className %>, styles);<% -} else { -%>export default <%= component.className %>;<% } %> diff --git a/generators/component/templates/4/components/StatelessCssModules.js b/generators/component/templates/4/components/StatelessCssModules.js new file mode 100644 index 0000000..5891d34 --- /dev/null +++ b/generators/component/templates/4/components/StatelessCssModules.js @@ -0,0 +1,15 @@ +import React from 'react'; +import cssmodules from 'react-css-modules'; +import styles from '<%= style.webpackPath %>'; + +const <%= component.className %> = () => ( +
+ Please edit <%= component.path %><%= component.fileName %> to update this component! +
+); + +<%= component.className %>.displayName = '<%= component.displayName %>'; +<%= component.className %>.propTypes = {}; +<%= component.className %>.defaultProps = {}; + +export default cssmodules(<%= component.className %>, styles); diff --git a/generators/component/templates/4/components/StatelessNoStyles.js b/generators/component/templates/4/components/StatelessNoStyles.js new file mode 100644 index 0000000..6f65dc2 --- /dev/null +++ b/generators/component/templates/4/components/StatelessNoStyles.js @@ -0,0 +1,13 @@ +import React from 'react'; + +const <%= component.className %> = () => ( +
+ Please edit <%= component.path %><%= component.fileName %> to update this component! +
+); + +<%= component.className %>.displayName = '<%= component.displayName %>'; +<%= component.className %>.propTypes = {}; +<%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/generators/component/templates/4/components/StatelessWithStyles.js b/generators/component/templates/4/components/StatelessWithStyles.js new file mode 100644 index 0000000..f8a2910 --- /dev/null +++ b/generators/component/templates/4/components/StatelessWithStyles.js @@ -0,0 +1,14 @@ +import React from 'react'; +import '<%= style.webpackPath %>'; + +const <%= component.className %> = () => ( +
+ Please edit <%= component.path %><%= component.fileName %> to update this component! +
+); + +<%= component.className %>.displayName = '<%= component.displayName %>'; +<%= component.className %>.propTypes = {}; +<%= component.className %>.defaultProps = {}; + +export default <%= component.className %>; diff --git a/test/generators/app/indexTest.js b/test/generators/app/indexTest.js index 6887d68..c83de08 100644 --- a/test/generators/app/indexTest.js +++ b/test/generators/app/indexTest.js @@ -98,7 +98,7 @@ describe('react-webpack:app', () => { 'src/actions/README.md', 'src/index.js', 'src/components/App.js', - 'src/components/app.cssmodule.css', + 'src/components/app.css', 'src/favicon.ico', 'src/images/yeoman.png', 'src/index.html', diff --git a/test/generators/component/indexTest.js b/test/generators/component/indexTest.js index bbbc8f5..b57f346 100644 --- a/test/generators/component/indexTest.js +++ b/test/generators/component/indexTest.js @@ -3,6 +3,7 @@ let path = require('path'); let assert = require('yeoman-assert'); let helpers = require('yeoman-test'); + describe('react-webpack:component', () => { const generatorComponent = path.join(__dirname, '../../../generators/component'); @@ -182,70 +183,78 @@ describe('react-webpack:component', () => { */ let generator; + const cssModSuffix = (useCssModules) => useCssModules ? '.cssmodule' : ''; + const importAssertion = (useCssModules, ext) => useCssModules + ? `import styles from './mycomponent.cssmodule.${ext}';` + : `import './mycomponent.${ext}';` + ; + // List of available style types. Please add a line that says // testComponentWithStyle(styleTypes.KEY); to the bottom of the file // to run all unit tests for this filetype. - const styleTypes = { + const styleTypes = (useCssModules) => ({ css: { type: 'css', - fileName: 'src/components/mycomponent.cssmodule.css', - expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.css', + fileName: `src/components/mycomponent${cssModSuffix(useCssModules)}.css`, + expandedFileName: `src/components/my/littleSpecial/test${cssModSuffix(useCssModules)}.css`, assertions: { - componentImport: 'import styles from \'./mycomponent.cssmodule.css\';', + componentImport: importAssertion(useCssModules, 'css'), styleContent: '.mycomponent-component' } }, sass: { type: 'sass', - fileName: 'src/components/mycomponent.cssmodule.sass', - expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.sass', + fileName: `src/components/mycomponent${cssModSuffix(useCssModules)}.sass`, + expandedFileName: `src/components/my/littleSpecial/test${cssModSuffix(useCssModules)}.sass`, assertions: { - componentImport: 'import styles from \'./mycomponent.cssmodule.sass\';', + componentImport: importAssertion(useCssModules, 'sass'), styleContent: '.mycomponent-component' } }, scss: { type: 'scss', - fileName: 'src/components/mycomponent.cssmodule.scss', - expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.scss', + fileName: `src/components/mycomponent${cssModSuffix(useCssModules)}.scss`, + expandedFileName: `src/components/my/littleSpecial/test${cssModSuffix(useCssModules)}.scss`, assertions: { - componentImport: 'import styles from \'./mycomponent.cssmodule.scss\';', + componentImport: importAssertion(useCssModules, 'scss'), styleContent: '.mycomponent-component' } }, less: { type: 'less', - fileName: 'src/components/mycomponent.cssmodule.less', - expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.less', + fileName: `src/components/mycomponent${cssModSuffix(useCssModules)}.less`, + expandedFileName: `src/components/my/littleSpecial/test${cssModSuffix(useCssModules)}.less`, assertions: { - componentImport: 'import styles from \'./mycomponent.cssmodule.less\';', + componentImport: importAssertion(useCssModules, 'less'), styleContent: '.mycomponent-component' } }, stylus: { type: 'stylus', - fileName: 'src/components/mycomponent.cssmodule.styl', - expandedFileName: 'src/components/my/littleSpecial/test.cssmodule.styl', + fileName: `src/components/mycomponent${cssModSuffix(useCssModules)}.styl`, + expandedFileName: `src/components/my/littleSpecial/test${cssModSuffix(useCssModules)}.styl`, assertions: { - componentImport: 'import styles from \'./mycomponent.cssmodule.styl\';', + componentImport: importAssertion(useCssModules, 'styl'), styleContent: '.mycomponent-component' } } - }; + }); /** * Return a newly generated component with given name and style * @param {String} name Name of the component * @param {String} styleType Styling language to use * @param {Object} options Options to use for the generator + * @param {boolean} useCssModules useCssModules indicate whether to test with cssmodules enabled * @param {Function} callback Test callback to run */ - function createGeneratedComponent(name, styleType, options, callback) { + function createGeneratedComponent(name, styleType, options, useCssModules, callback) { helpers.run(generatorComponent) .withArguments([name]) .withOptions(options) .on('ready', (instance) => { instance.config.set('style', styleType); + instance.config.set('cssmodules', useCssModules); instance.config.set('generatedWithVersion', 4); generator = instance; }) @@ -256,20 +265,21 @@ describe('react-webpack:component', () => { * Test a component with styling applied * @param {Object} style The style to apply (see styleTypes above) * @param {Object} options Options to use [optional] + * @param {boolean} useCssModules indicate whether to test with cssmodules enabled */ - function testComponentWithStyle(style, options) { + function testComponentWithStyle(style, options, useCssModules) { // Make sure we always have options if(!options) { options = {}; } - describe(`when using style type "${style.type}" including with nostyle set to false`, () => { + describe(`when using style type "${style.type}" with nostyle = false and cssmodules = ${useCssModules}`, () => { describe('when writing is called', () => { it(`should create the react component, its ${style.type}-stylesheet and test file`, (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.file([ 'src/components/Mycomponent.js', @@ -284,34 +294,34 @@ describe('react-webpack:component', () => { describe('when creating a component', () => { it('should always import REACT', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', 'import React from \'react\';'); done(); }); }); it(`should require the created ${style.type} file`, (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', style.assertions.componentImport); done(); }); }); it('should have its displayName set per default', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', 'Mycomponent.displayName = \'Mycomponent\';'); done(); }); }); it('should export the created component', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { let exportAssertion; - if(generator.options.stateless) { + if(useCssModules) { exportAssertion = 'export default cssmodules(Mycomponent, styles);'; } else { - exportAssertion = 'export default Mycomponent'; + exportAssertion = 'export default Mycomponent;'; } assert.fileContent('src/components/Mycomponent.js', exportAssertion); done(); @@ -319,7 +329,7 @@ describe('react-webpack:component', () => { }); it('should be possible to create components in a subfolder', (done) => { - createGeneratedComponent('my/little !special/test', style.type, options, () => { + createGeneratedComponent('my/little !special/test', style.type, options, useCssModules, () => { assert.file([ 'src/components/my/littleSpecial/Test.js', @@ -331,14 +341,14 @@ describe('react-webpack:component', () => { }); it(`should add the components ${style.type} class to the created stylesheet`, (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent(style.fileName, style.assertions.styleContent); done(); }); }); it('should create a unit test that imports the generated component', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('test/components/MycomponentTest.js', 'import Mycomponent from \'components/Mycomponent.js\';'); done(); }); @@ -351,20 +361,21 @@ describe('react-webpack:component', () => { * Test a component with styling applied * @param {Object} style The style to apply (see styleTypes above) * @param {Object} options Options to use [optional] + * @param {boolean} useCssModules indicate whether to test with cssmodules enabled */ - function testComponentWithoutStyle(style, options) { + function testComponentWithoutStyle(style, options, useCssModules) { // Make sure we always have options if(!options) { options = {}; } - describe(`when using style type "${style.type}" with nostyle set to true`, () => { + describe(`when using style type "${style.type}" with nostyle = true and cssmodules = ${useCssModules}`, () => { describe('when writing is called', () => { it('should create the react component, and test file', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.file([ 'src/components/Mycomponent.js', @@ -378,28 +389,28 @@ describe('react-webpack:component', () => { describe('when creating a component', () => { it('should always import REACT', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', 'import React from \'react\';'); done(); }); }); it('should have its displayName set per default', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', 'Mycomponent.displayName = \'Mycomponent\';'); done(); }); }); it('should export the created component', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('src/components/Mycomponent.js', 'export default Mycomponent'); done(); }); }); it('should be possible to create components in a subfolder', (done) => { - createGeneratedComponent('my/little !special/test', style.type, options, () => { + createGeneratedComponent('my/little !special/test', style.type, options, useCssModules, () => { assert.file([ 'src/components/my/littleSpecial/Test.js', @@ -410,7 +421,7 @@ describe('react-webpack:component', () => { }); it('should create a unit test that imports the generated component', (done) => { - createGeneratedComponent('mycomponent', style.type, options, () => { + createGeneratedComponent('mycomponent', style.type, options, useCssModules, () => { assert.fileContent('test/components/MycomponentTest.js', 'import Mycomponent from \'components/Mycomponent.js\';'); done(); }); @@ -421,10 +432,15 @@ describe('react-webpack:component', () => { // Run all tests for all available style types. // Stateless components will also be tested! - for(const style in styleTypes) { - testComponentWithStyle(styleTypes[style]); - testComponentWithStyle(styleTypes[style], { stateless: true }); - testComponentWithoutStyle(styleTypes[style], { nostyle: true }); + for(const style in styleTypes(true)) { + testComponentWithStyle(styleTypes(true)[style], {}, true); + testComponentWithStyle(styleTypes(true)[style], { stateless: true }, true); + testComponentWithoutStyle(styleTypes(true)[style], { nostyle: true }, true); + } + for(const style in styleTypes(false)) { + testComponentWithStyle(styleTypes(false)[style], {}, false); + testComponentWithStyle(styleTypes(false)[style], { stateless: true }, false); + testComponentWithoutStyle(styleTypes(false)[style], { nostyle: true }, false); } }); }); diff --git a/test/utils/yeomanTest.js b/test/utils/yeomanTest.js index baf5ced..cf32c53 100644 --- a/test/utils/yeomanTest.js +++ b/test/utils/yeomanTest.js @@ -114,11 +114,11 @@ describe('Utilities:Yeoman', () => { }; it('should get all required information for component creation from the components name', () => { - expect(utils.getAllSettingsFromComponentName('my/component/test', 'css', 4)).to.deep.equal(expectionNamespaced); + expect(utils.getAllSettingsFromComponentName('my/component/test', 'css', true, 4)).to.deep.equal(expectionNamespaced); }); it('should build path information wo/ two slashes when dealing with a non-namespaced component', () => { - expect(utils.getAllSettingsFromComponentName('test', 'css', 4)).to.deep.equal(expectionRoot); + expect(utils.getAllSettingsFromComponentName('test', 'css', true, 4)).to.deep.equal(expectionRoot); }); diff --git a/utils/all.js b/utils/all.js index 9039bf7..088de62 100644 --- a/utils/all.js +++ b/utils/all.js @@ -1,9 +1,11 @@ 'use strict'; const config = require('./config'); +const constants = require('./constants'); const yeoman = require('./yeoman'); module.exports = { config, + constants, yeoman }; diff --git a/utils/constants.js b/utils/constants.js new file mode 100644 index 0000000..b55a92f --- /dev/null +++ b/utils/constants.js @@ -0,0 +1,35 @@ +'use strict'; + +/** + * List of supported generator versions. + * @type {number[]} + */ +const SUPPORTED_GEN_VERSIONS = [3, 4]; + + +/** + * ENUM of supported component types. + * @type {{STATEFUL: string, STATELESS: string}} + */ +const COMP_TYPES = { + STATEFUL: 'Stateful', + STATELESS: 'Stateless' +}; + + +/** + * ENUM of supported style types. + * @type {{WITH_STYLES: string, WITH_CSSMODULES: string, NO_STYLES: string}} + */ +const STYLE_TYPES = { + WITH_STYLES: 'WithStyles', + WITH_CSSMODULES: 'CssModules', + NO_STYLES: 'NoStyles' +}; + + +module.exports = { + SUPPORTED_GEN_VERSIONS, + COMP_TYPES, + STYLE_TYPES +}; diff --git a/utils/yeoman.js b/utils/yeoman.js index 583d5a7..0e25fd1 100644 --- a/utils/yeoman.js +++ b/utils/yeoman.js @@ -3,6 +3,7 @@ const path = require('path'); const configUtils = require('./config'); const _ = require('underscore.string'); +const C = require('./constants'); // Needed directory paths const baseName = path.basename(process.cwd()); @@ -22,7 +23,7 @@ let getBaseDir = () => { * @param {String|Number} generatorVersion The version of the generator [optional] * @return {Object} Component settings */ -let getAllSettingsFromComponentName = (componentName, style, generatorVersion) => { +let getAllSettingsFromComponentName = (componentName, style, useCssModules, generatorVersion) => { // Use css per default if(!style) { @@ -60,9 +61,9 @@ let getAllSettingsFromComponentName = (componentName, style, generatorVersion) = case 4: settings = { style: { - webpackPath: `./${componentBaseName.toLowerCase()}.cssmodule${styleSettings.suffix}`, + webpackPath: `./${componentBaseName.toLowerCase()}${useCssModules ? '.cssmodule' : ''}${styleSettings.suffix}`, path: path.normalize(`${componentPath.path}/${componentPartPath}/`), - fileName: `${componentBaseName.toLowerCase()}.cssmodule${styleSettings.suffix}`, + fileName: `${componentBaseName.toLowerCase()}${useCssModules ? '.cssmodule' : ''}${styleSettings.suffix}`, className: getComponentStyleName(componentBaseName), suffix: styleSettings.suffix }, @@ -197,12 +198,32 @@ let getDestinationClassName = (name, type, suffix) => { return _.capitalize(fixedName.split('/').pop().split('.js')[0]); }; +/** + * Get the filename of the component template to copy. + * @param {boolean} isStateless + * @param {boolean} useStyles + * @param {boolean} useCssModules + * @return {string} The template filename including the .js suffix + */ +let getComponentTemplateName = (isStateless, useStyles, useCssModules) => { + const componentTypeFrag = isStateless ? C.COMP_TYPES.STATELESS : C.COMP_TYPES.STATEFUL; + const styleTypeFrag = !useStyles + ? C.STYLE_TYPES.NO_STYLES + : useCssModules + ? C.STYLE_TYPES.WITH_CSSMODULES + : C.STYLE_TYPES.WITH_STYLES + ; + + return `${componentTypeFrag}${styleTypeFrag}.js`; +}; + module.exports = { getBaseDir, getAllSettingsFromComponentName, getAppName, getCleanedPathName, getComponentStyleName, + getComponentTemplateName, getDestinationPath, getDestinationClassName };