Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/twbs/rewire.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/moduleEnv.js')
-rw-r--r--lib/moduleEnv.js68
1 files changed, 53 insertions, 15 deletions
diff --git a/lib/moduleEnv.js b/lib/moduleEnv.js
index 6754273..cbb76d9 100644
--- a/lib/moduleEnv.js
+++ b/lib/moduleEnv.js
@@ -1,17 +1,48 @@
"use strict";
+// TODO: Use https://www.npmjs.com/package/pirates here?
+
var Module = require("module"),
fs = require("fs"),
- babelCore = require("babel-core"),
+ eslint = require("eslint"),
coffee;
var moduleWrapper0 = Module.wrapper[0],
moduleWrapper1 = Module.wrapper[1],
originalExtensions = {},
- babelPlugins = [
- "babel-plugin-transform-es2015-block-scoping",
- "babel-plugin-transform-object-rest-spread"
- ],
+ linter = new eslint.Linter(),
+ eslintOptions = {
+ env: {
+ es6: true,
+ },
+ parserOptions: {
+ ecmaVersion: 6,
+ ecmaFeatures: {
+ globalReturn: true,
+ jsx: true,
+ experimentalObjectRestSpread: true
+ },
+ },
+ rules: {
+ "no-const-assign": 2
+ }
+ },
+ // The following regular expression is used to replace const declarations with let.
+ // This regex replacement is not 100% safe because transforming JavaScript requires an actual parser.
+ // However, parsing (e.g. via babel) comes with its own problems because now the parser needs to
+ // be aware of syntax extensions which might not be supported by the parser, but the underlying
+ // JavaScript engine. In fact, rewire used to have babel in place here but required an extra
+ // transform for the object spread operator (check out commit d9a81c0cdacf6995b24d205b4a2068adbd8b34ff
+ // or see https://github.com/jhnns/rewire/pull/128). It was also notable slower
+ // (see https://github.com/jhnns/rewire/issues/132).
+ // There is another issue: replacing const with let is not safe because of their different behavior.
+ // That's why we also have ESLint in place which tries to identify this error case.
+ // There is one edge case though: when a new syntax is used *and* a const re-assignment happens,
+ // rewire would compile happily in this situation but the actual code wouldn't work.
+ // However, since most projects have a seperate linting step which catches these const re-assignment
+ // errors anyway, it's probably still a reasonable trade-off.
+ // Test the regular expresssion at https://regex101.com/r/dvnZPv/2 and also check out testLib/constModule.js.
+ matchConst = /(^|\s|\}|;)const(\/\*|\s)/gm,
nodeRequire,
currentModule;
@@ -72,17 +103,27 @@ function restoreExtensions() {
}
}
+function isNoConstAssignMessage(message) {
+ return message.ruleId === "no-const-assign";
+}
+
function jsExtension(module, filename) {
var _compile = module._compile;
module._compile = function (content, filename) {
- content = babelCore.transform(content, {
- plugins: babelPlugins,
- retainLines: true,
- filename: filename,
- babelrc: false
- }).code;
- _compile.call(module, content, filename);
+ const noConstAssignMessage = linter.verify(content, eslintOptions).find(isNoConstAssignMessage);
+
+ if (noConstAssignMessage !== undefined) {
+ const { line, column } = noConstAssignMessage;
+
+ throw new TypeError(`Assignment to constant variable at ${ filename }:${ line }:${ column }`);
+ }
+
+ _compile.call(
+ module,
+ content.replace(matchConst, "$1let$2"), // replace const with let
+ filename
+ );
};
restoreExtensions();
@@ -113,9 +154,6 @@ function stripBOM(content) {
return content;
}
-// Prepopulate require.cache with babel plugins because otherwise it will be lazy-loaded by Babel during rewire()
-babelPlugins.forEach(require);
-
try {
coffee = require("coffee-script");
} catch (err) {