mirror of
https://github.com/react-webpack-generators/generator-react-webpack.git
synced 2025-12-08 18:01:59 +00:00
Refactored component subgen to support styles and/or cssmodules #255
This commit refactors the template structure for components to multiple different base templates based on the required styling options: - nostyle - with styles - with styles and css modules
This commit is contained in:
parent
389cc94bf4
commit
e2add4af4d
@ -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
|
||||
);
|
||||
|
||||
@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
class <%= component.className %> extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %>/<%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
|
||||
// Uncomment properties you need
|
||||
// <%= component.className %>.propTypes = {};
|
||||
// <%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -0,0 +1,17 @@
|
||||
'use strict';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
let <%= component.className %> = () => (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %>/<%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
|
||||
// Uncomment properties you need
|
||||
// <%= component.className %>.propTypes = {};
|
||||
// <%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -4,7 +4,7 @@ import React from 'react';
|
||||
|
||||
require('<%= style.webpackPath %>');
|
||||
|
||||
let <%= component.className %> = (props) => (
|
||||
let <%= component.className %> = () => (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %>/<%= component.fileName %> to update this component!
|
||||
</div>
|
||||
@ -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);
|
||||
@ -0,0 +1,18 @@
|
||||
import React from 'react';
|
||||
|
||||
class <%= component.className %> extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
import '<%= style.webpackPath %>';
|
||||
|
||||
class <%= component.className %> extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -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 (
|
||||
<div className="<%= style.className %>" styleName="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
<% if(componentHasStyles) { %>export default cssmodules(<%= component.className %>, styles);<%
|
||||
} else {
|
||||
%>export default <%= component.className %>;<% } %>
|
||||
@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
import cssmodules from 'react-css-modules';
|
||||
import styles from '<%= style.webpackPath %>';
|
||||
|
||||
const <%= component.className %> = () => (
|
||||
<div className="<%= style.className %>" styleName="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
export default cssmodules(<%= component.className %>, styles);
|
||||
@ -0,0 +1,13 @@
|
||||
import React from 'react';
|
||||
|
||||
const <%= component.className %> = () => (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import '<%= style.webpackPath %>';
|
||||
|
||||
const <%= component.className %> = () => (
|
||||
<div className="<%= style.className %>">
|
||||
Please edit <%= component.path %><%= component.fileName %> to update this component!
|
||||
</div>
|
||||
);
|
||||
|
||||
<%= component.className %>.displayName = '<%= component.displayName %>';
|
||||
<%= component.className %>.propTypes = {};
|
||||
<%= component.className %>.defaultProps = {};
|
||||
|
||||
export default <%= component.className %>;
|
||||
@ -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',
|
||||
|
||||
@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const config = require('./config');
|
||||
const constants = require('./constants');
|
||||
const yeoman = require('./yeoman');
|
||||
|
||||
module.exports = {
|
||||
config,
|
||||
constants,
|
||||
yeoman
|
||||
};
|
||||
|
||||
35
utils/constants.js
Normal file
35
utils/constants.js
Normal file
@ -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
|
||||
};
|
||||
@ -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
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user