'use strict'; 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. 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')), '..'); /** * Base generator. Will copy all required files from react-webpack-template */ class AppGenerator extends Generators.Base { constructor(args, options) { super(args, options); // Make options available this.option('skip-welcome-message', { desc: 'Skip the welcome message', type: Boolean, defaults: false }); this.option('skip-install'); // Use our plain template as source this.sourceRoot(baseRootPath); this.config.save(); } initializing() { 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() { return this.prompt(prompts).then((answers) => { // Make sure to get the correct app name if it is not the default if(answers.appName !== utils.yeoman.getAppName()) { answers.appName = utils.yeoman.getAppName(answers.appName); } // Set needed global vars for yo this.appName = answers.appName; this.style = answers.style; this.cssmodules = answers.cssmodules; this.postcss = answers.postcss; this.generatedWithVersion = parseInt(packageInfo.version.split('.').shift(), 10); // Set needed keys into config this.config.set('appName', this.appName); this.config.set('appPath', this.appPath); this.config.set('style', this.style); this.config.set('cssmodules', this.cssmodules); this.config.set('postcss', this.postcss); this.config.set('generatedWithVersion', this.generatedWithVersion); }); } configuring() { // Generate our package.json. Make sure to also include the required dependencies for styles let defaultSettings = this.fs.readJSON(`${baseRootPath}/package.json`); let packageSettings = { name: this.appName, private: true, version: '0.0.1', description: `${this.appName} - Generated by generator-react-webpack`, main: 'src/index.js', scripts: defaultSettings.scripts, repository: '', keywords: [], author: 'Your name here', devDependencies: defaultSettings.devDependencies, dependencies: defaultSettings.dependencies }; // Add needed loaders if we have special styles let styleConfig = utils.config.getChoiceByKey('style', this.style); if(styleConfig && styleConfig.packages) { for(let dependency of styleConfig.packages) { packageSettings.devDependencies[dependency.name] = dependency.version; } } // Add postcss module if enabled let postcssConfig = utils.config.getChoiceByKey('postcss', 'postcss'); if(this.postcss && postcssConfig && postcssConfig.packages) { for(let dependency of postcssConfig.packages) { packageSettings.devDependencies[dependency.name] = dependency.version; } } this.fs.writeJSON(this.destinationPath('package.json'), packageSettings); } writing() { const excludeList = [ 'LICENSE', 'README.md', 'CHANGELOG.md', 'node_modules', 'package.json', '.istanbul.yml', '.travis.yml' ]; // Get all files in our repo and copy the ones we should fs.readdir(this.sourceRoot(), (err, items) => { for(let item of items) { // Skip the item if it is in our exclude list if(excludeList.indexOf(item) !== -1) { continue; } // Copy all items to our root let fullPath = path.join(baseRootPath, item); if(fs.lstatSync(fullPath).isDirectory()) { this.bulkDirectory(item, item); } else { if (item === '.npmignore') { this.copy(item, '.gitignore'); } else { this.copy(item, item); } } } }); } 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;