### Typical Yeoman Workflow Example Source: https://yeoman.io/learning/support This example demonstrates a common workflow using Yeoman, Angular, Bower, and Grunt for web application development. It shows the sequence of commands to generate a project, install dependencies, and build. ```bash yo webapp $ yo angular $ bower install angular-directives $ grunt ``` -------------------------------- ### Install Project Dependencies Source: https://yeoman.io/learning/faq After cloning a Yeoman-generated web application, run these commands to install Node.js and Bower dependencies. ```bash $ npm install ``` ```bash $ bower install ``` -------------------------------- ### Install Bower Dependencies Source: https://yeoman.io/authoring/dependencies Use `this.bowerInstall()` to install Bower packages. This method ensures the `bower install` command runs only once. ```javascript this.bowerInstall(); ``` -------------------------------- ### Install npm Dependencies Source: https://yeoman.io/authoring/dependencies Use `this.npmInstall()` to install npm packages. This method ensures the `npm install` command runs only once. ```javascript class extends Generator { installingLodash() { this.npmInstall(['lodash'], { 'save-dev': true }); } } ``` -------------------------------- ### Start the Development Server Source: https://yeoman.io/codelab/preview-inbrowser Run this npm script to start a local Node-based HTTP server. The server typically runs on localhost:3000. ```bash npm run serve ``` -------------------------------- ### Install Yarn Dependencies Source: https://yeoman.io/authoring/dependencies Use `this.yarnInstall()` to install Yarn packages. Similar to `npmInstall`, it ensures the `yarn install` command runs only once. ```javascript generators.Base.extend({ installingLodash: function() { this.yarnInstall(['lodash'], { 'dev': true }); } }); ``` -------------------------------- ### Install yeoman-environment Source: https://yeoman.io/authoring/integrating-yeoman Install the `yeoman-environment` package using npm. This package provides the core Yeoman environment system. ```bash npm install --save yeoman-environment ``` -------------------------------- ### Install generator-fountain-webapp with npm Source: https://yeoman.io/codelab/install-generators Use this command to install the generator for FountainJS projects globally. This command downloads and installs the necessary Node packages for the generator to function. ```bash npm install --global generator-fountain-webapp ``` -------------------------------- ### Check Node.js and npm Versions Source: https://yeoman.io/codelab/setup Verify if Node.js and npm are installed and meet the minimum version requirements. This is a prerequisite for installing Yeoman. ```bash node --version && npm --version ``` -------------------------------- ### Install redux-localstorage Source: https://yeoman.io/codelab/local-storage Install the redux-localstorage package to enable persistence. This package simplifies the integration of local storage with your Redux store. ```bash npm install --save redux-localstorage@rc ``` -------------------------------- ### Install Yeoman Globally Source: https://yeoman.io/ Install Yeoman globally using npm to make the 'yo' command available on your system. ```bash npm install -g yo ``` -------------------------------- ### Get Yeoman Version Source: https://yeoman.io/learning Display the currently installed version of Yeoman. ```bash yo --version ``` -------------------------------- ### Test Structure Example Source: https://yeoman.io/contributing/testing-guidelines Demonstrates the recommended structure for Mocha describe blocks, differentiating between static and instance methods. ```javascript function Class() { this.args = nopt(); }; Class.exclude = function () {}; Class.name = 'Yeoman'; Class.prototype.find = function () {}; describe('Class', function () { describe('.exclude()', function () {}); describe('.name', function () {}); describe('#find()', function () {}); describe('#args', function () {}); }); ``` -------------------------------- ### Example .yo-rc.json structure Source: https://yeoman.io/authoring/storage This JSON structure shows how configuration objects from multiple generators are namespaced and stored. Each generator's configuration is sandboxed. ```json { "generator-backbone": { "requirejs": true, "coffee": true }, "generator-gruntfile": { "compass": false } } ``` -------------------------------- ### Equivalent npm Command Source: https://yeoman.io/authoring/dependencies This is the equivalent command-line execution for installing lodash as a dev dependency. ```bash npm install lodash --save-dev ``` -------------------------------- ### Check Git Installation Source: https://yeoman.io/codelab/setup Confirm if Git is installed on your system. Git is a version control system often required for managing project dependencies and code. ```bash git --version ``` -------------------------------- ### Equivalent Yarn Command Source: https://yeoman.io/authoring/dependencies This is the equivalent command-line execution for installing lodash as a dev dependency using Yarn. ```bash yarn add lodash --dev ``` -------------------------------- ### Install Yeoman CLI Globally Source: https://yeoman.io/codelab/setup Install the Yeoman command-line interface (CLI) globally on your system. This makes the 'yo' command available in your terminal for scaffolding projects. ```bash npm install --global yo ``` -------------------------------- ### Install Dependencies with Specific Package Managers Source: https://yeoman.io/authoring/dependencies Use `this.installDependencies()` to install dependencies, specifying which package managers (npm, bower, yarn) to use by passing boolean flags. ```javascript generators.Base.extend({ install: function () { this.installDependencies({ npm: false, bower: true, yarn: true }); } }); ``` -------------------------------- ### List Installed Yeoman Sub-Generators Source: https://yeoman.io/codelab/keep-going Run this command in your terminal to see a list of all available sub-generators for your installed Yeoman generators. ```bash yo --generators ``` -------------------------------- ### Lookup and Run Installed Generators Source: https://yeoman.io/authoring/integrating-yeoman Discover all Yeoman generators installed on the user's machine and register them with the environment. Then, run a specific generator. ```javascript env.lookup(function () { env.run('angular'); }); ``` -------------------------------- ### Run Yeoman Interactive Menu Source: https://yeoman.io/codelab/install-generators Execute this command to open the Yeoman interactive menu. From here, you can select 'Install a generator' to search for and install available generators. ```bash yo ``` -------------------------------- ### Install a Specific Generator Source: https://yeoman.io/learning Install a specific Yeoman generator, such as 'generator-webapp', globally using npm. Generators are npm packages that define project structures. ```bash npm install -g generator-webapp ``` -------------------------------- ### Check Yeoman CLI Version Source: https://yeoman.io/codelab/setup Verify that the Yeoman CLI has been installed correctly by checking its version. This confirms the installation was successful and displays the active version. ```bash yo --version ``` -------------------------------- ### Generator execution order example Source: https://yeoman.io/authoring/composability Demonstrates how generators composed within the `initializing` phase execute. The order of execution follows the order in which `composeWith` is called within the same priority group. ```javascript // In my-generator/generators/turbo/index.js module.exports = class extends Generator { prompting() { this.log('prompting - turbo'); } writing() { this.log('writing - turbo'); } }; // In my-generator/generators/electric/index.js module.exports = class extends Generator { prompting() { this.log('prompting - zap'); } writing() { this.log('writing - zap'); } }; // In my-generator/generators/app/index.js module.exports = class extends Generator { initializing() { this.composeWith(require.resolve('../turbo')); this.composeWith(require.resolve('../electric')); } }; ``` ```text Upon running `yo my-generator`, this will result in: prompting - turbo prompting - zap writing - turbo writing - zap ``` -------------------------------- ### Access Generator Homepage Source: https://yeoman.io/learning Open the homepage of an installed generator in your web browser. This is useful for finding documentation or support. ```bash npm home generator-webapp ``` -------------------------------- ### Add npm Bin to PATH Environment Variable Source: https://yeoman.io/learning/faq If `yo` command is not found after npm installation, add this to your `.bashrc` to include global NPM modules in your PATH. ```bash export PATH=/usr/local/share/npm/bin:$PATH ``` -------------------------------- ### Link Local Generator with npm Source: https://yeoman.io/authoring Use this command in your generator's root directory to install dependencies and create a symlink for local development. This allows you to run your generator using `yo name`. ```bash npm link ``` -------------------------------- ### Assertion Message Example Source: https://yeoman.io/contributing/testing-guidelines Shows the recommended way to add messages to assertions for clarity when an error occurs. ```javascript assert(Generator.appname, 'Expected Generator to have an `appname` property'); ``` -------------------------------- ### Declarative 'it' Block Example Source: https://yeoman.io/contributing/testing-guidelines Illustrates the preferred declarative style for 'it' blocks in Mocha tests. ```javascript // GOOD it('find generators'); ``` -------------------------------- ### Fix npm Install Failure on OS X Source: https://yeoman.io/learning/faq If `npm install -g yo` fails on OS X with 'sh: node: command not found', try granting execute permissions to the Node binary. ```bash sudo chmod a+rx /usr/local/bin /usr/local/bin/node ``` -------------------------------- ### Get Destination Path - Yeoman Generator Source: https://yeoman.io/authoring/file-system Use `this.destinationRoot()` to get the current destination root path and `this.destinationPath('sub/path')` to construct a full path within the destination context. Assumes the destination root is already set. ```javascript class extends Generator { paths() { this.destinationRoot(); // returns '~/projects' this.destinationPath('index.js'); // returns '~/projects/index.js' } } ``` -------------------------------- ### Use User Answers for Template Processing Source: https://yeoman.io/authoring/file-system Store user answers during the prompting stage and use them to populate template variables in `copyTpl`. This example prompts for a project title and uses it for the template's title. ```javascript class extends Generator { async prompting() { this.answers = await this.prompt([{ type : 'input', name : 'title', message : 'Your project title', }]); } writing() { this.fs.copyTpl( this.templatePath('index.html'), this.destinationPath('public/index.html'), { title: this.answers.title } // user answer `title` used ); } } ``` -------------------------------- ### Overwrite Generator Constructor Source: https://yeoman.io/authoring Override the generator's constructor to set up initial state and options. Remember to call `super(args, opts)` to ensure proper setup. ```javascript module.exports = class extends Generator { // The name `constructor` is important here constructor(args, opts) { // Calling the super constructor is important so our generator is correctly set up super(args, opts); // Next, add your custom code this.option('babel'); // This method adds support for a `--babel` flag } }; ``` -------------------------------- ### Use a Sub-Generator Source: https://yeoman.io/learning Invoke a sub-generator to add specific features to an existing project. This example adds a new controller named 'MyNewController' using the 'generator-angular' sub-generator. ```bash yo angular:controller MyNewController ``` -------------------------------- ### Declare Peer Dependencies in package.json Source: https://yeoman.io/authoring/composability Use `peerDependencies` to declare generators that should be installed alongside your generator. Specify version ranges using npm's syntax. ```json { "peerDependencies": { "generator-gruntfile": "*", "generator-bootstrap": ">=1.0.0" } } ``` -------------------------------- ### Get Registered Generators Metadata Source: https://yeoman.io/authoring/integrating-yeoman Retrieve metadata for all generators registered with the environment. This includes their resolved path and namespace. ```javascript { "webapp:app": { "resolved": "/usr/lib/node_modules/generator-webapp/app/index.js", "namespace": "webapp:app" } } ``` -------------------------------- ### Get Template Path - Yeoman Generator Source: https://yeoman.io/authoring/file-system Use `this.sourceRoot()` to retrieve the current template root path and `this.templatePath('app/index.js')` to create a path relative to the template context. The default template root is './templates/'. ```javascript class extends Generator { paths() { this.sourceRoot(); // returns './templates' this.templatePath('index.js'); // returns './templates/index.js' } }; ``` -------------------------------- ### Compose with a generator namespace Source: https://yeoman.io/authoring/composability Pass a generator namespace directly to `composeWith`. Yeoman will attempt to find the generator among peer dependencies or globally installed packages. This approach is not encouraged. ```javascript this.composeWith('backbone:route', {rjs: true}); ``` -------------------------------- ### Build Production Version Source: https://yeoman.io/codelab/prepare-production Run this command to create a production-ready version of your application. The optimized files will be placed in the `dist` folder. ```bash npm run build ``` -------------------------------- ### Preview Production App Locally Source: https://yeoman.io/codelab/prepare-production Use this command to preview your production app locally before deployment. It builds the project and launches a local web server. ```bash npm run serve:dist ``` -------------------------------- ### Running Generator in a Temporary Directory with Copied Files Source: https://yeoman.io/authoring/testing Use `inTmpDir()` to set up a temporary directory for testing. Copy existing files into this directory before the generator runs. Assert file existence after the generator completes. ```javascript var path = require('path'); var fs = require('fs-extra'); helpers.run(path.join(__dirname, '../app')) .inTmpDir(function (dir) { // `dir` is the path to the new temporary directory fs.copySync(path.join(__dirname, '../templates/common'), dir) }) .withPrompts({ coffee: false }) .then(function () { assert.file('common/file.txt'); }); ``` -------------------------------- ### Create Project Folder Source: https://yeoman.io/codelab/scaffold-app Use this command to create a new directory for your project and navigate into it. This is where the generator will place your scaffolded files. ```bash mkdir mytodo && cd mytodo ``` -------------------------------- ### Create First Git Commit Source: https://yeoman.io/codelab/review-generated-files Use these commands to add all generated files and create the initial commit in your git repository. ```bash git add --all && git commit -m "First commit" ``` -------------------------------- ### Create and Instantiate Environment Source: https://yeoman.io/authoring/integrating-yeoman Create a new Yeoman environment instance. This is the first step before registering or running generators. ```javascript var yeoman = require('yeoman-environment'); var env = yeoman.createEnv(); ``` -------------------------------- ### Run Unit Tests Source: https://yeoman.io/codelab/run-unit-tests Execute the unit tests defined in the project using the npm script. Ensure all tests pass after initial scaffolding. ```bash npm test ``` -------------------------------- ### View Generator Help Source: https://yeoman.io/learning Display the help options for a specific Yeoman generator. This shows available configurations and sub-generators. ```bash yo webapp --help ``` -------------------------------- ### Gather System Information (Windows) Source: https://yeoman.io/contributing/opening-issues Run this command on Windows systems to collect version and path information for issue reporting. ```bash yo --version && echo %PATH% %NODE_PATH% && node -e "console.log(process.platform, process.versions)" && type Gruntfile.js ``` -------------------------------- ### Assert File Existence Source: https://yeoman.io/authoring/testing Verify that specific files exist in the project directory. Use `assert.noFile()` to check for the absence of files. ```javascript assert.file(['Gruntfile.js', 'app/router.js', 'app/views/main.js']); ``` -------------------------------- ### Spawn Custom Commands Source: https://yeoman.io/authoring/dependencies Use `this.spawnCommand()` to run any CLI command, such as `composer`. This method normalizes the command for cross-platform compatibility. ```javascript class extends Generator { install() { this.spawnCommand('composer', ['install']); } } ``` -------------------------------- ### Gather System Information (Unix) Source: https://yeoman.io/contributing/opening-issues Run this command on Unix-like systems to collect version and path information for issue reporting. ```bash yo --version && echo $PATH $NODE_PATH && node -e 'console.log(process.platform, process.versions)' && cat Gruntfile.js ``` -------------------------------- ### Define and Use Prompts in Yeoman Source: https://yeoman.io/authoring/user-interactions Use the `prompt` method within the `prompting` queue to ask users questions. The answers are returned as a promise and can be accessed after `await`ing. ```javascript module.exports = class extends Generator { async prompting() { const answers = await this.prompt([ { type: "input", name: "name", message: "Your project name", default: this.appname // Default to current folder name }, { type: "confirm", name: "cool", message: "Would you like to enable the Cool feature?" } ]); this.log("app name", answers.name); this.log("cool feature", answers.cool); } }; ``` -------------------------------- ### Running a Generator with Test Context Source: https://yeoman.io/authoring/testing Use `helpers.run()` to execute a generator within a controlled test environment. Return the promise to ensure the test waits for completion. Mock options, arguments, prompts, and local configurations as needed. ```javascript var path = require('path'); it('generate a project', function () { // The object returned acts like a promise, so return it to wait until the process is done return helpers.run(path.join(__dirname, '../app')) .withOptions({ foo: 'bar' }) // Mock options passed in .withArguments(['name-x']) // Mock the arguments .withPrompts({ coffee: false }) // Mock the prompt answers .withLocalConfig({ lang: 'en' }) // Mock the local config .then(function() { // assert something about the generator }); }) ``` -------------------------------- ### Scaffold a New Project Source: https://yeoman.io/learning Create a new project using a Yeoman generator. Replace 'webapp' with the name of the generator you wish to use. ```bash yo webapp ``` -------------------------------- ### Testing Throws with .bind() Source: https://yeoman.io/contributing/testing-guidelines Demonstrates the preferred method for testing if a function throws an error with specific parameters using `.bind()`. ```javascript assert.throws(class.method.bind(class, 'Invalid param')); ``` -------------------------------- ### Remember User Preferences with `store: true` Source: https://yeoman.io/authoring/user-interactions Utilize the `store: true` option on a prompt to save the user's answer and use it as the default for future runs. ```javascript this.prompt({ type: "input", name: "username", message: "What's your GitHub username", store: true }); ``` -------------------------------- ### Manage package.json Programmatically Source: https://yeoman.io/authoring/dependencies Extend or create a `package.json` file programmatically using `this.fs.extendJSON()`. This is useful for defining fixed dependency versions. ```javascript class extends Generator { writing() { const pkgJson = { devDependencies: { eslint: '^3.15.0' }, dependencies: { react: '^16.2.0' } }; // Extend or create package.json file in destination path this.fs.extendJSON(this.destinationPath('package.json'), pkgJson); } install() { this.npmInstall(); } }; ``` -------------------------------- ### Deploy dist directory using Git subtree Source: https://yeoman.io/learning/deployment Deploy the contents of the 'dist' directory to a specified branch (e.g., 'gh-pages') on a remote repository (e.g., 'origin'). This command pushes the 'dist' directory as a subtree. ```bash git subtree push --prefix dist origin gh-pages ``` -------------------------------- ### Run a Generator Source: https://yeoman.io/authoring/integrating-yeoman Run a registered generator. This can be done in its simplest form or by passing arguments and options. ```javascript // In its simplest form env.run('npm:app', done); // Or passing arguments and options env.run('npm:app some-name', { 'skip-install': true }, done); ``` -------------------------------- ### Importing Yeoman Test Helpers Source: https://yeoman.io/authoring/testing Import the `yeoman-test` package to access testing utilities. ```javascript var helpers = require('yeoman-test'); ``` -------------------------------- ### Compose with a peer dependency generator Source: https://yeoman.io/authoring/composability Use `require.resolve()` to specify the path to a generator that is a peer dependency. Options can be passed to the composed generator. ```javascript this.composeWith(require.resolve('generator-bootstrap/generators/app'), {preprocessor: 'sass'}); ``` -------------------------------- ### Define Options with `this.option()` Source: https://yeoman.io/authoring/user-interactions Use `this.option()` in the constructor to define command-line flags (options), specifying their type, default values, and aliases. Access them via `this.options`. ```javascript module.exports = class extends Generator { // note: arguments and options should be defined in the constructor. constructor(args, opts) { super(args, opts); // This method adds support for a `--coffee` flag this.option("coffee"); // And you can then access it later; e.g. this.scriptSuffix = this.options.coffee ? ".coffee" : ".js"; } }; ``` -------------------------------- ### Initial State Test (Jasmine) Source: https://yeoman.io/codelab/run-unit-tests This is the initial unit test for the Todos reducer, verifying its default state. It checks if the reducer correctly initializes with a specific todo item. ```javascript it('should handle initial state', () => { expect(todos(undefined, {})).toEqual([ { text: 'Use Redux', completed: false, id: 0 } ]); }); ``` -------------------------------- ### Run a Generator Directly Source: https://yeoman.io/codelab/scaffold-app This command allows you to bypass the interactive menu and run a specific generator, such as 'fountain-webapp', directly. ```bash yo fountain-webapp ``` -------------------------------- ### Register Generator by Path Source: https://yeoman.io/authoring/integrating-yeoman Register a generator with the environment using its resolved path. The namespace can be provided optionally. ```javascript // Here we register a generator based on its path. // Providing the namespace is optional. env.register(require.resolve('generator-npm'), 'npm:app'); ``` -------------------------------- ### Running Transpiled Generators Source: https://yeoman.io/authoring/testing When a generator's source code is transpiled, you can run it by providing the generator class and specific settings like `resolved` path and `namespace` to `helpers.run()`. ```javascript var MyGenerator = require('../src/app'); helpers.run(MyGenerator, { resolved: require.resolve(__dirname, '../src/app/index.js'), namespace: 'mygenerator:app' }); ``` -------------------------------- ### Define a Priority Queue Method Source: https://yeoman.io/authoring/running-context Methods named after Yeoman's priority queues (e.g., 'initializing', 'prompting') are placed into specific queues within the run loop. ```javascript class extends Generator { priorityName() {} } ``` -------------------------------- ### Using this.log() for User Output Source: https://yeoman.io/authoring/user-interactions Always use `this.log()` for outputting content to the user. This method ensures compatibility with various Yeoman environments, including terminals and graphical tools. Avoid using `console.log()` or `process.stdout.write()`. ```javascript this.log('This is a message for the user.'); ``` -------------------------------- ### Define Helper Methods Using Instance Properties Source: https://yeoman.io/authoring/running-context Assigning a function to an instance property within the constructor creates a helper method that is not automatically run by the Yeoman environment. ```javascript class extends Generator { constructor(args, opts) { // Calling the super constructor is important so our generator is correctly set up super(args, opts) this.helperMethod = function () { console.log('won\'t be called automatically'); }; } } ``` -------------------------------- ### Integrate Livereload Script in HTML Source: https://yeoman.io/learning/faq Manually insert this script snippet into your HTML to enable livereloading when using a custom webserver, after removing the `connect` task from your Gruntfile/Gulpfile. ```html ``` -------------------------------- ### Handling Generator Events Source: https://yeoman.io/authoring/testing Instead of using promises, you can listen for `'ready'`, `'error'`, and `'end'` events emitted by the `RunContext` for more granular control over test execution flow. ```javascript helpers.run(path.join(__dirname, '../app')) .on('error', function (error) { console.log('Oh Noes!', error); }) .on('ready', function (generator) { // This is called right before `generator.run()` is called }) .on('end', done); ``` -------------------------------- ### Outputting Information with this.log Source: https://yeoman.io/authoring/user-interactions Use `this.log` to output strings to the user. This method mimics `console.log` within a terminal session. ```javascript module.exports = class extends Generator { myAction() { this.log("Something has gone wrong!"); } }; ``` -------------------------------- ### Scaffold a New Component with Fountain Angular Source: https://yeoman.io/codelab/keep-going Use this command to create a new component and its associated unit test file for your Angular project. ```bash yo fountain-angular2:component componentName ``` -------------------------------- ### Copy and Process Template File with `copyTpl` Source: https://yeoman.io/authoring/file-system Use `copyTpl` to copy a file and process its content as an EJS template. Provide a data object for template variables. The source template is `./templates/index.html` and the destination is `public/index.html`. ```javascript class extends Generator { writing() { this.fs.copyTpl( this.templatePath('index.html'), this.destinationPath('public/index.html'), { title: 'Templating with Yeoman' } ); } } ``` -------------------------------- ### Asynchronous File Copy in Temporary Directory Source: https://yeoman.io/authoring/testing Perform asynchronous file operations within `inTmpDir()` by using `this.async()` to manage the completion of the task. The generator run will wait for this asynchronous operation to finish. ```javascript var path = require('path'); var fs = require('fs-extra'); helpers.run(path.join(__dirname, '../app')) .inTmpDir(function (dir) { var done = this.async(); // `this` is the RunContext object. fs.copy(path.join(__dirname, '../templates/common'), dir, done); }) .withPrompts({ coffee: false }); ``` -------------------------------- ### Group Multiple Methods in a Priority Queue Source: https://yeoman.io/authoring/running-context Use an object to group multiple methods under a single priority name, ensuring they are run together. This syntax is not compatible with ES6 class definitions. ```javascript Generator.extend({ priorityName: { method() {}, method2() {} } }); ``` -------------------------------- ### Accessing Temporary Directory Path After Run Source: https://yeoman.io/authoring/testing The promise returned by `helpers.run()` resolves with the path to the temporary directory where the generator was executed. This allows for assertions on the final state of the generated files. ```javascript helpers.run(path.join(__dirname, '../app')) .inTmpDir(function (dir) { var done = this.async(); // `this` is the RunContext object. fs.copy(path.join(__dirname, '../templates/common'), dir, done); }) .withPrompts({ coffee: false }) .then(function (dir) { // assert something about the stuff in `dir` }); ``` -------------------------------- ### Yeoman Generator package.json with multiple generators Source: https://yeoman.io/authoring When using the 'generators/' directory structure, list all generator subdirectories in the 'files' property of package.json. ```json { "files": [ "app", "router" ] } ``` -------------------------------- ### Register Generator Constructor Source: https://yeoman.io/authoring/integrating-yeoman Register a generator using its constructor. A namespace must be provided manually when using this method. ```javascript var GeneratorNPM = generators.Base.extend(/* put your methods in here */); env.registerStub(GeneratorNPM, 'npm:app'); ``` -------------------------------- ### Function Declaration Style Source: https://yeoman.io/contributing/style-guide Demonstrates the preferred style for function declarations, including single quotes, two-space indentation, and whitespace after keywords. ```javascript function () { ... } ``` ```javascript function foo() { ... } ``` -------------------------------- ### Stop the Development Server Source: https://yeoman.io/codelab/preview-inbrowser Use Ctrl+C in the terminal to stop the currently running CLI process, which includes the development server. ```bash Ctrl+C ``` -------------------------------- ### Compose with a Generator class Source: https://yeoman.io/authoring/composability Compose with a generator class by providing an object with `Generator` and `path` properties. This is useful for composing with generators defined locally or imported from other modules. ```javascript // Import generator-node's main generator const NodeGenerator = require('generator-node/generators/app/index.js'); // Compose with it this.composeWith({ Generator: NodeGenerator, path: require.resolve('generator-node/generators/app') }); ``` -------------------------------- ### Configure Redux store with local storage Source: https://yeoman.io/codelab/local-storage Replace your existing store configuration with this code to integrate local storage persistence. It uses `redux-localstorage` to automatically save and load the state. ```javascript import {compose, createStore} from 'redux'; import rootReducer from '../reducers'; import persistState, {mergePersistedState} from 'redux-localstorage'; import adapter from 'redux-localstorage/lib/adapters/localStorage'; export default function configureStore(initialState) { const reducer = compose( mergePersistedState() )(rootReducer, initialState); const storage = adapter(window.localStorage); const createPersistentStore = compose( persistState(storage, 'state') )(createStore); const store = createPersistentStore(reducer); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextReducer = require('../reducers').default; store.replaceReducer(nextReducer); }); } return store; } ``` -------------------------------- ### Define Private Methods with Underscore Prefix Source: https://yeoman.io/authoring/running-context Prefixing a method name with an underscore prevents it from being automatically executed as a task by the Yeoman run loop. ```javascript class extends Generator { method1() { console.log('hey 1'); } _private_method() { console.log('private hey'); } } ``` -------------------------------- ### Require Assertion Helpers Source: https://yeoman.io/authoring/testing Import the necessary assertion helpers from the 'yeoman-assert' package. ```javascript var assert = require('yeoman-assert'); ``` -------------------------------- ### Basic Generator Test Structure Source: https://yeoman.io/authoring/testing Organize tests by generator, option, and assertion. This structure helps in managing complex generators. ```javascript describe('backbone:app', function () { it('generates a project with require.js', function () { // assert the file exist // assert the file uses AMD definition }); it('generates a project with webpack'); }); ``` -------------------------------- ### Debug Generator with Node.js Inspector Source: https://yeoman.io/authoring/debugging Run your generator with the Node.js inspector enabled to attach a debugger. This allows for breakpoints and step-through debugging. ```bash npx --node-options="--inspect" yo [arguments] ``` -------------------------------- ### Increase Open File Limit Source: https://yeoman.io/learning/faq To resolve 'EMFILE, too many open files' errors, increase the OS limit for concurrently open files by adding this to your `.bashrc` or `.zshrc`. ```bash ulimit -n [number of files] ``` -------------------------------- ### Run Tests Automatically Source: https://yeoman.io/codelab/run-unit-tests Execute unit tests continuously, automatically re-running them whenever file changes are detected. This is useful for TDD workflows. ```bash npm run test:auto ``` -------------------------------- ### Updated Initial State Test (Jasmine) Source: https://yeoman.io/codelab/run-unit-tests This updated unit test for the Todos reducer reflects a change in the expected initial state. It is used to demonstrate failing tests after modifying the reducer's initial state. ```javascript it('should handle initial state', () => { expect(todos(undefined, {})).toEqual([ { text: 'Use Yeoman', // <=== HERE completed: false, id: 0 } ]); }); ``` -------------------------------- ### Update Yeoman to Latest Version Source: https://yeoman.io/contributing/opening-issues Ensure you are using the latest version of Yeoman before reporting an issue. ```bash npm update -g yo ``` -------------------------------- ### Store User Answers for Later Use Source: https://yeoman.io/authoring/user-interactions Store user answers in `this` context during the `prompting` phase to access them in subsequent queues like `writing`. ```javascript module.exports = class extends Generator { async prompting() { this.answers = await this.prompt([ { type: "confirm", name: "cool", message: "Would you like to enable the Cool feature?" } ]); } writing() { this.log("cool feature", this.answers.cool); // user answer `cool` used } }; ``` -------------------------------- ### Assert File Content Source: https://yeoman.io/authoring/testing Check if a file contains specific content, using a string or a regular expression. Use `assert.noFileContent()` to assert the contrary. ```javascript assert.fileContent('controllers/user.js', /App\.UserController = Ember\.ObjectController\.extend/); ``` -------------------------------- ### Add dist directory to repository Source: https://yeoman.io/learning/deployment Add the 'dist' directory to your Git repository before deploying it as a subtree. This is necessary because Yeoman projects typically ignore the 'dist' directory by default. ```bash git add dist && git commit -m "Initial dist subtree commit" ``` -------------------------------- ### Handle Asynchronous Tasks with Promises Source: https://yeoman.io/authoring/running-context Return a promise from a generator method to pause the run loop until the promise resolves or rejects. The run loop continues on resolution and stops on rejection. ```javascript asyncTask() { var done = this.async(); getUserEmail(function (err, name) { done(err); }); } ``` -------------------------------- ### Mocking Dependent Generators with `withGenerators` Source: https://yeoman.io/authoring/testing Mock generators that your current generator composes with using `withGenerators()`. Provide an array of arrays, where each inner array contains a dummy generator created with `createDummyGenerator()` and the namespace of the mocked generator. ```javascript var deps = [ [helpers.createDummyGenerator(), 'karma:app'] ]; return helpers.run(path.join(__dirname, '../app')).withGenerators(deps); ``` -------------------------------- ### Enable Yeoman Generator Debug Logging Source: https://yeoman.io/authoring/debugging Activate Yeoman's debug mode by setting the DEBUG environment variable to the 'yeoman:generator' scope. This logs internal lifecycle information. ```bash # OS X / Linux DEBUG=yeoman:generator ``` ```bash # Windows set DEBUG=yeoman:generator ```