Skip to content

Commit 9ab5b66

Browse files
authored
Manager caching (codesandbox#420)
* Manager caching * Fix error caching and cache resolve paths * Start of HMR and bugfixes * HMR * Fix HMR * Small cleanup * Cleanup * Cleanup HMR * Experimental vue hot reloading * Got it working!!!! * Fix css modules * Cleaning * Fix loaders * Changes * Progress * Fix * Fix Vue recompiling * Changes * Fix hard reload of vue file changes * Add ts-loader * Fix tests * Update dependency handling * Trigger CI * Update cache to v3 * CI test commit * Fix scss dependencies * Fix loading screen being in front of error * Fix inconsistent states * Use CircularJSON
1 parent 6f95129 commit 9ab5b66

File tree

43 files changed

+2063
-852
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2063
-852
lines changed

.babelrc

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
{
22
"env": {
33
"test": {
4-
"presets": [
5-
"env",
6-
"react"
7-
],
4+
"presets": ["env", "react"],
85
"plugins": [
96
"babel-plugin-transform-async-to-generator",
107
"babel-plugin-transform-object-rest-spread",
@@ -19,7 +16,8 @@
1916
"webpack": true
2017
}
2118
],
22-
"babel-plugin-system-import-transformer"
19+
"babel-plugin-system-import-transformer",
20+
"babel-macros"
2321
]
2422
}
2523
}

.circleci/config.yml

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,22 @@ jobs:
88
steps:
99
- checkout
1010
- restore_cache:
11-
key: v2-dependency-cache-{{ .Branch }}-{{ checksum "yarn.lock" }}
11+
keys:
12+
- v3-dependency-cache-{{ .Branch }}-{{ checksum "yarn.lock" }}
13+
- v3-dependency-cache-{{ .Branch }}
14+
- v3-dependency-cache
1215
- run:
1316
name: Install Dependencies
1417
command: yarn install
1518
- save_cache:
16-
key: v2-dependency-cache-{{ .Branch }}-{{ checksum "yarn.lock" }}
19+
key: v3-dependency-cache-{{ .Branch }}-{{ checksum "yarn.lock" }}
1720
paths:
18-
- ./node_modules
19-
- ./packages/app/node_modules
20-
- ./packages/codesandbox-api/node_modules
21-
- ./packages/common/node_modules
22-
- ./packages/homepage/node_modules
23-
- ~/.yarn-cache
21+
- node_modules
2422
- run:
2523
name: Build
2624
command: yarn build:dependents
2725
- save_cache:
28-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
26+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
2927
paths:
3028
- ~/codesandbox-client
3129

@@ -35,19 +33,19 @@ jobs:
3533
working_directory: ~/codesandbox-client
3634
steps:
3735
- restore_cache:
38-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
36+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
3937
# We do this to compare sizes from these builds with master
4038
- restore_cache:
41-
key: v2-prod-app-build-cache-master
39+
key: v3-prod-app-build-cache-master
4240
- run:
4341
name: Build Application
4442
command: yarn build:prod
4543
- save_cache:
46-
key: v2-prod-app-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
44+
key: v3-prod-app-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
4745
paths:
4846
- ./packages/app/www
4947
- save_cache:
50-
key: v2-prod-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
48+
key: v3-prod-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
5149
paths:
5250
- ./www
5351
- store_artifacts:
@@ -60,7 +58,7 @@ jobs:
6058
working_directory: ~/codesandbox-client
6159
steps:
6260
- restore_cache:
63-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
61+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
6462
- run:
6563
name: Start Test Server
6664
command: yarn start:test
@@ -84,7 +82,7 @@ jobs:
8482
working_directory: ~/codesandbox-client
8583
steps:
8684
- restore_cache:
87-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
85+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
8886
- run:
8987
name: Test
9088
command: yarn test --ci --testResultsProcessor="jest-junit"
@@ -97,7 +95,7 @@ jobs:
9795
working_directory: ~/codesandbox-client
9896
steps:
9997
- restore_cache:
100-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
98+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
10199
- run:
102100
name: Lint
103101
command: yarn lint
@@ -108,9 +106,9 @@ jobs:
108106
working_directory: ~/codesandbox-client
109107
steps:
110108
- restore_cache:
111-
key: v2-repo-{{ .Environment.CIRCLE_SHA1 }}
109+
key: v3-repo-{{ .Environment.CIRCLE_SHA1 }}
112110
- restore_cache:
113-
key: v2-prod-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
111+
key: v3-prod-build-cache-{{ .Environment.CIRCLE_BRANCH }}-{{ .Environment.CIRCLE_SHA1 }}
114112
- add_ssh_keys:
115113
fingerprints:
116114
- "f7:f1:e6:60:96:24:d9:cd:1b:8b:c0:34:e7:ee:fa:82"
@@ -153,6 +151,3 @@ workflows:
153151
only: master
154152
requires:
155153
- hold
156-
157-
158-

