Upgrade to Pro — share decks privately, control downloads, hide ads and more …

uneject and recreate ReactJS Charlotte

uneject and recreate ReactJS Charlotte

Mark Pedrotti

February 08, 2017
Tweet

More Decks by Mark Pedrotti

Other Decks in Programming

Transcript

  1. Current situation: • Painful problem • Why it’s a problem

    Desired situation: • Surprising solution • How it solves the problem
  2. Painful problem, part 1 You need a critical feature that

    • isn’t yet in create-react-app • is already in a released version 
 of its devDependencies
 For example, Jest
  3. Why it’s a problem If you eject to upgrade dependencies

    You’re on your own. You can’t go back! But you don’t need full control of configuration…
  4. Surprising solution, part 1 If you eject on a branch,

    
 you can upgrade dependencies 
 to confirm a critical feature works.
  5. Painful problem, part 2 If you leave changes on a

    branch 
 until create-react-app catches up,
 you can expect merge conflicts 
 and rebase, oh my!
  6. Surprising solution, part 2 1. Confirm a feature on a

    branch. 2. Merge the branch to master. 3. Don’t tweak the ejected config. 4. Recreate an unejected config 
 when create-react-app catches up.
  7. How it solves the problem • Add a critical feature

    sooner 
 to develop your app better. • Don’t lose default configuration. • Find bugs in dependencies before they get into create-react-app.
  8. Review create-react-app Create React apps with no build configuration. There

    is just one build dependency. You don’t need to configure anything by default. You can “eject” to a custom setup at any time.
  9. Install the command-line interface npm install --global create-react-app # You

    install it as global instead of local. # It rarely changes. # It installs the current version of the react-scripts package.
  10. Create a new project create-react-app uneject-and-recreate cd uneject-and-recreate # For

    this example: in package.json, # I changed the version of "react-scripts" to "0.6.0" npm install
  11. Develop the app # Write components. For example, # src/TodoList.js

    # src/Todo.js # Run the app in development mode. npm start # Build the app for production. npm build
  12. Test the app # Install devDependencies for tests. npm install

    --save-dev --save-exact react-test-renderer # Write tests. Jest finds: # …/__tests__/Todo-test.js # …/Todo.spec.js # …/Todo.test.js # Run the test watcher. npm test
  13. // src/Todo.test.js import React from 'react'; import renderer from 'react-test-renderer';

    import Todo from './Todo'; // or .. if test file is in __tests__ describe('Todo', () => { it('renders completed item', () => { const text = 'Modify a component'; expect(renderer.create( <Todo text={text} completed={true} onClick={jest.fn()} /> ).toJSON()).toMatchSnapshot(); }); });
  14. // src/__snapshots__/Todo.test.js.snap exports[`Todo renders completed item 1`] = ` <li

    onClick={[Function mockConstructor]} # style={ Object { "color": "green", "listStyleType": "disc" # } }> Modify a component </li> `;
  15. A valuable feature, my confirmation Snapshot improvements in Jest 16

    when react-scripts 0.6.0 had version 15.1.1 • Functions do not have names. • Objects and Arrays have trailing commas.
  16. A critical feature, my motivation toMatchObject assertion in Jest 18

    and 19 while react-scripts 0.8.5 has version 17.0.2 • Match a subset of the properties of an object. • Support asymmetric matchers as in toEqual.
  17. Create a new branch and then eject git checkout -b

    jest-snapshot-improvements npm run eject Are you sure you want to eject? This action is permanent. [y/N] y git add --all git commit -m "eject from react-scripts 0.6.0" # A tag is optional. We’ll refer to this commit when we uneject. git tag eject-from-0.6.0
  18. Confirm the critical feature npm test # Press a to

    run all tests. # Because we have committed # the file we need to test. # By default, create-react-app runs tests # related to files changed since last commit.
  19. Update the snapshot improvements # Press u to update failing

    snapshots. # Meaning of green and red # is opposite to GitHub. # Removed function name # Added trailing comma
  20. // src/__snapshots__/Todo.test.js.snap exports[`Todo renders completed item 1`] = ` <li

    onClick={[Function]} $ style={ Object { "color": "green", "listStyleType": "disc", $ } }> Modify a component </li> `;
  21. Merge the branch to master git status # modified: package.json

    # modified: src/__snapshots__/Todo.test.js.snap git commit -am "upgrade snapshot tests to Jest 16.0.0" git checkout master git merge jest-snapshot-improvements
  22. Recreate an unejected config, part 1 # Which files were

    added compared to the commit before you ejected? git diff eject-from-0.6.0~1 eject-from-0.6.0 --name-status # Remove 2 files and 2 subdirectories # that were added when you ejected. git rm .babelrc git rm .eslintrc git rm -r config/ git rm -r scripts/
  23. Recreate an unejected config, part 2 # How did the

    modified file change since the commit when you ejected? git diff eject-from-0.6.0 HEAD -- package.json # - "jest": "15.1.1", # + "jest": "16.0.0", # Revert the modified file to the commit before you ejected. git checkout eject-from-0.6.0~1 -- package.json # Because you only upgraded Jest, didn’t tweak the ejected config, # edit package.json only to upgrade "react-scripts" to "0.7.0"
  24. Recreate an unejected config, part 3 # Remove all, in

    case the upgraded dependencies are now obsolete. # For example, Jest 16.0.0 rm -rf node_modules npm install npm list jest [email protected] "#$ [email protected] "## [email protected]
  25. Confirm the critical feature again npm test # Press a

    to run all tests. # Because we have committed # the file we need to test. git commit -am "uneject to react-scripts 0.7.0"
  26. Conclusion • If a feature is critical… • If you

    work carefully… • Then you can move fast! It’s like The Hobbit: There and Back Again