-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Next.js example to check bundle size on web #3650
Changes from 14 commits
323ad19
0f3202d
21a787e
c690993
076b943
834eaf9
9999093
78a4295
2c3022a
ce9d566
8bb33a8
3f0a0ab
8743774
d907f36
9bd99b9
f19fe96
976e04b
9726c86
9f9c34a
889dc4e
31c8f9a
e32e2ae
aef5000
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
name: Check bundle size on web | ||
on: | ||
pull_request: | ||
paths: | ||
- .github/workflows/check-bundle-size.yml | ||
- 'src/**' | ||
- 'NextExample/**' | ||
- '*' | ||
push: | ||
branches: | ||
- main | ||
|
||
env: | ||
MAX_SIZE_KB: 30 | ||
|
||
jobs: | ||
check: | ||
runs-on: ubuntu-latest | ||
concurrency: | ||
group: check-bundle-size-${{ github.ref }} | ||
cancel-in-progress: true | ||
steps: | ||
- name: Checkout Git repository | ||
uses: actions/checkout@v3 | ||
|
||
- name: Install Reanimated node_modules | ||
run: yarn install --frozen-lockfile | ||
|
||
- name: Build Reanimated package | ||
run: ./createNPMPackage.sh nightly | ||
|
||
- name: Install NextExample node_modules | ||
working-directory: NextExample | ||
run: yarn install --frozen-lockfile | ||
|
||
- name: Install Reanimated package | ||
working-directory: NextExample | ||
run: yarn add file:`find .. -name "react-native-reanimated-*.tgz"` | ||
|
||
- name: Compile production build | ||
working-directory: NextExample | ||
run: yarn next build | tee output.txt | ||
|
||
- name: Check bundle size | ||
working-directory: NextExample | ||
run: if [[ $SIZE_KB -gt $MAX_SIZE_KB ]]; then false || echo "Bundle size is greater than $MAX_SIZE_KB kB." ; fi |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
.pnpm-debug.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
|
||
.expo | ||
.node_modules | ||
.next |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"semi": false, | ||
"useTabs": false, | ||
"singleQuote": true | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
# React Native Web example | ||
|
||
This example features how to use [react-native-web](https://github.com/necolas/react-native-web) to bring the platform-agnostic Components and APIs of React Native to the web. | ||
|
||
> **High-quality user interfaces**: React Native for Web makes it easy to create fast, adaptive web UIs in JavaScript. It provides native-like interactions, support for multiple input modes (touch, mouse, keyboard), optimized vendor-prefixed styles, built-in support for RTL layout, built-in accessibility, and integrates with React Dev Tools. | ||
> | ||
> **Write once, render anywhere**: React Native for Web interoperates with existing React DOM components and is compatible with the majority of the React Native API. You can develop new components for native and web without rewriting existing code. React Native for Web can also render to HTML and critical CSS on the server using Node.js. | ||
|
||
## Deploy your own | ||
|
||
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-react-native-web) | ||
|
||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-react-native-web&project-name=with-react-native-web&repository-name=with-react-native-web) | ||
|
||
## How to use | ||
|
||
Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: | ||
|
||
```bash | ||
npx create-next-app --example with-react-native-web with-react-native-web-app | ||
``` | ||
|
||
```bash | ||
yarn create next-app --example with-react-native-web with-react-native-web-app | ||
``` | ||
|
||
```bash | ||
pnpm create next-app --example with-react-native-web with-react-native-web-app | ||
``` | ||
|
||
Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
tomekzaw marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"name": "NextExample", | ||
"displayName": "NextExample" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module.exports = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if we should use the reanimated SWC plug-in instead of Babel? Or perhaps do a run with and a run without it, using an env variable? For reference: https://github.com/showtime-xyz/showtime-frontend/blob/staging/apps/next/next.config.js#L91-L99 This isn’t a requirement for this PR, but would be useful for testing. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea, we can test the SWC plugin as well once it's merged (in a separate PR). |
||
presets: ['next/babel', ['babel-preset-expo', { jsxRuntime: 'automatic' }]], | ||
plugins: [ | ||
['@babel/plugin-proposal-class-properties', { loose: true }], | ||
['@babel/plugin-proposal-private-methods', { loose: true }], | ||
['@babel/plugin-proposal-private-property-in-object', { loose: true }], | ||
'react-native-reanimated/plugin', | ||
], | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
// @ts-check | ||
|
||
const enabled = process.env.ANALYZE === 'true' | ||
|
||
if (enabled) { | ||
console.log('[next-config] Analyzing bundle size...') | ||
} | ||
|
||
const withNextBundleAnalyzer = require('@next/bundle-analyzer')({ | ||
enabled, | ||
}) | ||
|
||
const withTM = require('next-transpile-modules')(['react-native-reanimated']) | ||
|
||
const compose = require('next-compose-plugins') | ||
|
||
const { withExpo } = require('@expo/next-adapter') | ||
|
||
module.exports = compose( | ||
[withTM, withNextBundleAnalyzer, [withExpo, { projectRoot: __dirname }]], | ||
/** @type {import('next').NextConfig} */ | ||
{ | ||
webpack5: true, | ||
eslint: { | ||
ignoreDuringBuilds: true, | ||
}, | ||
webpack(config, _options) { | ||
// config.resolve.alias = { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you could make this point to the locally-built folder. |
||
// ...config.resolve.alias, | ||
// 'react-native-reanimated': require('path').resolve( | ||
// __dirname, | ||
// 'lib/react-native-reanimated/src/index.js' | ||
// ), | ||
// } | ||
|
||
return config | ||
}, | ||
} | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
{ | ||
"private": true, | ||
"scripts": { | ||
"dev": "next", | ||
"build": "next build", | ||
"start": "next start", | ||
"analyze": "ANALYZE=true next build", | ||
"cache:clear": "rm -rf .expo .next node_modules/.cache" | ||
}, | ||
"dependencies": { | ||
"next": "latest", | ||
"raf": "^3.4.1", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"react-native-reanimated": "3.0.0-rc.3", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any option to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. an easier method is probably to un-comment the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this approach support fast-refresh also when changing Reanimated codebase, e.g. |
||
"react-native-web": "^0.18.9" | ||
}, | ||
"devDependencies": { | ||
"@expo/config": "^7.0.1", | ||
"@expo/next-adapter": "^4.0.12", | ||
"@next/bundle-analyzer": "^12.3.1", | ||
"babel-plugin-react-native-web": "^0.18.9", | ||
"next-compose-plugins": "^2.2.1", | ||
"next-transpile-modules": "^9.0.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import 'raf/polyfill' | ||
|
||
export default function MyApp({ Component, pageProps }) { | ||
return <Component {...pageProps} /> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from '@expo/next-adapter/document' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import { StyleSheet, Text, View } from 'react-native' | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
alignItems: 'center', | ||
flexGrow: 1, | ||
justifyContent: 'center', | ||
}, | ||
link: { | ||
color: 'blue', | ||
}, | ||
textContainer: { | ||
alignItems: 'center', | ||
marginTop: 16, | ||
}, | ||
text: { | ||
alignItems: 'center', | ||
fontSize: 24, | ||
marginBottom: 24, | ||
}, | ||
}) | ||
|
||
export default function App(props) { | ||
return ( | ||
<View style={styles.container}> | ||
<Text accessibilityRole="header" style={styles.text}> | ||
React Native for Web & Next.js | ||
</Text> | ||
|
||
<Text style={styles.link} accessibilityRole="link" href={`/alternate`}> | ||
A universal link | ||
</Text> | ||
|
||
<View style={styles.textContainer}> | ||
<Text accessibilityRole="header" aria-level="2" style={styles.text}> | ||
Subheader | ||
</Text> | ||
</View> | ||
</View> | ||
) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Animated, { | ||
useAnimatedStyle, | ||
useSharedValue, | ||
withRepeat, | ||
withTiming, | ||
} from 'react-native-reanimated' | ||
import { StyleSheet, View } from 'react-native' | ||
|
||
import { useEffect } from 'react' | ||
|
||
export default function App() { | ||
const sv = useSharedValue(0) | ||
|
||
useEffect(() => { | ||
sv.value = 0 | ||
sv.value = withRepeat(withTiming(1), -1, true) | ||
}) | ||
|
||
const animatedStyle = useAnimatedStyle(() => { | ||
return { | ||
width: sv.value * 200 + 10, | ||
} | ||
}) | ||
|
||
return ( | ||
<View style={styles.container}> | ||
<Animated.View style={[styles.box, animatedStyle]} /> | ||
</View> | ||
) | ||
} | ||
|
||
const styles = StyleSheet.create({ | ||
container: { | ||
flex: 1, | ||
backgroundColor: '#fff', | ||
alignItems: 'center', | ||
justifyContent: 'center', | ||
}, | ||
box: { | ||
height: 100, | ||
backgroundColor: 'blue', | ||
}, | ||
}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The plan is that we will increase this value accordingly if needed.