Skip to content

Commit

Permalink
feat(cli): add basic static rendering for router projects (expo#21572)
Browse files Browse the repository at this point in the history
# Why

- Implement an experimental static rendering system for Metro websites
using Expo Router.
- Behavior is undocumented and highly experimental.

<!--
Please describe the motivation for this PR, and link to relevant GitHub
issues, forums posts, or feature requests.
-->

# How

- Add support to `start` and `export` which pre-renders static web pages
to HTML to improve SEO support on web.
- The system implements [React Navigation's
SSR](https://reactnavigation.org/docs/server-rendering) support.
- Head elements can be used with `import { Head } from
'expo-router/head'`.
- The root HTML is not exposed to the user.
- There are no data fetching mechanisms.
- There's no ability to provide a 404 page or other server features.


<!--
How did you build this feature or fix this bug and why?
-->

# Test Plan

- e2e test for exporting a router project statically.
- `EXPO_USE_STATIC=1 yarn expo` -> websites are pre-rendered before
being served.
- `EXPO_USE_STATIC=1 yarn expo export -p web` -> static routes are
rendered to static HTML files by the same name (dynamic routes are not
supported).


<!--
Please describe how you tested this change and how a reviewer could
reproduce your test, especially if this PR does not include automated
tests! If possible, please also provide terminal output and/or
screenshots demonstrating your test/reproduction.
-->

# Checklist

<!--
Please check the appropriate items below if they apply to your diff.
This is required for changes to Expo modules.
-->

- [ ] Documentation is up to date to reflect these changes (eg:
https://docs.expo.dev and README.md).
- [ ] Conforms with the [Documentation Writing Style
Guide](https://github.com/expo/expo/blob/main/guides/Expo%20Documentation%20Writing%20Style%20Guide.md)
- [ ] This diff will work correctly for `expo prebuild` & EAS Build (eg:
updated a module plugin).

---------

Co-authored-by: Expo Bot <[email protected]>
  • Loading branch information
EvanBacon and expo-bot authored Mar 13, 2023
1 parent b34a3e1 commit 0a6ddb2
Show file tree
Hide file tree
Showing 29 changed files with 1,316 additions and 286 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ templates/**/android/app/build
templates/**/Pods/**
templates/**/Podfile.lock
templates/**/yarn.lock
templates/**/*.tgz

# EYW template
/packages/expo-yarn-workspaces/workspace-template/yarn.lock
Expand Down
1 change: 1 addition & 0 deletions packages/@expo/cli/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
- Reduce install prompt. ([#21264](https://github.com/expo/expo/pull/21264) by [@EvanBacon](https://github.com/EvanBacon))
- Improve multi-target iOS scheme resolution for `expo run:ios`. ([#21240](https://github.com/expo/expo/pull/21240) by [@EvanBacon](https://github.com/EvanBacon))
- Added experimental react-devtools integration. ([#21462](https://github.com/expo/expo/pull/21462) by [@kudo](https://github.com/kudo))
- Add experimental static rendering for Metro web in Expo Router. ([#21572](https://github.com/expo/expo/pull/21572) by [@EvanBacon](https://github.com/EvanBacon))
- Add experimental inspector proxy to handle more CDP requests. ([#21449](https://github.com/expo/expo/pull/21449) by [@byCedric](https://github.com/byCedric))
- Add inspector proxy workarounds for known issues with vscode debugger and Hermes CDP messages. ([#21560](https://github.com/expo/expo/pull/21560) by [@byCedric](https://github.com/byCedric))

Expand Down
261 changes: 261 additions & 0 deletions packages/@expo/cli/e2e/__tests__/__snapshots__/export-test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`server runs \`npx expo export -p web\` for static rendering 1`] = `
"<!DOCTYPE html><html lang="en" style="height:100%"><head><title data-rh="true">About | Website</title><meta data-rh="true" name="fake" content="bar"/><meta data-rh="true" name="description" content="About page"/><meta charSet="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=edge"/><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1.00001,viewport-fit=cover"/><style id="expo-reset">
html, body, #root {
-webkit-overflow-scrolling: touch;
}
#root {
display: flex;
flex-direction: column;
height: 100%;
}
html {
scroll-behavior: smooth;
-webkit-text-size-adjust: 100%;
}
body {
/* Allows you to scroll below the viewport; default value is visible */
overflow-y: auto;
overscroll-behavior-y: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
-ms-overflow-style: scrollbar;
}
</style><style id="react-native-stylesheet">[stylesheet-group="0"]{}
body{margin:0;}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0;}
html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0);}
input::-webkit-search-cancel-button,input::-webkit-search-decoration,input::-webkit-search-results-button,input::-webkit-search-results-decoration{display:none;}
[stylesheet-group="1"]{}
.css-11aywtz{-moz-appearance:textfield;-webkit-appearance:none;background-color:rgba(0,0,0,0.00);border-bottom-left-radius:0px;border-bottom-right-radius:0px;border-top-left-radius:0px;border-top-right-radius:0px;border:0 solid black;box-sizing:border-box;font:14px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;margin:0px;padding:0px;resize:none;}
.css-175oi2r{align-items:stretch;background-color:rgba(0,0,0,0.00);border:0 solid black;box-sizing:border-box;display:flex;flex-basis:auto;flex-direction:column;flex-shrink:0;list-style:none;margin:0px;min-height:0px;min-width:0px;padding:0px;position:relative;text-decoration:none;z-index:0;}
.css-1qaijid{background-color:rgba(0,0,0,0.00);border:0 solid black;box-sizing:border-box;color:inherit;display:inline;font:inherit;list-style:none;margin:0px;padding:0px;text-align:inherit;text-decoration:none;white-space:inherit;word-wrap:break-word;}
.css-1rynq56{background-color:rgba(0,0,0,0.00);border:0 solid black;box-sizing:border-box;color:rgba(0,0,0,1.00);display:inline;font:14px -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;list-style:none;margin:0px;padding:0px;text-align:inherit;text-decoration:none;white-space:pre-wrap;word-wrap:break-word;}
.css-9pa8cd{bottom:0px;height:100%;left:0px;opacity:0;position:absolute;right:0px;top:0px;width:100%;z-index:-1;}
[stylesheet-group="2"]{}
.r-13awgt0{flex:1;}
.r-1a976y8{border-bottom-left-radius:19px;border-bottom-right-radius:19px;border-top-left-radius:19px;border-top-right-radius:19px;}
.r-1awa8pu{border-bottom-color:rgba(101,119,134,1.00);border-left-color:rgba(101,119,134,1.00);border-right-color:rgba(101,119,134,1.00);border-top-color:rgba(101,119,134,1.00);}
.r-1bq2mok{margin:3px;}
.r-1d4xg89{border-bottom-color:rgba(170,184,194,1.00);border-left-color:rgba(170,184,194,1.00);border-right-color:rgba(170,184,194,1.00);border-top-color:rgba(170,184,194,1.00);}
.r-1j16mh1{border-bottom-left-radius:100%;border-bottom-right-radius:100%;border-top-left-radius:100%;border-top-right-radius:100%;}
.r-1jkafct{border-bottom-left-radius:2px;border-bottom-right-radius:2px;border-top-left-radius:2px;border-top-right-radius:2px;}
.r-1jyn79y{border-bottom-color:rgba(0,150,136,1.00);border-left-color:rgba(0,150,136,1.00);border-right-color:rgba(0,150,136,1.00);border-top-color:rgba(0,150,136,1.00);}
.r-1phboty{border-bottom-style:solid;border-left-style:solid;border-right-style:solid;border-top-style:solid;}
.r-1udh08x{overflow-x:hidden;overflow-y:hidden;}
.r-4a18lf{border-bottom-color:rgba(255,0,0,1.00);border-left-color:rgba(255,0,0,1.00);border-right-color:rgba(255,0,0,1.00);border-top-color:rgba(255,0,0,1.00);}
.r-60ke3l{border-bottom-color:rgba(0,128,0,1.00);border-left-color:rgba(0,128,0,1.00);border-right-color:rgba(0,128,0,1.00);border-top-color:rgba(0,128,0,1.00);}
.r-6koalj{display:flex;}
.r-9x6qib{border-bottom-color:rgba(204,214,221,1.00);border-left-color:rgba(204,214,221,1.00);border-right-color:rgba(204,214,221,1.00);border-top-color:rgba(204,214,221,1.00);}
.r-crgep1{margin:0px;}
.r-d045u9{border-bottom-width:2px;border-left-width:2px;border-right-width:2px;border-top-width:2px;}
.r-d23pfw{padding:24px;}
.r-edyy15{padding:8px;}
.r-fx7oqy{border-bottom-color:rgba(0,0,255,1.00);border-left-color:rgba(0,0,255,1.00);border-right-color:rgba(0,0,255,1.00);border-top-color:rgba(0,0,255,1.00);}
.r-krxsd3{display:-webkit-box;}
.r-kshhro{border-bottom-color:rgba(50,50,50,1.00);border-left-color:rgba(50,50,50,1.00);border-right-color:rgba(50,50,50,1.00);border-top-color:rgba(50,50,50,1.00);}
.r-rs99b7{border-bottom-width:1px;border-left-width:1px;border-right-width:1px;border-top-width:1px;}
.r-t60dpp{padding:0px;}
.r-xoduu5{display:inline-flex;}
.r-ywje51{margin:auto;}
[stylesheet-group="2.1"]{}
.r-1e081e0{padding-left:12px;padding-right:12px;}
.r-1guathk{padding-left:24px;padding-right:24px;}
.r-1jgb5lz{margin-left:auto;margin-right:auto;}
.r-1mi5vxm{margin-left:11px;margin-right:11px;}
.r-1ydw1k6{margin-left:16px;margin-right:16px;}
.r-1yzf0co{padding-bottom:16px;padding-top:16px;}
.r-fpx60m{margin-bottom:3px;margin-top:3px;}
.r-s1qlax{padding-left:4px;padding-right:4px;}
.r-usiww2{margin-bottom:12px;margin-top:12px;}
[stylesheet-group="2.2"]{}
.r-105ug2t{pointer-events:auto!important;}
.r-10ptun7{height:16px;}
.r-10x49cs{font-size:10px;}
.r-10xqauy{padding-top:env(safe-area-inset-top);}
.r-11j9u27{visibility:hidden;}
.r-11mpjr4{background-color:rgba(223,223,223,1.00);}
.r-11udlyb{background-color:rgba(0,150,136,1.00);}
.r-11yh6sk{overflow-x:hidden;}
.r-127358a{animation-name:r-9p3sdl;}
.r-12vffkv>*{pointer-events:auto;}
.r-12vffkv{pointer-events:none!important;}
.r-13qz1uu{width:100%;}
.r-13tjlyg{transition-duration:0.1s;}
.r-1472mwg{height:24px;}
.r-14eup4l{top:3px;}
.r-14lw9ot{background-color:rgba(255,255,255,1.00);}
.r-14sbq61{background-color:rgba(33,150,243,1.00);}
.r-150rngu{-webkit-overflow-scrolling:touch;}
.r-15651gt{transform:scaleX(1);}
.r-16y2uox{flex-grow:1;}
.r-16z8t6w{;}
.r-173mn98{align-self:flex-end;}
.r-1777fci{justify-content:center;}
.r-17bb2tj{animation-duration:0.75s;}
.r-17leim2{background-repeat:repeat;}
.r-17s6mgv{justify-content:flex-end;}
.r-18u1ve8{color:rgba(255,255,255,0.40);}
.r-18u37iz{flex-direction:row;}
.r-19qrga8{margin-top:3px;}
.r-19u6a5r{margin-left:12px;}
.r-19wmn03{width:20px;}
.r-19z077z{touch-action:none;}
.r-1a2p6p6{-webkit-text-decoration-style:solid;text-decoration-style:solid;}
.r-1abnn5w{animation-play-state:paused;}
.r-1acpoxo{width:36px;}
.r-1awozwy{align-items:center;}
.r-1ay1djp{animation-duration:1s;}
.r-1b43r93{font-size:14px;}
.r-1c6unfx{forced-color-adjust:none;}
.r-1d2f490{left:0px;}
.r-1d5kdc7{flex-direction:column-reverse;}
.r-1ddef8g{-webkit-text-decoration-line:underline;text-decoration-line:underline;}
.r-1dernwh{height:70%;}
.r-1ei5mc7{cursor:inherit;}
.r-1euagl{border-bottom-color:rgba(50,50,50,1.00);}
.r-1euycsn{flex-direction:row-reverse;}
.r-1ewcgjf{box-shadow:0px 1px 3px rgba(0,0,0,0.5);}
.r-1fe0xdi{left:0%;}
.r-1ff274t{text-align:right;}
.r-1habvwh{align-items:flex-start;}
.r-1i10wst{font-size:18px;}
.r-1i6wzkk{-moz-transition-property:opacity;-webkit-transition-property:opacity;transition-property:opacity;}
.r-1i93rbr{right:0%;}
.r-1ielgck{animation-duration:300ms;}
.r-1iln25a{word-wrap:normal;}
.r-1inkyih{font-size:17px;}
.r-1iusvr4{flex-basis:0px;}
.r-1janqcz{width:16px;}
.r-1joea0r{margin-left:20px;}
.r-1kihuf0{align-self:center;}
.r-1knl56f{animation-name:r-1hunrpy;}
.r-1ldzwu0{animation-timing-function:linear;}
.r-1loqt21{cursor:pointer;}
.r-1mlwlqe{flex-basis:auto;}
.r-1mrlafo{background-position:0;}
.r-1muvv40{animation-iteration-count:infinite;}
.r-1niwhzg{background-color:rgba(0,0,0,0.00);}
.r-1ny4l3l{outline-style:none;}
.r-1ocf4r9{scroll-snap-type:y mandatory;}
.r-1oszu61{align-items:stretch;}
.r-1otgn73{touch-action:manipulation;}
.r-1p0dtai{bottom:0px;}
.r-1pi2tsx{height:100%;}
.r-1pm8pkb{font-family:Courier;}
.r-1qc3rpd{transform:scaleY(-1);}
.r-1qd0xha{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;}
.r-1qdbj55{animation-name:r-ndfo3d;}
.r-1r8g8re{height:36px;}
.r-1rnoaur{overflow-y:auto;}
.r-1ro7rbe{right:100%;}
.r-1sg8ghl{z-index:1000;}
.r-1sncvnh{transform:translateZ(0px);}
.r-1sxrcry{background-size:auto;}
.r-1ub1aon{transform:translateY(100%);}
.r-1udbk01{text-overflow:ellipsis;}
.r-1uxf3jb{min-width:25px;}
.r-1uypc71{animation-timing-function:ease-in;}
.r-1ve781c{top:7px;}
.r-1wbh5a2{flex-shrink:1;}
.r-1wrzk55{margin-left:-14.5px;}
.r-1wtj0ep{justify-content:space-between;}
.r-1wyyakw{z-index:-1;}
.r-1xcajam{position:fixed;}
.r-1xnzce8{-moz-user-select:text;-webkit-user-select:text;user-select:text;}
.r-1xzupcd{width:13px;}
.r-2eszeu::-webkit-scrollbar{display:none}
.r-2eszeu{scrollbar-width:none;}
.r-30o5oe{-moz-appearance:none;-ms-appearance:none;-webkit-appearance:none;appearance:none;}
.r-356f0p{letter-spacing:0.35px;}
.r-3i2nvb{font-size:36px;}
.r-3s2u2q{white-space:nowrap;}
.r-417010{z-index:0;}
.r-4gszlv{background-size:cover;}
.r-4v7adb{height:5px;}
.r-5kkj8d{border-top-width:1px;}
.r-60vfwk{min-width:1px;}
.r-633pao{pointer-events:none!important;}
.r-6dt33c{opacity:1;}
.r-6gpygo{margin-bottom:12px;}
.r-6taxm2:-ms-input-placeholder{color:var(--placeholderTextColor);opacity:1;}
.r-6taxm2::-moz-placeholder{color:var(--placeholderTextColor);opacity:1;}
.r-6taxm2::-webkit-input-placeholder{color:var(--placeholderTextColor);opacity:1;}
.r-6taxm2::placeholder{color:var(--placeholderTextColor);opacity:1;}
.r-76blku{height:21px;}
.r-7b7h2f{left:100%;}
.r-7cikom{font-size:inherit;}
.r-7q8q6z{cursor:default;}
.r-8akbws{-webkit-box-orient:vertical;}
.r-97e31f{padding-bottom:env(safe-area-inset-bottom);}
.r-9ji8r7{transform:translateY(0%);}
.r-adyw6z{font-size:20px;}
.r-ah5dr5>*{pointer-events:none;}
.r-ah5dr5{pointer-events:auto!important;}
.r-buy8e9{overflow-y:hidden;}
.r-bv2aro{padding-left:env(safe-area-inset-left);}
.r-c68hjy{color:rgba(161,161,161,1.00);}
.r-cpa5s6{scroll-snap-align:start;}
.r-cqee49{color:rgba(0,0,0,1.00);}
.r-dkge59{background-color:rgba(170,184,194,1.00);}
.r-dnmrzs{max-width:100%;}
.r-eafdt9{transition-duration:0.15s;}
.r-ehq7j7{background-size:contain;}
.r-eqz5dr{flex-direction:column;}
.r-fdjqy7{text-align:left;}
.r-g3mlsw{animation-name:r-t2lo5v;}
.r-gtdqiz{position:-webkit-sticky;position:sticky;}
.r-h2q2x{transform:scaleX(-1);}
.r-hxflta{padding-right:env(safe-area-inset-right);}
.r-icoktb{opacity:0.5;}
.r-ipm5af{top:0px;}
.r-j300sb{animation-name:r-1rx4pb;}
.r-jwli3a{color:rgba(255,255,255,1.00);}
.r-k200y{align-self:flex-start;}
.r-kemksi{background-color:rgba(0,0,0,1.00);}
.r-kzbkwu{padding-bottom:12px;}
.r-l4djrs{left:3px;}
.r-lltvgl{overflow-x:auto;}
.r-lrsllp{width:24px;}
.r-lrvibr{-moz-user-select:none;-webkit-user-select:none;user-select:none;}
.r-majxgm{font-weight:500;}
.r-mfh4gg{scroll-snap-type:x mandatory;}
.r-mhe3cw{z-index:10;}
.r-n6v787{font-size:13px;}
.r-n9uq8g{;}
.r-nvplwv{animation-timing-function:ease-out;}
.r-obd0qt{align-items:flex-end;}
.r-orgf3d{opacity:0;}
.r-q4m81j{text-align:center;}
.r-qfi6ny{top:30000px;}
.r-qklmqi{border-bottom-width:1px;}
.r-r5vmyo{z-index:1002;}
.r-rs94m5{background-image:url("data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICB2aWV3Qm94PSIwIDAgMSAxIgogICBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWluWU1pbiBtZWV0Ij4KICA8cGF0aAogICAgIGQ9Ik0gMC4wNDAzODA1OSwwLjYyNjc3NjcgMC4xNDY0NDY2MSwwLjUyMDcxMDY4IDAuNDI5Mjg5MzIsMC44MDM1NTMzOSAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IE0gMC4yMTcxNTcyOSwwLjgwMzU1MzM5IDAuODUzNTUzMzksMC4xNjcxNTcyOSAwLjk1OTYxOTQxLDAuMjczMjIzMyAwLjMyMzIyMzMsMC45MDk2MTk0MSB6IgogICAgIGlkPSJyZWN0Mzc4MCIKICAgICBzdHlsZT0iZmlsbDojZmZmZmZmO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTpub25lIiAvPgo8L3N2Zz4K");}
.r-sfbmgh{z-index:9999;}
.r-tsynxw{text-transform:uppercase;}
.r-u6sd8q{background-repeat:no-repeat;}
.r-u8s1d{position:absolute;}
.r-u92y06{background-color:rgba(255,165,0,1.00);}
.r-vvn4in{background-position:center;}
.r-vw2c0b{font-weight:bold;}
.r-wfqgy4{transition-duration:100ms;}
.r-x3cy2q{background-size:100% 100%;}
.r-xx3c9p{animation-name:r-imtty0;}
.r-yie26v{z-index:1001;}
.r-z80fyv{height:20px;}
.r-zchlnj{right:0px;}
@-webkit-keyframes r-1hunrpy{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
@-webkit-keyframes r-1rx4pb{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
@-webkit-keyframes r-9p3sdl{0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}}
@-webkit-keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
@-webkit-keyframes r-ndfo3d{0%{transform:translateY(0%);}100%{transform:translateY(100%);}}
@-webkit-keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}
@keyframes r-1hunrpy{0%{transform:translateY(100%);}100%{transform:translateY(0%);}}
@keyframes r-1rx4pb{0%{transform:translateX(-100%);}100%{transform:translateX(400%);}}
@keyframes r-9p3sdl{0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}}
@keyframes r-imtty0{0%{opacity:0;}100%{opacity:1;}}
@keyframes r-ndfo3d{0%{transform:translateY(0%);}100%{transform:translateY(100%);}}
@keyframes r-t2lo5v{0%{opacity:1;}100%{opacity:0;}}</style></head><body style="height:100%;overflow:hidden"><div id="root"><div class="css-175oi2r" style="flex:1"><div class="css-175oi2r r-13awgt0"><div class="css-175oi2r r-13awgt0"><div class="css-175oi2r r-13awgt0"><div class="css-175oi2r r-13awgt0 r-1d5kdc7 r-1p0dtai r-1d2f490 r-u8s1d r-zchlnj r-ipm5af" style="background-color:rgba(242,242,242,1.00);display:flex"><div class="css-175oi2r r-13awgt0"><div class="css-175oi2r r-13awgt0"><div dir="auto" class="css-1rynq56" data-testid="content">About</div></div></div><div class="css-175oi2r"><div class="css-175oi2r r-12vffkv" style="position:absolute;left:0px;right:0px;top:0px;bottom:0px;z-index:0"><div class="css-175oi2r" style="flex:1;border-bottom-width:1px;background-color:rgba(255,255,255,1.00);border-bottom-color:rgba(216,216,216,1.00);box-shadow:0px 0px 0px rgba(216,216,216,1.00)"></div></div><div class="css-175oi2r r-12vffkv" style="height:64px"><div class="css-175oi2r r-633pao" style="height:0px"></div><div class="css-175oi2r r-1oszu61 r-13awgt0 r-18u37iz r-12vffkv"><div class="css-175oi2r r-12vffkv" style="justify-content:center;align-items:flex-start;margin-left:0px"></div><div class="css-175oi2r r-12vffkv" style="margin-right:16px;margin-left:16px;justify-content:center;max-width:-32px"><h1 dir="auto" role="heading" class="css-1rynq56 r-dnmrzs r-1udh08x r-1udbk01 r-3s2u2q r-1iln25a" style="font-size:18px;font-weight:500;color:rgba(28,28,30,1.00)">about</h1></div><div class="css-175oi2r r-12vffkv" style="justify-content:center;align-items:flex-end;flex-grow:1;flex-basis:0px;margin-right:0px"></div></div></div></div></div></div></div>;</div></div></div><script src="/bundles/[mock].js" defer></script></body></html>"
`;
40 changes: 22 additions & 18 deletions packages/@expo/cli/e2e/__tests__/config-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,26 +49,30 @@ it('runs `npx expo config --help`', async () => {
`);
});

it('runs `npx expo config --json`', async () => {
const projectName = 'basic-config';
const projectRoot = getRoot(projectName);
// Create the project root aot
await fs.mkdir(projectRoot, { recursive: true });
// Create a fake package.json -- this is a terminal file that cannot be overwritten.
await fs.writeFile(path.join(projectRoot, 'package.json'), '{ "version": "1.0.0" }');
await fs.writeFile(path.join(projectRoot, 'app.json'), '{ "expo": { "name": "foobar" } }');
it(
'runs `npx expo config --json`',
async () => {
const projectName = 'basic-config';
const projectRoot = getRoot(projectName);
// Create the project root aot
await fs.mkdir(projectRoot, { recursive: true });
// Create a fake package.json -- this is a terminal file that cannot be overwritten.
await fs.writeFile(path.join(projectRoot, 'package.json'), '{ "version": "1.0.0" }');
await fs.writeFile(path.join(projectRoot, 'app.json'), '{ "expo": { "name": "foobar" } }');

const results = await execute('config', projectName, '--json');
// @ts-ignore
const exp = JSON.parse(results.stdout);
const results = await execute('config', projectName, '--json');
// @ts-ignore
const exp = JSON.parse(results.stdout);

expect(exp.name).toEqual('foobar');
expect(exp.slug).toEqual('foobar');
expect(exp.platforms).toStrictEqual([]);
expect(exp.version).toBe('1.0.0');
expect(exp._internal.dynamicConfigPath).toBe(null);
expect(exp._internal.staticConfigPath).toMatch(/\/basic-config\/app\.json$/);
});
expect(exp.name).toEqual('foobar');
expect(exp.slug).toEqual('foobar');
expect(exp.platforms).toStrictEqual([]);
expect(exp.version).toBe('1.0.0');
expect(exp._internal.dynamicConfigPath).toBe(null);
expect(exp._internal.staticConfigPath).toMatch(/\/basic-config\/app\.json$/);
}, // Could take 45s depending on how fast npm installs
120 * 1000
);

it('throws on invalid project root', async () => {
expect.assertions(1);
Expand Down
Loading

0 comments on commit 0a6ddb2

Please sign in to comment.