Skip to content

Commit 22164ff

Browse files
committed
Compile import statements to require calls in sandbox
1 parent d6b30d3 commit 22164ff

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

html/js/sandbox.js

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@
274274
}
275275

276276
let strict = /^(\s|\/\/.*)*["']use strict['"]/.test(code), ast
277-
try { ast = acorn.parse(code) }
277+
try { ast = acorn.parse(code, {sourceType: detectSourceType(code)}) }
278278
catch(e) { return code }
279279
let patches = []
280280
let backJump = "if (++__c % 1000 === 0) __sandbox.tick();"
@@ -293,6 +293,31 @@
293293
ForInStatement: loop,
294294
WhileStatement: loop,
295295
DoWhileStatement: loop,
296+
ImportDeclaration(node) {
297+
dependencies.push(node.source.value)
298+
let req = "require(" + node.source.raw + ")", text
299+
if (node.specifiers.length == 0) {
300+
text = req
301+
} else if (node.specifiers.length > 1 || node.specifiers[0].type == "ImportDefaultSpecifier") {
302+
let name = modVar(node.source.value)
303+
text = "var " + name + " = " + req
304+
node.specifiers.forEach(spec => {
305+
if (spec.type == "ImportDefaultSpecifier")
306+
text += ", " + spec.local.name + " = " + name + ".default || " + name
307+
else if (name != null)
308+
text += ", " + spec.local.name + " = " + name + "." + spec.imported.name
309+
})
310+
} else {
311+
text = "var "
312+
node.specifiers.forEach(spec => {
313+
if (spec.type == "ImportNamespaceSpecifier")
314+
text += spec.local.name + " = " + req
315+
else
316+
text += spec.local.name + " = " + req + "." + spec.imported.name
317+
})
318+
}
319+
patches.push({from: node.start, to: node.end, text: text + ";"})
320+
},
296321
CallExpression(node) {
297322
if (node.callee.type == "Identifier" && node.callee.name == "require" &&
298323
node.arguments.length == 1 && node.arguments[0].type == "Literal" &&
@@ -324,10 +349,15 @@
324349
pos = patch.to || patch.from
325350
}
326351
out += code.slice(pos, code.length)
352+
console.log(out)
327353
out += "\n//# sourceURL=code" + randomID()
328354
return {code: (strict ? '"use strict";' : "") + out, dependencies}
329355
}
330356

357+
function detectSourceType(code) {
358+
return /(^|\n)\s*(im|ex)port\b/.test(code) ? "module" : "script"
359+
}
360+
331361
function randomID() {
332362
return Math.floor(Math.random() * 0xffffffff).toString(16)
333363
}

0 commit comments

Comments
 (0)