@react-native/eslint-plugin-specs 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUCK +23 -0
- package/__tests__/eslint-tester.js +22 -0
- package/__tests__/react-native-modules-test.js +58 -0
- package/index.js +19 -0
- package/package.json +21 -0
- package/react-native-modules.js +156 -0
- package/with-babel-register/disk-cache.js +131 -0
- package/with-babel-register/index.js +110 -0
package/BUCK
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
load("@fbsource//tools/build_defs/third_party:yarn_defs.bzl", "yarn_workspace")
|
|
2
|
+
|
|
3
|
+
yarn_workspace(
|
|
4
|
+
name = "yarn-workspace",
|
|
5
|
+
srcs = glob(
|
|
6
|
+
["**/*.js"],
|
|
7
|
+
exclude = [
|
|
8
|
+
"**/__fixtures__/**",
|
|
9
|
+
"**/__flowtests__/**",
|
|
10
|
+
"**/__mocks__/**",
|
|
11
|
+
"**/__server_snapshot_tests__/**",
|
|
12
|
+
"**/__tests__/**",
|
|
13
|
+
"**/node_modules/**",
|
|
14
|
+
"**/node_modules/.bin/**",
|
|
15
|
+
"**/.*",
|
|
16
|
+
"**/.*/**",
|
|
17
|
+
"**/.*/.*",
|
|
18
|
+
"**/*.xcodeproj/**",
|
|
19
|
+
"**/*.xcworkspace/**",
|
|
20
|
+
],
|
|
21
|
+
),
|
|
22
|
+
visibility = ["PUBLIC"],
|
|
23
|
+
)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @format
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
'use strict';
|
|
11
|
+
|
|
12
|
+
const ESLintTester = require('eslint').RuleTester;
|
|
13
|
+
|
|
14
|
+
ESLintTester.setDefaultConfig({
|
|
15
|
+
parser: require.resolve('babel-eslint'),
|
|
16
|
+
parserOptions: {
|
|
17
|
+
ecmaVersion: 6,
|
|
18
|
+
sourceType: 'module',
|
|
19
|
+
},
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
module.exports = ESLintTester;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails react_native
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const ESLintTester = require('./eslint-tester.js');
|
|
14
|
+
|
|
15
|
+
const rule = require('../react-native-modules');
|
|
16
|
+
|
|
17
|
+
const NATIVE_MODULES_DIR = __dirname;
|
|
18
|
+
|
|
19
|
+
const eslintTester = new ESLintTester();
|
|
20
|
+
|
|
21
|
+
const VALID_SPECS = [
|
|
22
|
+
{
|
|
23
|
+
code: `
|
|
24
|
+
import {TurboModuleRegistry, type TurboModule} from 'react-native';
|
|
25
|
+
import type {UnsafeObject} from 'react-native/Libraries/Types/CodegenTypes';
|
|
26
|
+
|
|
27
|
+
export interface Spec extends TurboModule {
|
|
28
|
+
func1(a: string): UnsafeObject,
|
|
29
|
+
}
|
|
30
|
+
export default TurboModuleRegistry.get<Spec>('XYZ');
|
|
31
|
+
`,
|
|
32
|
+
filename: `${NATIVE_MODULES_DIR}/NativeXYZ.js`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
const INVALID_SPECS = [
|
|
37
|
+
// Untyped NativeModule require
|
|
38
|
+
{
|
|
39
|
+
code: `
|
|
40
|
+
import {TurboModuleRegistry, type TurboModule} from 'react-native';
|
|
41
|
+
export interface Spec extends TurboModule {
|
|
42
|
+
func1(a: string): {||},
|
|
43
|
+
}
|
|
44
|
+
export default TurboModuleRegistry.get<Spec>('XYZ');
|
|
45
|
+
`,
|
|
46
|
+
filename: `${NATIVE_MODULES_DIR}/XYZ.js`,
|
|
47
|
+
errors: [
|
|
48
|
+
{
|
|
49
|
+
message: rule.errors.misnamedHasteModule('XYZ'),
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
eslintTester.run('../react-native-modules', rule, {
|
|
56
|
+
valid: VALID_SPECS,
|
|
57
|
+
invalid: INVALID_SPECS,
|
|
58
|
+
});
|
package/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails react_native
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const reactNativeModules = require('./react-native-modules');
|
|
14
|
+
|
|
15
|
+
module.exports = {
|
|
16
|
+
rules: {
|
|
17
|
+
'react-native-modules': reactNativeModules,
|
|
18
|
+
},
|
|
19
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@react-native/eslint-plugin-specs",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "ESLint rules to validate NativeModule and Component Specs",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git@github.com:facebook/react-native.git",
|
|
9
|
+
"directory": "packages/eslint-plugin-specs"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@babel/core": "^7.14.0",
|
|
13
|
+
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
|
|
14
|
+
"flow-parser": "^0.121.0",
|
|
15
|
+
"make-dir": "^2.1.0",
|
|
16
|
+
"pirates":"^4.0.1",
|
|
17
|
+
"react-native-codegen": "*",
|
|
18
|
+
"source-map-support": "0.5.0"
|
|
19
|
+
},
|
|
20
|
+
"license": "MIT"
|
|
21
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails react_native
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
'use strict';
|
|
12
|
+
|
|
13
|
+
const path = require('path');
|
|
14
|
+
const withBabelRegister = require('./with-babel-register');
|
|
15
|
+
|
|
16
|
+
const ERRORS = {
|
|
17
|
+
misnamedHasteModule(hasteModuleName) {
|
|
18
|
+
return `Module ${hasteModuleName}: All files using TurboModuleRegistry must start with Native.`;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
let RNModuleParser;
|
|
23
|
+
let RNParserUtils;
|
|
24
|
+
|
|
25
|
+
function requireModuleParser() {
|
|
26
|
+
if (RNModuleParser == null || RNParserUtils == null) {
|
|
27
|
+
const config = {
|
|
28
|
+
only: [/react-native-codegen\/src\//],
|
|
29
|
+
plugins: [require('@babel/plugin-transform-flow-strip-types').default],
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
withBabelRegister(config, () => {
|
|
33
|
+
RNModuleParser = require('react-native-codegen/src/parsers/flow/modules');
|
|
34
|
+
RNParserUtils = require('react-native-codegen/src/parsers/flow/utils');
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
buildModuleSchema: RNModuleParser.buildModuleSchema,
|
|
40
|
+
createParserErrorCapturer: RNParserUtils.createParserErrorCapturer,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const VALID_SPEC_NAMES = /^Native\S+$/;
|
|
45
|
+
|
|
46
|
+
function isModuleRequire(node) {
|
|
47
|
+
if (node.type !== 'CallExpression') {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const callExpression = node;
|
|
52
|
+
|
|
53
|
+
if (callExpression.callee.type !== 'MemberExpression') {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const memberExpression = callExpression.callee;
|
|
58
|
+
if (
|
|
59
|
+
!(
|
|
60
|
+
memberExpression.object.type === 'Identifier' &&
|
|
61
|
+
memberExpression.object.name === 'TurboModuleRegistry'
|
|
62
|
+
)
|
|
63
|
+
) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (
|
|
68
|
+
!(
|
|
69
|
+
memberExpression.property.type === 'Identifier' &&
|
|
70
|
+
(memberExpression.property.name === 'get' ||
|
|
71
|
+
memberExpression.property.name === 'getEnforcing')
|
|
72
|
+
)
|
|
73
|
+
) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function isGeneratedFile(context) {
|
|
80
|
+
return (
|
|
81
|
+
context
|
|
82
|
+
.getSourceCode()
|
|
83
|
+
.getText()
|
|
84
|
+
.indexOf('@' + 'generated SignedSource<<') !== -1
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* A lint rule to guide best practices in writing type safe React NativeModules.
|
|
90
|
+
*/
|
|
91
|
+
function rule(context) {
|
|
92
|
+
const filename = context.getFilename();
|
|
93
|
+
const hasteModuleName = path.basename(filename).replace(/\.js$/, '');
|
|
94
|
+
|
|
95
|
+
if (isGeneratedFile(context)) {
|
|
96
|
+
return {};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let isModule = false;
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
'Program:exit': function (node) {
|
|
103
|
+
if (!isModule) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// Report invalid file names
|
|
108
|
+
if (!VALID_SPEC_NAMES.test(hasteModuleName)) {
|
|
109
|
+
context.report({
|
|
110
|
+
node,
|
|
111
|
+
message: ERRORS.misnamedHasteModule(hasteModuleName),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const {buildModuleSchema, createParserErrorCapturer} =
|
|
116
|
+
requireModuleParser();
|
|
117
|
+
const flowParser = require('flow-parser');
|
|
118
|
+
|
|
119
|
+
const [parsingErrors, tryParse] = createParserErrorCapturer();
|
|
120
|
+
|
|
121
|
+
const sourceCode = context.getSourceCode().getText();
|
|
122
|
+
const ast = flowParser.parse(sourceCode);
|
|
123
|
+
|
|
124
|
+
tryParse(() => {
|
|
125
|
+
buildModuleSchema(hasteModuleName, ast, tryParse);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
parsingErrors.forEach(error => {
|
|
129
|
+
error.nodes.forEach(flowNode => {
|
|
130
|
+
context.report({
|
|
131
|
+
loc: flowNode.loc,
|
|
132
|
+
message: error.message,
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
},
|
|
137
|
+
CallExpression(node) {
|
|
138
|
+
if (!isModuleRequire(node)) {
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
isModule = true;
|
|
143
|
+
},
|
|
144
|
+
InterfaceExtends(node) {
|
|
145
|
+
if (node.id.name !== 'TurboModule') {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
isModule = true;
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
rule.errors = ERRORS;
|
|
155
|
+
|
|
156
|
+
module.exports = rule;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails react_native
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const path = require('path');
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const os = require('os');
|
|
14
|
+
const {sync: makeDirSync} = require('make-dir');
|
|
15
|
+
|
|
16
|
+
const packageJson = JSON.parse(
|
|
17
|
+
fs.readFileSync(require.resolve('../package.json'), 'utf8'),
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* This file is a fork of
|
|
22
|
+
* https://github.com/babel/babel/blob/2782a549e99d2ef1816332d23d7dfd5190f58a0f/packages/babel-register/src/cache.js#L1
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
const FILENAME = path.join(
|
|
26
|
+
os.tmpdir(),
|
|
27
|
+
`.eslint-plugin-specs.${packageJson.version}.disk-cache.json`,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
let data = {};
|
|
31
|
+
|
|
32
|
+
let cacheDisabled = process.env.NODE_ENV === 'test';
|
|
33
|
+
|
|
34
|
+
function isCacheDisabled() {
|
|
35
|
+
return cacheDisabled;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Write stringified cache to disk.
|
|
40
|
+
*/
|
|
41
|
+
function save() {
|
|
42
|
+
if (isCacheDisabled()) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let serialised = '{}';
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
serialised = JSON.stringify(data, null, ' ');
|
|
50
|
+
} catch (err) {
|
|
51
|
+
if (err.message === 'Invalid string length') {
|
|
52
|
+
err.message = "Cache too large so it's been cleared.";
|
|
53
|
+
console.error(err.stack);
|
|
54
|
+
} else {
|
|
55
|
+
throw err;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
makeDirSync(path.dirname(FILENAME));
|
|
61
|
+
fs.writeFileSync(FILENAME, serialised);
|
|
62
|
+
} catch (e) {
|
|
63
|
+
switch (e.code) {
|
|
64
|
+
// workaround https://github.com/nodejs/node/issues/31481
|
|
65
|
+
// todo: remove the ENOENT error check when we drop node.js 13 support
|
|
66
|
+
case 'ENOENT':
|
|
67
|
+
case 'EACCES':
|
|
68
|
+
case 'EPERM':
|
|
69
|
+
console.warn(
|
|
70
|
+
`Could not write cache to file: ${FILENAME} due to a permission issue. Cache is disabled.`,
|
|
71
|
+
);
|
|
72
|
+
cacheDisabled = true;
|
|
73
|
+
break;
|
|
74
|
+
case 'EROFS':
|
|
75
|
+
console.warn(
|
|
76
|
+
`Could not write cache to file: ${FILENAME} because it resides in a readonly filesystem. Cache is disabled.`,
|
|
77
|
+
);
|
|
78
|
+
cacheDisabled = true;
|
|
79
|
+
break;
|
|
80
|
+
default:
|
|
81
|
+
throw e;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Load cache from disk and parse.
|
|
88
|
+
*/
|
|
89
|
+
|
|
90
|
+
function load() {
|
|
91
|
+
if (isCacheDisabled()) {
|
|
92
|
+
data = {};
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
process.on('exit', save);
|
|
97
|
+
process.nextTick(save);
|
|
98
|
+
|
|
99
|
+
let cacheContent;
|
|
100
|
+
|
|
101
|
+
try {
|
|
102
|
+
cacheContent = fs.readFileSync(FILENAME);
|
|
103
|
+
} catch (e) {
|
|
104
|
+
switch (e.code) {
|
|
105
|
+
// check EACCES only as fs.readFileSync will never throw EPERM on Windows
|
|
106
|
+
// https://github.com/libuv/libuv/blob/076df64dbbda4320f93375913a728efc40e12d37/src/win/fs.c#L735
|
|
107
|
+
case 'EACCES':
|
|
108
|
+
console.warn(
|
|
109
|
+
`Babel could not read cache file: ${FILENAME} due to a permission issue. Cache is disabled.`,
|
|
110
|
+
);
|
|
111
|
+
cacheDisabled = true;
|
|
112
|
+
/* fall through */
|
|
113
|
+
default:
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
data = JSON.parse(cacheContent);
|
|
120
|
+
} catch {}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Retrieve data from cache.
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
function get() {
|
|
128
|
+
return data;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
module.exports = {load, get};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*
|
|
7
|
+
* @emails react_native
|
|
8
|
+
* @format
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const babel = require('@babel/core');
|
|
12
|
+
const {OptionManager, DEFAULT_EXTENSIONS} = require('@babel/core');
|
|
13
|
+
const sourceMapSupport = require('source-map-support');
|
|
14
|
+
const {addHook} = require('pirates');
|
|
15
|
+
const path = require('path');
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const diskCache = require('./disk-cache');
|
|
18
|
+
|
|
19
|
+
function compile(sourceMapManager, cache, options, code, filename) {
|
|
20
|
+
const opts = new OptionManager().init({
|
|
21
|
+
sourceRoot: path.dirname(filename) + path.sep,
|
|
22
|
+
...options,
|
|
23
|
+
filename,
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Bail out ASAP if the file has been ignored.
|
|
27
|
+
if (opts === null) {
|
|
28
|
+
return code;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
let output = cache[filename];
|
|
32
|
+
|
|
33
|
+
if (!output || output.mtime !== mtime(filename)) {
|
|
34
|
+
output = babel.transformSync(code, {
|
|
35
|
+
...opts,
|
|
36
|
+
sourceMaps: opts.sourceMaps === undefined ? 'both' : opts.sourceMaps,
|
|
37
|
+
ast: false,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
cache[filename] = output;
|
|
41
|
+
output.mtime = mtime(filename);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (!sourceMapManager.isInstalled) {
|
|
45
|
+
sourceMapManager.install();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (output.map) {
|
|
49
|
+
sourceMapManager.maps[filename] = output.map;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return output.code;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function mtime(filename) {
|
|
56
|
+
return +fs.statSync(filename).mtime;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function withBabelRegister(options, fn) {
|
|
60
|
+
let revertHook;
|
|
61
|
+
/**
|
|
62
|
+
* TODO: Do source maps break when we use a require hook
|
|
63
|
+
* to before we initialize the ESLint plugin?
|
|
64
|
+
*/
|
|
65
|
+
const sourceMapManager = {
|
|
66
|
+
isInstalled: false,
|
|
67
|
+
maps: {},
|
|
68
|
+
install() {
|
|
69
|
+
if (sourceMapManager.isInstalled) {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
sourceMapManager.isInstalled = true;
|
|
73
|
+
sourceMapSupport.install({
|
|
74
|
+
handleUncaughtExceptions: true,
|
|
75
|
+
environment: 'node',
|
|
76
|
+
retrieveSourceMap(filename) {
|
|
77
|
+
const map = sourceMapManager.maps && sourceMapManager.maps[filename];
|
|
78
|
+
if (map) {
|
|
79
|
+
return {
|
|
80
|
+
url: null,
|
|
81
|
+
map: map,
|
|
82
|
+
};
|
|
83
|
+
} else {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
diskCache.load();
|
|
92
|
+
const cache = diskCache.get();
|
|
93
|
+
|
|
94
|
+
try {
|
|
95
|
+
revertHook = addHook(
|
|
96
|
+
(code, filename) => {
|
|
97
|
+
return compile(sourceMapManager, cache, options, code, filename);
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
exts: DEFAULT_EXTENSIONS,
|
|
101
|
+
ignoreNodeModules: false,
|
|
102
|
+
},
|
|
103
|
+
);
|
|
104
|
+
return fn();
|
|
105
|
+
} finally {
|
|
106
|
+
revertHook();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
module.exports = withBabelRegister;
|