Skip to content

Commit e8654f2

Browse files
author
Ives van Hoorne
committed
Fix sass resolving
1 parent adcb528 commit e8654f2

File tree

4 files changed

+122
-36
lines changed

4 files changed

+122
-36
lines changed

packages/app/src/sandbox/compile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ async function compile({
134134
try {
135135
clearErrorTransformers();
136136
initializeErrorTransformers();
137-
unmount(!hadError);
137+
unmount(manager && manager.webpackHMR ? true : hadError);
138138
} catch (e) {
139139
console.error(e);
140140
}

packages/app/src/sandbox/eval/transpilers/sass/sass-worker.js

Lines changed: 109 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import resolve from 'browser-resolve';
2+
import { join, basename, absolute, dirname } from 'common/utils/path';
23
import delay from 'common/utils/delay';
34

45
self.importScripts([
@@ -15,8 +16,95 @@ declare var Sass: {
1516
registerPlugin: (name: string, plugin: Function) => void,
1617
};
1718

19+
const existsPromise = (fs, file) =>
20+
new Promise(r => {
21+
fs.stat(file, (err, stats) => {
22+
if (err || stats.isDirectory()) {
23+
return r(false);
24+
}
25+
26+
return r(file);
27+
});
28+
});
29+
30+
const getExistingPath = async (fs, p) => {
31+
const underscoredPath = join(dirname(p), '_' + basename(p));
32+
const possiblePaths = [
33+
p,
34+
`${p}.css`,
35+
`${p}.scss`,
36+
`${p}.sass`,
37+
underscoredPath,
38+
`${underscoredPath}.css`,
39+
`${underscoredPath}.scss`,
40+
`${underscoredPath}.sass`,
41+
];
42+
43+
let existedFile = false;
44+
45+
for (let i = 0; i < possiblePaths.length; i++) {
46+
if (!existedFile) {
47+
existedFile = await existsPromise(fs, possiblePaths[i]); // eslint-disable-line
48+
}
49+
}
50+
51+
return existedFile;
52+
};
53+
54+
const resolveSass = (fs, p, path) =>
55+
new Promise((r, reject) => {
56+
resolve(
57+
p,
58+
{
59+
filename: path,
60+
extensions: ['.scss', '.css', '.sass'],
61+
moduleDirectory: ['node_modules'],
62+
isFile: async (pp, cb) => {
63+
const exists = !!await getExistingPath(fs, pp);
64+
65+
if (!exists) {
66+
const err = new Error('Could not find ' + pp);
67+
// $FlowIssue
68+
err.code = 'ENOENT';
69+
70+
return cb(err);
71+
}
72+
73+
return cb(null, exists);
74+
},
75+
readFile: async (pp, encoding, cb) => {
76+
const foundPath = await getExistingPath(fs, pp);
77+
78+
if (!foundPath) {
79+
const err = new Error('Could not find ' + pp);
80+
// $FlowIssue
81+
err.code = 'ENOENT';
82+
83+
return cb(err);
84+
}
85+
86+
return fs.readFile(foundPath, encoding, cb);
87+
},
88+
},
89+
async (err, resolvedPath) => {
90+
if (err) {
91+
if (/^\w/.test(p)) {
92+
r(resolveSass(fs, '.' + absolute(p), path));
93+
}
94+
95+
reject(err);
96+
} else {
97+
const foundPath = await getExistingPath(fs, resolvedPath);
98+
99+
r(foundPath);
100+
}
101+
}
102+
);
103+
});
104+
18105
function initializeBrowserFS() {
19106
return new Promise(res => {
107+
// eslint-disable-next-line
20108
BrowserFS.configure(
21109
{
22110
fs: 'WorkerFS',
@@ -51,40 +139,32 @@ self.addEventListener('message', async event => {
51139
}
52140

53141
// register a custom importer callback
54-
Sass.importer((request, done) => {
55-
resolve(
56-
request.current,
57-
{
58-
filename: path,
59-
extensions: ['.scss', '.css', '.sass'],
60-
moduleDirectory: ['node_modules'],
61-
},
62-
(err, resolvedPath) => {
63-
if (err) {
64-
done({ error: err.message });
65-
return;
66-
}
142+
Sass.importer(async (request, done) => {
143+
// eslint-disable-next-line
144+
const fs = BrowserFS.BFSRequire('fs');
67145

68-
self.postMessage({
69-
type: 'add-transpilation-dependency',
70-
path: resolvedPath,
71-
isAbsolute: true,
72-
});
146+
try {
147+
const foundPath = await resolveSass(fs, request.current, path);
73148

74-
const fs = BrowserFS.BFSRequire('fs');
149+
self.postMessage({
150+
type: 'add-transpilation-dependency',
151+
path: foundPath,
152+
isAbsolute: true,
153+
});
75154

76-
fs.readFile(resolvedPath, {}, (error, data) => {
77-
if (error) {
78-
done({ error: error.message });
79-
return;
80-
}
155+
fs.readFile(foundPath, {}, (error, data) => {
156+
if (error) {
157+
done({ error: error.message });
158+
return;
159+
}
81160

82-
done({
83-
content: data.toString(),
84-
});
161+
done({
162+
content: data.toString(),
85163
});
86-
}
87-
);
164+
});
165+
} catch (e) {
166+
done({ error: e.message });
167+
}
88168
});
89169

90170
Sass.compile(

packages/app/src/sandbox/eval/transpilers/vue/loader.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,10 +430,14 @@ export default function(content: string, loaderContext: LoaderContext) {
430430
}
431431

432432
function getRequireForImportString(type, impt, scoped) {
433-
return loaderUtils.stringifyRequest(
433+
const depPath = loaderUtils.stringifyRequest(
434434
loaderContext,
435435
'!!' + getLoaderString(type, impt, -1, scoped) + impt.src
436436
);
437+
438+
loaderContext.addDependency(JSON.parse(depPath));
439+
440+
return depPath;
437441
}
438442

439443
function addCssModulesToLoader(loader, part, index) {

standalone-packages/codesandbox-browserfs/src/backend/CodeSandboxFS.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ export default class CodeSandboxFS extends SynchronousFileSystem
145145

146146
public renameSync(oldPath: string, newPath: string) {
147147
const tModules = this.manager.getTranspiledModules();
148-
const modulesWithPath = Object.keys(tModules).filter((p: string) =>
149-
p.startsWith(oldPath)
148+
const modulesWithPath = Object.keys(tModules).filter(
149+
(p: string) => p.startsWith(oldPath) + '/' || p === oldPath
150150
);
151151

152152
if (modulesWithPath.length === 0) {
@@ -165,7 +165,7 @@ export default class CodeSandboxFS extends SynchronousFileSystem
165165

166166
if (!moduleInfo) {
167167
const modulesStartingWithPath = Object.keys(tModules).filter(
168-
(pa: string) => pa.startsWith(p)
168+
(pa: string) => pa.startsWith(p + '/') || pa === p
169169
);
170170

171171
if (modulesStartingWithPath.length > 0) {
@@ -221,7 +221,7 @@ export default class CodeSandboxFS extends SynchronousFileSystem
221221
public rmdirSync(p: string) {
222222
const tModules = this.manager.getTranspiledModules();
223223
Object.keys(tModules)
224-
.filter((pa: string) => pa.startsWith(p))
224+
.filter((pa: string) => pa.startsWith(p + '/') || p === pa)
225225
.forEach((pa: string) => {
226226
const { module } = tModules[pa];
227227

@@ -239,7 +239,9 @@ export default class CodeSandboxFS extends SynchronousFileSystem
239239

240240
const p = path.endsWith('/') ? path : path + '/';
241241

242-
const pathsInDir = paths.filter((secondP: string) => secondP.startsWith(p));
242+
const pathsInDir = paths.filter(
243+
(secondP: string) => secondP.startsWith(p + '/') || secondP === p
244+
);
243245
if (pathsInDir.length === 0) {
244246
return [];
245247
}

0 commit comments

Comments
 (0)