lerna.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"lerna": "2.4.0",
3+
"packages": ["packages/*"],
34
"version": "independent",
45
"npmClient": "yarn",
56
"useWorkspaces": true

packages/app/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@
131131
"humps": "CompuIves/humps",
132132
"image-extensions": "^1.1.0",
133133
"jszip": "^3.1.3",
134+
"localforage": "^1.5.5",
134135
"lodash": "^4.17.2",
135136
"match-sorter": "^1.8.1",
136137
"moment": "^2.18.1",
@@ -141,6 +142,7 @@
141142
"postcss": "^6.0.9",
142143
"postcss-selector-parser": "^2.2.3",
143144
"qs": "^6.5.0",
145+
"querystring": "^0.2.0",
144146
"rc-slider": "^8.2.0",
145147
"react": "16.2.0",
146148
"react-addons-css-transition-group": "^15.6.0",
@@ -174,6 +176,7 @@
174176
"svg-react-loader": "^0.4.4",
175177
"tern": "^0.21.0",
176178
"vue": "^2.5.2",
179+
"vue-hot-reload-api": "^2.2.4",
177180
"vue-template-compiler": "^2.5.2",
178181
"vue-template-es2015-compiler": "^1.6.0"
179182
},

packages/app/src/app/components/sandbox/Preview/utils/should-update.js

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,7 @@
22
import type { Module, Directory } from 'common/types';
33

44
// Fields to compare
5-
const MODULE_FIELDS = [
6-
'directoryShortid',
7-
'code',
8-
'title',
9-
'isNotSynced',
10-
'isBinary',
11-
];
5+
const MODULE_FIELDS = ['directoryShortid', 'code', 'title', 'isBinary'];
126

137
const DIRECTORY_FIELDS = ['title', 'directoryShortid', 'shortid'];
148

packages/app/src/app/store/entities/reducer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import moduleReducer from './sandboxes/modules/reducer';
1010
import directoryReducer from './sandboxes/directories/reducer';
1111
import userReducer from './users/reducer';
1212

13-
const d = _debug('cw:app:store:reducers:entities');
13+
const d = _debug('cs:app:store:reducers:entities');
1414

