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

uneject and recreate ReactJS Charlotte

uneject and recreate ReactJS Charlotte

Avatar for Mark Pedrotti

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