Skip to content

Commit

Permalink
fix(metro-config): fix source map url with sentry (#30980)
Browse files Browse the repository at this point in the history
# Why

- when sentry mutates the src to add a comment, the bundle changes and
the source map url name is incorrect. This change recomputes the hash
name when the premodules change.

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

# How

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

# Test Plan

- Added a new e2e test.

<!--
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 `npx expo prebuild` & EAS Build
(eg: updated a module plugin).

---------

Co-authored-by: Expo Bot <[email protected]>
  • Loading branch information
EvanBacon and expo-bot authored Aug 15, 2024
1 parent 4391fc6 commit a6e59b1
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 4 deletions.
37 changes: 36 additions & 1 deletion apps/router-e2e/metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,42 @@ const path = require('path');
// Find the project and workspace directories
const projectRoot = __dirname;

const config = getDefaultConfig(projectRoot);
const config = getDefaultConfig(
projectRoot,

require('getenv').boolish('E2E_USE_MOCK_SERIALIZER_PLUGINS', false)
? {
// Mock the serializer plugins to inject a virtual module. This ensures that we compute correct source maps with tools like sentry.
unstable_beforeAssetSerializationPlugins: [
({ premodules, debugId }) => {
if (!debugId) {
return premodules;
}
const src = '// MOCK INJECTED VALUE';
return [
// Return a mock module.
{
dependencies: new Map(),
getSource: () => Buffer.from(src),
inverseDependencies: new Set(),
path: '__debugid__',
output: [
{
type: 'js/script/virtual',
data: {
code: src,
lineCount: 1,
map: [],
},
},
],
},
];
},
],
}
: undefined
);

const root = path.join(projectRoot, '../..');

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 @@ -27,6 +27,7 @@

### 🐛 Bug fixes

- Update source map URL when config mutates modules. ([#30980](https://github.com/expo/expo/pull/30980) by [@EvanBacon](https://github.com/EvanBacon))
- Use `react-server` resolution when experimental react canary support is enabled. ([#30747](https://github.com/expo/expo/pull/30747) by [@EvanBacon](https://github.com/EvanBacon))
- Fix server closing in headless run commands. ([#30432](https://github.com/expo/expo/pull/30432) by [@EvanBacon](https://github.com/EvanBacon))
- Fix resolver fields for SSR + native platforms. ([#29701](https://github.com/expo/expo/pull/29701) by [@EvanBacon](https://github.com/EvanBacon))
Expand Down
88 changes: 88 additions & 0 deletions packages/@expo/cli/e2e/__tests__/export/serializer-plugins.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/* eslint-env jest */
import execa from 'execa';
import fs from 'fs-extra';
import klawSync from 'klaw-sync';
import path from 'path';

import { runExportSideEffects } from './export-side-effects';
import {
bin,
expectChunkPathMatching,
getHtmlHelpers,
getPageHtml,
getRouterE2ERoot,
} from '../utils';

runExportSideEffects();

describe('exports with serializer plugins', () => {
const projectRoot = getRouterE2ERoot();
const outputName = 'dist-splitting-plugins';
const outputDir = path.join(projectRoot, outputName);

beforeAll(
async () => {
// E2E_USE_MOCK_SERIALIZER_PLUGIN=1 NODE_ENV=production EXPO_USE_STATIC=static E2E_ROUTER_SRC=static-rendering E2E_ROUTER_ASYNC=production EXPO_USE_FAST_RESOLVER=1 npx expo export -p web --source-maps --output-dir dist-static-splitting-plugins
await execa(
'node',
[bin, 'export', '-p', 'web', '--source-maps', '--output-dir', outputName],
{
cwd: projectRoot,
env: {
NODE_ENV: 'production',
E2E_USE_MOCK_SERIALIZER_PLUGINS: '1',
EXPO_USE_STATIC: 'static',
E2E_ROUTER_SRC: 'modal-splitting',
E2E_ROUTER_ASYNC: 'production',
EXPO_USE_FAST_RESOLVER: '1',
},
}
);
},
// Could take 45s depending on how fast the bundler resolves
560 * 1000
);

it('has source maps', async () => {
// List output files with sizes for snapshotting.
// This is to make sure that any changes to the output are intentional.
// Posix path formatting is used to make paths the same across OSes.
const files = klawSync(outputDir)
.map((entry) => {
if (entry.path.includes('node_modules') || !entry.stats.isFile()) {
return null;
}
return path.posix.relative(outputDir, entry.path);
})
.filter(Boolean);

const mapFiles = files.filter((file) => file?.endsWith('.map'));

// "_expo/static/js/web/_layout-e67451b6ca1f415eec1baf46b17d16c6.js.map",
expect(mapFiles).toEqual(
['_layout', 'index', 'index', 'modal'].map((file) =>
expect.stringMatching(new RegExp(`_expo\\/static\\/js\\/web\\/${file}-.*\\.js\\.map`))
)
);

for (const file of mapFiles) {
// Ensure the bundle does not contain a source map reference
const sourceMap = JSON.parse(fs.readFileSync(path.join(outputDir, file!), 'utf8'));
expect(sourceMap.version).toBe(3);
}

const jsFiles = files.filter((file) => file?.endsWith('.js'));

for (const file of jsFiles) {
// Ensure the bundle does not contain a source map reference
const jsBundle = fs.readFileSync(path.join(outputDir, file!), 'utf8');
expect(jsBundle).toMatch(/^\/\/\# sourceMappingURL=\/_expo\/static\/js\/web\/.*\.js\.map$/gm);
// expect(jsBundle).toMatch(/^\/\/\# sourceURL=\/_expo\/static\/js\/web\/index-.*\.js$/gm);
const mapFile = jsBundle.match(
/^\/\/\# sourceMappingURL=(\/_expo\/static\/js\/web\/.*\.js\.map)$/m
)?.[1];

expect(fs.existsSync(path.join(outputDir, mapFile!))).toBe(true);
}
});
});
1 change: 1 addition & 0 deletions packages/@expo/metro-config/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

### 🐛 Bug fixes

- Update source map URL when config mutates modules. ([#30980](https://github.com/expo/expo/pull/30980) by [@EvanBacon](https://github.com/EvanBacon))
- Terminate module source maps with a null mapping [upstream](https://github.com/facebook/metro/commit/96c6b893eb77b5929b6050d7189905232ddf6d6d). ([#30701](https://github.com/expo/expo/pull/30701) by [@EvanBacon](https://github.com/EvanBacon))
- Fix Typescript type export. ([#22410](https://github.com/expo/expo/pull/22410) by [@dcposch](https://github.com/dcposch])
- Account for the entire dependency tree when creating module name hashes. ([#30512](https://github.com/expo/expo/pull/30512) by [@EvanBacon](https://github.com/EvanBacon))
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a6e59b1

Please sign in to comment.