diff --git a/Grunttasks.ts b/Grunttasks.ts index f7a547f74..abc172e47 100644 --- a/Grunttasks.ts +++ b/Grunttasks.ts @@ -137,7 +137,7 @@ function getWebpackConfig(target: string, optimize: boolean = false): webpack.Co * @param target release, dev, or fast-dev */ function getKarmaConfig(target: string, singleRun = false, browsers = ['Chrome']): karma.ConfigOptions { - return { + return { // base path, that will be used to resolve files and exclude basePath: '.', frameworks: ['jasmine'], @@ -149,6 +149,7 @@ function getKarmaConfig(target: string, singleRun = false, browsers = ['Chrome'] autoWatch: true, browsers: browsers, captureTimeout: 60000, + concurrency: 1, // Avoid hardcoding and cross-origin issues. proxies: { '/': 'http://localhost:8000/' diff --git a/src/global_require.ts b/src/global_require.ts new file mode 100644 index 000000000..5985af87c --- /dev/null +++ b/src/global_require.ts @@ -0,0 +1,13 @@ +/** + * The only way I could figure out how to get a handle on Node's 'require' + * function without confusing webpack. Using a Function constructor doesn't work, + * as require() isn't in its scope! + * + * Isolating in its own module so it doesn't mess up mangling in other modules. + */ +export default function getGlobalRequire(): Function { + const reqVar = eval('typeof(require)!=="undefined"?require:null'); + return reqVar ? reqVar : function(moduleName: string): any { + throw new Error(`Cannot find module ${moduleName}`); + }; +} \ No newline at end of file diff --git a/src/jvm.ts b/src/jvm.ts index 0b085ec7f..515dda452 100644 --- a/src/jvm.ts +++ b/src/jvm.ts @@ -18,6 +18,7 @@ import ThreadPool from './threadpool'; import logging = require('./logging'); import JDKInfo = require('../vendor/java_home/jdk.json'); import global = require('./global'); +import getGlobalRequire from './global_require'; declare var RELEASE: boolean; if (typeof RELEASE === 'undefined') global.RELEASE = false; @@ -103,6 +104,10 @@ class JVM { private jitDisabled: boolean = false; private dumpJITStats: boolean = false; + // Get the environment's require variable, indirectly. + // Hidden from webpack and other builders, as it confuses them. + private globalRequire: Function = null; + public static isReleaseBuild(): boolean { return typeof(RELEASE) !== 'undefined' && RELEASE; } @@ -528,6 +533,9 @@ class JVM { */ private evalNativeModule(mod: string): any { "use strict"; // Prevent eval from being terrible. + if (!this.globalRequire) { + this.globalRequire = getGlobalRequire(); + } var rv: any; /** * Called by the native method file. Registers the package's native @@ -538,10 +546,7 @@ class JVM { } // Provide the natives with the Doppio API, if needed. const DoppioJVM = require('./doppiojvm'), - globalRequire = global['require'], - savedRequire = typeof(globalRequire) !== 'undefined' ? globalRequire : function(moduleName: string): any { - throw new Error(`Cannot find module ${moduleName}`); - }; + globalRequire = this.globalRequire; /** * An emulation of CommonJS require() for the modules. @@ -570,9 +575,9 @@ class JVM { case 'pako/lib/zlib/adler32': return adler32; case 'crypto': - return util.are_in_browser() ? null : savedRequire('crypto'); + return util.are_in_browser() ? null : globalRequire('crypto'); default: - return savedRequire(name); + return globalRequire(name); } } /** diff --git a/tsconfig.json b/tsconfig.json index fa5cc5867..d328308ad 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -26,6 +26,7 @@ "src/fd_state.ts", "src/gLong.ts", "src/global.ts", + "src/global_require.ts", "src/heap.ts", "src/interfaces.ts", "src/jar.ts",