javascriptplop

Modifying an existing file with Plop?


I’m using plop to generate components for a React-based component library. I have a directory full of Handlebars templates that are used to create new component directories, and all is working well. I also have this index.js file that acts as the entrypoint for my bundler. It’s just full of lots of imports and an export. It looks like this:

import { Badge } from './components/Badge';
import { Button, ButtonMemo } from './components/Button';
import { Column } from './components/Column';
import { ErrorBoundary } from './components/ErrorBoundary';
import { FormBasicInfo } from './components/FormBasicInfo';
import { FormLogin } from './components/FormLogin';
import { FormSignup } from './components/FormSignUp';
import { Icon } from './components/Icon';
import { Input } from './components/Input';
import { Link } from './components/Link';
import { Loader } from './components/Loader';
import { Logo } from './components/Logo';
import { Row } from './components/Row';
import { Select } from './components/Select';
import { SimpleMenu } from './components/SimpleMenu';
import { Slideshow } from './components/Slideshow';
import { Spinner } from './components/Spinner';

export {
  Badge,
  Button,
  Column,
  ErrorBoundary,
  FormBasicInfo,
  FormLogin,
  FormSignup,
  Icon,
  Input,
  Link,
  Loader,
  Logo,
  Row,
  Select,
  SimpleMenu,
  Slideshow,
  Spinner,
};

When generating a new component, I would love to also add the new component to this entrypoint file. That would require adding an import line to the top block, and an export line to the bottom. Ideally it would still be alphabetically sorted, but that isn’t a hard requirement.

Is this possible?


Solution

  • This is how I ended up pulling it off:

    In my index.js file (the one I want modified), I added two comments in the places where the inserts should take place:

    …
    import { PointAccountCard } from './components/PointAccountCard';
    import { Card } from './components/Card';
    import { SettingsPanelFooter } from './components/SettingsPanelFooter';
    // COMPONENT IMPORTS
    
    export {
        …
        PointAccountCard,
        Card,
        SettingsPanelFooter,
    // COMPONENT EXPORTS
    };
    

    Then in my plopfile.js config, I added these two steps to my actions config:

    module.exports = function (plop) {
        plop.setGenerator('component', {
            actions: [
                …
                {
                    path: '../../src/index.js',
                    pattern: /(\/\/ COMPONENT IMPORTS)/g,
                    template: 'import { {{name}} } from \'./components/{{name}}\';\n$1',
                    type: 'modify',
                },
                {
                    path: '../../src/index.js',
                    pattern: /(\/\/ COMPONENT EXPORTS)/g,
                    template: '\t{{name}},\n$1',
                    type: 'modify',
                },
            ],
            description: 'New React Component',
            prompts: [
                …
            ],
        })
    };
    

    All new components are automatically added to the index.js file.