1515
const entityReducers = {
1616
sandboxes: sandboxReducer,

packages/app/src/sandbox/compile.js

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,31 @@ export function getCurrentManager(): ?Manager {
3535
return manager;
3636
}
3737

38-
async function updateManager(sandboxId, template, managerModules) {
38+
let firstLoad = true;
39+
40+
async function updateManager(
41+
sandboxId,
42+
template,
43+
managerModules,
44+
manifest,
45+
isNewCombination
46+
) {
47+
let newManager = false;
3948
if (!manager || manager.id !== sandboxId) {
40-
manager = new Manager(sandboxId, managerModules, getPreset(template));
41-
} else {
42-
await manager.updateData(managerModules);
49+
newManager = true;
50+
manager = new Manager(sandboxId, getPreset(template), managerModules);
51+
if (firstLoad) {
52+
// We save the state of transpiled modules, and load it here again. Gives
53+
// faster initial loads.
54+
55+
await manager.load();
56+
}
4357
}
4458

59+
if (isNewCombination || newManager) {
60+
manager.setManifest(manifest);
61+
}
62+
await manager.updateData(managerModules);
4563
return manager;
4664
}
4765

@@ -69,10 +87,11 @@ async function compile({
6987
isModuleView = false,
7088
template,
7189
}) {
90+
const startTime = Date.now();
7291
try {
7392
clearErrorTransformers();
7493
initializeErrorTransformers();
75-
unmount();
94+
unmount(manager && manager.webpackHMR);
7695
} catch (e) {
7796
console.error(e);
7897
}
@@ -81,52 +100,57 @@ async function compile({
81100
handleExternalResources(externalResources);
82101

83102
try {
84-
const [{ manifest, isNewCombination }] = await Promise.all([
85-
loadDependencies(dependencies),
86-
updateManager(sandboxId, template, modules),
87-
]);
103+
const { manifest, isNewCombination } = await loadDependencies(dependencies);
88104

89-
// Just reset the whole packager if it's a new combination
90-
if (isNewCombination) {
105+
if (isNewCombination && !firstLoad) {
106+
// Just reset the whole manager if it's a new combination
91107
manager = null;
92-
await updateManager(sandboxId, template, modules);
93108
}
109+
const t = Date.now();
94110

95-
manager.setManifest(manifest);
111+
await updateManager(
112+
sandboxId,
113+
template,
114+
modules,
115+
manifest,
116+
isNewCombination
117+
);
96118

97119
const managerModuleToTranspile = modules.find(m => m.path === entry);
98120

99-
const t = Date.now();
100121
await manager.transpileModules(managerModuleToTranspile);
122+
101123
debug(`Transpilation time ${Date.now() - t}ms`);
102124

103125
resetScreen();
104126

105-
try {
106-
const children = document.body.children;
107-
// Do unmounting for react
108-
if (manifest.dependencies.find(n => n.name === 'react-dom')) {
109-
const reactDOMModule = manager.resolveModule('react-dom', '');
110-
const reactDOM = manager.evaluateModule(reactDOMModule);
127+
if (!manager.webpackHMR) {
128+
try {
129+
const children = document.body.children;
130+
// Do unmounting for react
131+
if (manifest.dependencies.find(n => n.name === 'react-dom')) {
132+
const reactDOMModule = manager.resolveModule('react-dom', '');
133+
const reactDOM = manager.evaluateModule(reactDOMModule);
111134

112-
reactDOM.unmountComponentAtNode(document.body);
135+
reactDOM.unmountComponentAtNode(document.body);
113136

114-
for (let i = 0; i < children.length; i += 1) {
115-
if (children[i].tagName === 'DIV') {
116-
reactDOM.unmountComponentAtNode(children[i]);
137+
for (let i = 0; i < children.length; i += 1) {
138+
if (children[i].tagName === 'DIV') {
139+
reactDOM.unmountComponentAtNode(children[i]);
140+
}
117141
}
118142
}
143+
} catch (e) {
144+
/* don't do anything with this error */
119145
}
120-
} catch (e) {
121-
/* don't do anything with this error */
122146
}
123-
124-
const htmlModule = modules.find(
125-
m => m.path === '/public/index.html' || m.path === '/index.html'
126-
);
127-
const html = htmlModule ? htmlModule.code : '<div id="root"></div>';
128-
129-
document.body.innerHTML = html;
147+
if (!manager.webpackHMR || firstLoad) {
148+
const htmlModule = modules.find(
149+
m => m.path === '/public/index.html' || m.path === '/index.html'
150+
);
151+
const html = htmlModule ? htmlModule.code : '<div id="root"></div>';
152+
document.body.innerHTML = html;
153+
}
130154

131155
const tt = Date.now();
132156
const oldHTML = document.body.innerHTML;
@@ -162,13 +186,22 @@ async function compile({
162186
initializeResizeListener();
163187
}
164188

189+
debug(`Total time: ${Date.now() - startTime}ms`);
190+
165191
dispatch({
166192
type: 'success',
167193
});
194+
195+
firstLoad = false;
196+
manager.save();
168197
} catch (e) {
169198
console.log('Error in sandbox:');
170199
console.error(e);
171200

201+
if (manager) {
202+
manager.clearCache();
203+
}
204+
172205
e.module = e.module;
173206
e.fileName = e.fileName || entry;
174207

0 commit comments

Comments
 (0)