Skip to content

Commit f8a535c

Browse files
authored
Add support for modern Expo (#132)
1 parent 5c6c38b commit f8a535c

File tree

2 files changed

+66
-13
lines changed

2 files changed

+66
-13
lines changed

.github/workflows/test.yml

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ env:
1111
NODEJS_VERSION: 24
1212

1313
jobs:
14-
test:
14+
pure_rn:
1515
name: Analyze bundle with React Native ${{ matrix.rn-version }}
1616
runs-on: ubuntu-latest
1717
strategy:
1818
matrix:
19-
rn-version: [latest, 0.83.4, 0.82.1]
19+
rn-version: [latest, 0.83.4, 0.82.1] # Three latest major versions of React Native
2020
steps:
2121
- name: Checkout
2222
uses: actions/checkout@v6
@@ -39,5 +39,36 @@ jobs:
3939
set -x # print all executed commands
4040
npx @react-native-community/cli@latest init ${{ env.APP_NAME }} --version ${{ matrix.rn-version }} --skip-git-init --install-pods false --pm yarn
4141
cd ${{ env.APP_NAME }}
42-
yarn add react-native-bundle-visualizer@portal:${{ github.workspace }}
42+
yarn add react-native-bundle-visualizer@portal:${{ github.workspace }} # yarn v2+ syntax
4343
yarn run react-native-bundle-visualizer --verbose --error-on-fail
44+
45+
expo:
46+
name: Analyze bundle with Expo default@sdk-${{ matrix.expo-sdk }}
47+
runs-on: ubuntu-latest
48+
strategy:
49+
matrix:
50+
expo-sdk: [ 55, 54, 53 ] # Three latest major Expo SDK versions
51+
steps:
52+
- name: Checkout
53+
uses: actions/checkout@v6
54+
55+
- name: Use Node.js ${{ env.NODEJS_VERSION }}
56+
uses: actions/setup-node@v6
57+
with:
58+
node-version: ${{ env.NODEJS_VERSION }}
59+
cache: 'yarn'
60+
61+
- name: Install node_modules in ${{ github.workspace }}
62+
run: yarn install --frozen-lockfile
63+
64+
- name: Install Expo and run the visualizer
65+
working-directory: /tmp
66+
shell: bash
67+
env:
68+
YARN_ENABLE_IMMUTABLE_INSTALLS: false
69+
run: |
70+
set -x # print all executed commands
71+
yarn create expo-app ${{ env.APP_NAME }} --template default@sdk-${{ matrix.expo-sdk }}
72+
cd ${{ env.APP_NAME }}
73+
yarn add ${{ github.workspace }} # yarn v1 syntax
74+
yarn run react-native-bundle-visualizer --verbose --expo --error-on-fail --bundle-output=./dist/ios.bundle

src/react-native-bundle-visualizer.js

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const path = require('path');
77
const argv = require('minimist')(process.argv.slice(2));
88
const execa = require('execa');
99
const open = require('open');
10-
const { explore } = require('source-map-explorer');
10+
const {explore} = require('source-map-explorer');
1111
const pkgJSON = JSON.parse(fs.readFileSync('./package.json'));
1212

1313
function sanitizeString(str) {
@@ -37,7 +37,7 @@ function getEntryPoint() {
3737
}
3838

3939
function getReactNativeBin() {
40-
const localBin = './node_modules/.bin/react-native';
40+
const localBin = isExpo ? 'node_modules/.bin/expo' : './node_modules/.bin/react-native';
4141
if (fs.existsSync(localBin)) return localBin;
4242
try {
4343
const reactNativeDir = path.dirname(
@@ -64,9 +64,9 @@ const isExpo = argv.expo || false;
6464
const dev = argv.dev || false;
6565
const verbose = argv.verbose || false;
6666
const resetCache = argv['reset-cache'] || false;
67-
const bundleOutput =
67+
let bundleOutput =
6868
argv['bundle-output'] || path.join(tmpDir, platform + '.bundle');
69-
const bundleOutputSourceMap = bundleOutput + '.map';
69+
let bundleOutputSourceMap = bundleOutput + '.map';
7070
const format = argv.format || 'html';
7171
const bundleOutputExplorerFile = path.join(outDir, 'explorer.' + format);
7272
const onlyMapped = !!argv['only-mapped'] || false;
@@ -85,8 +85,18 @@ if (fs.existsSync(bundleOutput)) {
8585
}
8686

8787
// Bundle
88+
const expoOutputDir = path.parse(bundleOutput).dir;
8889
console.log(chalk.green.bold('Generating bundle...'));
89-
const commands = [
90+
const commands = isExpo ? [
91+
'export',
92+
'--platform',
93+
platform,
94+
dev && '--dev',
95+
'--output-dir',
96+
expoOutputDir,
97+
'--no-bytecode',
98+
'--source-maps',
99+
].filter(Boolean) : [
90100
'bundle',
91101
'--platform',
92102
platform,
@@ -102,8 +112,12 @@ const commands = [
102112
isExpo,
103113
];
104114
if (resetCache) {
105-
commands.push('--reset-cache');
106-
commands.push(resetCache);
115+
if (isExpo) {
116+
commands.push('--clear');
117+
} else {
118+
commands.push('--reset-cache');
119+
commands.push(resetCache);
120+
}
107121
}
108122

109123
const reactNativeBin = getReactNativeBin();
@@ -114,6 +128,12 @@ bundlePromise.stdout.pipe(process.stdout);
114128
bundlePromise
115129
.then(
116130
() => {
131+
if (isExpo) {
132+
const jsFolder = `${expoOutputDir}/_expo/static/js/${platform}`;
133+
const files = fs.readdirSync(`${expoOutputDir}/_expo/static/js/${platform}`);
134+
bundleOutput = jsFolder + '/' + files.find((file) => file.endsWith('.js'));
135+
bundleOutputSourceMap = jsFolder + '/' + files.find((file) => file.endsWith('.js.map'));
136+
}
117137
// Log bundle-size
118138
const stats = fs.statSync(bundleOutput);
119139

@@ -136,8 +156,8 @@ bundlePromise
136156
console.log(
137157
chalk.green.bold(
138158
'Bundle is ' +
139-
Math.round((stats.size / (1024 * 1024)) * 100) / 100 +
140-
' MB in size'
159+
Math.round((stats.size / (1024 * 1024)) * 100) / 100 +
160+
' MB in size'
141161
) + deltaSuffix
142162
);
143163

@@ -183,7 +203,9 @@ bundlePromise
183203
});
184204
}
185205

186-
// Open output file
206+
console.log(
207+
chalk.green.bold('Opening bundle visualizer output file: ' + bundleOutputExplorerFile)
208+
)
187209
return open(bundleOutputExplorerFile);
188210
})
189211
.catch((error) => {

0 commit comments

Comments
 (0)