   exportDictionary = (jsDictionary exportList, exportList)
   {typedModulePath} = ctx
   [..., type] = typedModulePath.types
-  switch type
-    when 'commonJs'
-      (concat [
-        toJsString 'use strict'
-        definitions
-        [(jsAssignStatement 'module.exports', exportDictionary)]])
-    when 'browser'
-      [(jsAssignStatement (jsAccess "Shem", (validIdentifier (modulePathToName typedModulePath.names))),
-        (iife (concat [
-          toJsString 'use strict'
-          definitions
-          [(jsReturn exportDictionary)]])))]
-    when 'submodule'
-      [..., name] = typedModulePath.names
-      [(jsVarDeclaration (validIdentifier name),
-        (iife (join definitions, [(jsReturn exportDictionary)])))]
-    else
-      throw new Error "Unspecified ctx.moduleCompilationType"
-
-topLevelExpressionInModule = (ctx, expression) ->
+  definitions: definitions
+  moduleWrapper:
+    (compiledDefinitions) ->
+      defs = jsStatementList [compiledDefinitions]
+      strict = jsStatementList [toJsString 'use strict']
+      switch type
+        when 'commonJs'
+          [strict
+            defs
+            (jsAssignStatement 'module.exports', exportDictionary)]
+        when 'browser'
+          [(jsAssignStatement (jsAccess "Shem", (modulePathToName typedModulePath.names)),
+            (iife [
+              strict
+              defs
+              (jsReturn exportDictionary)]))]
+        when 'submodule'
+          [..., name] = typedModulePath.names
+          [(jsVarDeclaration (validIdentifier name),
+            (iife [defs, (jsReturn exportDictionary)]))]
+        else
+          throw new Error "Unspecified ctx.moduleCompilationType"
+
+topLevelExpressionInModule = (compiledDefinitions) -> (ctx, expression) ->
   (iife (concat [
     toJsString 'use strict;'
-    (importImplicit ctx)
+    compiledDefinitions
     [(jsReturn (topLevelExpression ctx, expression))]]))
 
 importImplicit = (ctx) ->

    labelConflict conflict.ref.val
  else
    conflict.error = yes

lookupJs = (moduleName) ->
  compiled = (lookupCompiledModule moduleName)

  toInject = requiresFor moduleName
  ctx = injectedContext toInject
  ctx.typedModulePath = typedModulePath
  {definitions, moduleWrapper} = topLevelModule ctx, ast
  {request, ir, js: compiledDefinitions} = compileCtxAstIrToJs ctx, ast, definitions
  if request
    if not allInjected request, requiredMap
      return compileModuleTopLevelAst ast, typedModulePath, request
    else
      {js: compiledDefinitions} = compileCtxWithoutRequestIrToJs ctx, ir
  {js} = compileCtxWithoutRequestIrToJs ctx, moduleWrapper compiledDefinitions
  errors = checkTypes ctx
  # (finalizeTypes ctx, ast) # TODO: this doesn't work when the AST includes multiple modules with different contexts than the current one
  replaceOrAddToMap compiledModules, moduleName,
    declared: (subtractContexts ctx, (injectedContext toInject)) # must recompute because ctx is mutated
    js: js
    compiledDefinitions: compiledDefinitions
  js: js
  ast: ast
  # types: typeEnumaration ctx
