UNPKG

2 kBJavaScriptView Raw
1'use strict';
2const getDocumentationUrl = require('./utils/get-documentation-url');
3const methodSelector = require('./utils/method-selector');
4
5const message = 'Only use `process.exit()` in CLI apps. Throw an error instead.';
6const importWorkerThreadsSelector = [
7 // `require('worker_threads')`
8 [
9 'CallExpression',
10 '[callee.type="Identifier"]',
11 '[callee.name="require"]',
12 '[arguments.length=1]',
13 '[arguments.0.type="Literal"]',
14 '[arguments.0.value="worker_threads"]'
15 ].join(''),
16 // `import workerThreads from 'worker_threads'`
17 [
18 'ImportDeclaration',
19 '[source.type="Literal"]',
20 '[source.value="worker_threads"]'
21 ].join('')
22].join(', ');
23const processOnOrOnceCallSelector = methodSelector({
24 object: 'process',
25 names: ['on', 'once'],
26 min: 1
27});
28const processExitCallSelector = methodSelector({
29 object: 'process',
30 name: 'exit'
31});
32
33const create = context => {
34 const startsWithHashBang = context.getSourceCode().lines[0].indexOf('#!') === 0;
35
36 if (startsWithHashBang) {
37 return {};
38 }
39
40 let processEventHandler;
41
42 // Only report if it's outside an worker thread context. See #328.
43 let requiredWorkerThreadsModule = false;
44 const problemNodes = [];
45
46 return {
47 // Check `worker_threads` require / import
48 [importWorkerThreadsSelector]: () => {
49 requiredWorkerThreadsModule = true;
50 },
51 // Check `process.on` / `process.once` call
52 [processOnOrOnceCallSelector]: node => {
53 processEventHandler = node;
54 },
55 // Check `process.exit` call
56 [processExitCallSelector]: node => {
57 if (!processEventHandler) {
58 problemNodes.push(node);
59 }
60 },
61 'CallExpression:exit': node => {
62 if (node === processEventHandler) {
63 processEventHandler = undefined;
64 }
65 },
66 'Program:exit': () => {
67 if (!requiredWorkerThreadsModule) {
68 for (const node of problemNodes) {
69 context.report({
70 node,
71 message
72 });
73 }
74 }
75 }
76 };
77};
78
79module.exports = {
80 create,
81 meta: {
82 type: 'suggestion',
83 docs: {
84 url: getDocumentationUrl(__filename)
85 }
86 }
87};