Skip to content

Commit 431d4c7

Browse files
authored
Simplify sandbox and optimize prefetching (codesandbox#402)
* Simplify sandbox and optimize prefetching * Add fallback for discrepancy in sw version * Fix standalone sandboxes * Fix standalone * Disable script altering * Don't inline babel worker * Inline the babel transpiler * Add 'as' attribute * Fix inlining * Preload workers * Tweaks * Change tests * Fix transpilers * Fix console.log * Don't inline sandbox worker code * Add test metadata * Allow custom arguments in integration test
1 parent 6bba393 commit 431d4c7

File tree

17 files changed

+410
-660
lines changed

17 files changed

+410
-660
lines changed

.circleci/config.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,11 @@ jobs:
6969
name: Test Integrations
7070
command: |
7171
sleep 6
72-
yarn test:integrations
72+
yarn test:integrations --ci --testResultsProcessor="jest-junit"
73+
environment:
74+
JEST_JUNIT_OUTPUT: "/tmp/test-results/js-test-results.xml"
75+
- store_test_results:
76+
path: /tmp/test-results
7377
- store_artifacts:
7478
path: packages/app/integration-tests/tests/__image_snapshots__/__diff_output__
7579
destination: image_snapshot_diff
@@ -83,7 +87,9 @@ jobs:
8387
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
8488
- run:
8589
name: Test
86-
command: yarn test
90+
command: yarn test --ci --testResultsProcessor="jest-junit"
91+
environment:
92+
JEST_JUNIT_OUTPUT: "reports/junit/js-test-results.xml"
8793

8894
lint:
8995
docker:

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
"start:dev_api":
1515
"lerna run start --parallel --ignore app & lerna run start:dev_api --scope app --stream",
1616
"test": "lerna run test",
17-
"test:integrations": "lerna run test:integrations --scope app --stream",
17+
"test:integrations": "lerna exec --scope app --stream -- yarn test:integrations",
1818
"lint": "lerna run lint",
1919
"add-contributor": "all-contributors add",
2020
"generate": "all-contributors generate",

packages/app/config/webpack.common.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module.exports = {
2424
require.resolve('./polyfills'),
2525
path.join(paths.sandboxSrc, 'index.js'),
2626
],
27+
'sandbox-startup': path.join(paths.sandboxSrc, 'startup.js'),
2728
}
2829
: {
2930
app: [
@@ -34,6 +35,7 @@ module.exports = {
3435
require.resolve('./polyfills'),
3536
path.join(paths.sandboxSrc, 'index.js'),
3637
],
38+
'sandbox-startup': path.join(paths.sandboxSrc, 'startup.js'),
3739
embed: [
3840
require.resolve('./polyfills'),
3941
path.join(paths.embedSrc, 'index.js'),
@@ -168,7 +170,7 @@ module.exports = {
168170
}),
169171
new HtmlWebpackPlugin({
170172
inject: true,
171-
chunks: ['common-sandbox', 'sandbox'],
173+
chunks: ['sandbox-startup', 'common-sandbox', 'sandbox'],
172174
filename: 'frame.html',
173175
template: paths.sandboxHtml,
174176
minify: __PROD__ && {

packages/app/integration-tests/tests/sandboxes.test.js

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,19 @@ const SANDBOXES = [
1919
'lp5rjr0z4z',
2020
'nOymMxyY',
2121
];
22-
23-
SANDBOXES.forEach(sandbox => {
24-
const id = sandbox.id || sandbox;
25-
const threshold = sandbox.threshold || 0.01;
22+
describe('sandboxes', () => {
2623
let browser = puppeteer.launch({
2724
args: ['--no-sandbox', '--disable-setuid-sandbox'],
2825
});
26+
afterAll(() => {
27+
browser.close();
28+
});
2929

30-
describe('sandboxes', () => {
31-
afterAll(() => {
32-
browser.close();
33-
});
30+
SANDBOXES.forEach(sandbox => {
31+
const id = sandbox.id || sandbox;
32+
const threshold = sandbox.threshold || 0.01;
3433

35-
it.concurrent(
34+
it(
3635
`loads the sandbox with id '${id}'`,
3736
async () => {
3837
browser = await browser;
@@ -51,8 +50,10 @@ SANDBOXES.forEach(sandbox => {
5150
},
5251
customSnapshotIdentifier: id.split('/').join('-'),
5352
});
53+
54+
await page.close();
5455
},
55-
1000 * 60 * 10 // 10 minutes for all tests in total
56+
1000 * 60 * 1
5657
);
5758
});
5859
});

packages/app/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@
5959
"husky": "^0.14.3",
6060
"jest": "^21.2.1",
6161
"jest-image-snapshot": "^1.0.1",
62+
"jest-junit": "^3.4.1",
6263
"jest-styled-components": "^4.9.0",
6364
"json-loader": "0.5.4",
6465
"object-assign": "^4.1.1",
@@ -159,21 +160,22 @@
159160
"react-redux": "^5.0.5",
160161
"react-router-dom": "^4.2.2",
161162
"react-router-redux": "next",
163+
"react-show": "^1.1.2",
162164
"react-split-pane": "^0.1.63",
163165
"react-stripe-elements": "^1.2.0",
164166
"react-tippy": "^0.14.0",
165167
"redbox-react": "^1.4.3",
166168
"redux": "^3.7.1",
167169
"reselect": "^3.0.1",
170+
"script-ext-html-webpack-plugin": "^1.8.8",
168171
"shelljs": "^0.7.8",
169172
"store": "^2.0.12",
170173
"styled-components": "^2.1.1",
171174
"svg-react-loader": "^0.4.4",
172175
"tern": "^0.21.0",
173176
"vue": "^2.5.2",
174177
"vue-template-compiler": "^2.5.2",
175-
"vue-template-es2015-compiler": "^1.6.0",
176-
"react-show": "^1.1.2"
178+
"vue-template-es2015-compiler": "^1.6.0"
177179
},
178180
"jest": {
179181
"roots": [

packages/app/src/app/components/sandbox/Preview/index.js

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import { debounce } from 'lodash';
88
import type { Module, Sandbox, Preferences, Directory } from 'common/types';
99

1010
import { frameUrl } from 'common/utils/url-generator';
11-
import { findMainModule } from 'app/store/entities/sandboxes/modules/selectors';
11+
import { getModulePath } from 'app/store/entities/sandboxes/modules/selectors';
1212
import sandboxActionCreators from 'app/store/entities/sandboxes/actions';
13+
1314
import shouldUpdate from './utils/should-update';
1415

1516
import DevTools from './DevTools';
@@ -253,15 +254,14 @@ export default class Preview extends React.PureComponent<Props, State> {
253254
getRenderedModule = () => {
254255
const { modules, module, directories, entry, isInProjectView } = this.props;
255256
return isInProjectView
256-
? findMainModule(modules, directories, entry)
257-
: module;
257+
? '/' + entry
258+
: getModulePath(modules, directories, module.id);
258259
};
259260

260261
executeCodeImmediately = (initialRender: boolean = false) => {
261262
const {
262263
modules,
263264
directories,
264-
module,
265265
externalResources,
266266
preferences,
267267
dependencies,
@@ -286,18 +286,22 @@ export default class Preview extends React.PureComponent<Props, State> {
286286
this.evaluateInSandbox(`history.pushState({}, null, '/')`);
287287
}
288288

289+
// We convert the modules to a format the manager understands
290+
const normalizedModules = modules.map(m => ({
291+
path: getModulePath(modules, directories, m.id),
292+
code: m.code,
293+
}));
294+
289295
this.sendMessage({
290296
type: 'compile',
291-
module: renderedModule,
292-
changedModule: module,
297+
version: 2,
298+
entry: renderedModule,
293299
dependencies,
294-
modules,
295-
directories,
300+
modules: normalizedModules,
296301
sandboxId,
297302
externalResources,
298303
template,
299304
hasActions: !!runActionFromPreview,
300-
isModuleView: !isInProjectView,
301305
});
302306
}
303307
};

packages/app/src/app/index.html

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,28 @@
2222
<meta name="description" content="CodeSandbox is an online editor tailored for web applications.">
2323
<link rel="shortcut icon" href="./favicon.ico">
2424
<link rel="manifest" href="/manifest.json">
25-
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Source+Code+Pro:500" rel="stylesheet">
25+
<link rel="preload" as="font" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Source+Code+Pro:500" rel="stylesheet">
2626
<title>CodeSandbox</title>
27+
28+
<!-- AMD Loader for Monaco -->
29+
<script rel="preload" src="/public/vs/loader.js"></script>
30+
2731
<!-- Google Tag Manager -->
2832
<script>
2933
(function (w, d, s, l, i) {
3034
w[l] = w[l] || []; w[l].push({
3135
'gtm.start':
32-
new Date().getTime(), event: 'gtm.js'
36+
new Date().getTime(), event: 'gtm.js'
3337
}); var f = d.getElementsByTagName(s)[0],
3438
j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
3539
'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
3640
})(window, document, 'script', 'dataLayer', 'GTM-T3L6RFK');
3741
</script>
3842
<!-- End Google Tag Manager -->
39-
<script src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
43+
<script async src="https://cdn.ravenjs.com/3.17.0/raven.min.js" crossorigin="anonymous"></script>
4044
<!-- <script async src="//cdn.headwayapp.co/widget.js"></script> -->
41-
<script async src="https://js.stripe.com/v3/"></script>
4245

43-
<!-- AMD Loader for Monaco -->
44-
<script src="/public/vs/loader.js"></script>
46+
<script async rel="prefetch" src="https://js.stripe.com/v3/"></script>
4547
</head>
4648

4749
<body style="margin: 0; padding: 0;">

0 commit comments

Comments
 (0)