ESLINT: no-unused-vars, stream conditional pipe use case - javascript

So i have the following function:
function buildJavaScript(file) {
var manifestRoot,
stream;
validateManifestSection(file.manifest, 'javascript');
if (file.manifest.javascript.disabled) {
return;
}
manifestRoot = path.dirname(file.path);
stream = gulp.src(path.join(manifestRoot, file.manifest.javascript.src))
.pipe(gulpBrowserify())
.pipe(gulpRename(file.manifest.javascript.dest));
if (file.manifest.javascript.minify) {
stream = stream.pipe(gulpUglify());
}
stream = stream.pipe(gulp.dest(manifestRoot));
}
Its purpose is part of a gulp task, receives an object representing a manifest file then browserifies and conditionally uglifies it.
Now when i ESLint it i get the following error:
error no-unused-vars : 'stream' is defined but never used.
NOTE: i don't make common practice of linting my build files, this was part of testing the linter and its behavior here caught my attention.
I get that you need more than just assignment for it to be satisfied which is a good thing otherwise it could be easily fooled.
However in the instance above where the variable is a stream and assignment and chaining is enough to warrant use how do you get ESLint to be happy?
Or am i doing it wrong and that is not how your meant to conditionally pipe a stream?
I get if i was to return stream or pass it into another method it would please the linter but that doesn't seem right, i don't need to return it for use elsewhere.
Thanks for any help or insights.
EDIT:
In trying to pinpoint the issue ive reduced the method down to the following which still has the issue:
function buildJavaScript(file) {
var stream;
stream = gulp
.src(path.join('', file.manifest.javascript.src))
.pipe(gulpBrowserify())
.pipe(gulpRename(file.manifest.javascript.dest));
if (file.manifest.javascript.minify) {
stream = stream.pipe(gulpUglify());
}
}
I can understand its reasoning, technically all I am doing is assignment, not consumption elsewhere but its the context of the assignment which means the variable is being used.

Related

How can I specify a type from a dependency with typescript and node?

I'm trying to refactor some code to use a list of signals and attach .once handlers to each.
const terminationSignals = ["SIGINT", "SIGUSR2", "SIGTERM"];
terminationSignals.forEach((sig) => {
process.once(sig, () => {
l("received signal", sig, "terminating");
Shutdown();
});
});
This does not work because once accepts Signals but not arbitrary strings.
How can I extract the Signal type out of the process module global? I want to specify that terminationSignals is of type Signal[].
I was able to stumble upon it with the tsserver completion hints. The global namespace I needed to find was named NodeJS. So, the type was already available as NodeJS.Signals, defined in node_modules/#types/node/process.d.ts.

How to avoid default errors from a library

I have created a code that it actually works, but I call a library that has an error, and I would like to know if it is possible to avoid that specific line of code. I will try to explain the case as well as possible:
Error
Uncaught TypeError: fs.openSync is not a function
Previous code
function synthesizeToAudioFile(authorizationToken, message) {
// replace with your own subscription key,
// service region (e.g., "westus"), and
// the name of the file you save the synthesized audio.
var serviceRegion = "westus"; // e.g., "westus"
var filename = "./audiocue.wav";
//Use token.Otherwise use the provided subscription key
var audioConfig, speechConfig;
audioConfig = SpeechSDK.AudioConfig.fromAudioFileOutput(filename);
speechConfig = SpeechSDK.SpeechConfig.fromAuthorizationToken(authorizationToken, serviceRegion);
// create the speech synthesizer.
var synthesizer = new SpeechSDK.SpeechSynthesizer(speechConfig, audioConfig);
// start the synthesizer and wait for a result.
synthesizer.speakTextAsync(message,
function (result) {
if (result.reason === SpeechSDK.ResultReason.SynthesizingAudioCompleted) {
console.log("synthesis finished.");
} else {
console.error("Speech synthesis canceled, " + result.errorDetails +
"\nDid you update the subscription info?");
}
synthesizer.close();
synthesizer = undefined;
},
function (err) {
console.trace("err - " + err);
synthesizer.close();
synthesizer = undefined;
});
console.log("Now synthesizing to: " + filename);
}
I created a method, which later I have replicated in my current code. The difference was that I was using Browserify in order to import a library from a script of a HTML file:
<script type="text/javascript" src="js/dist/sub_mqtt.js"></script>
This file had my method, and the whole library, which made it crazy unreadable, and therefore I started using ScriptJS to import it. The problem is that, using browserify I was able to remove the line of code that it was failing using fs.openSync(and I do not even need), but by importing it with ScriptJS I do not have access to the source code.
I assume that what is missing is that I am not importing the library fs, which is being used by the library that I am importing with ScriptJS before importing that one, but how could I do it? I have tried:
<script src="../text-to-speech/node_modules/fs.realpath/index.js"></script>
, or
<script type="text/javascript" src="../text-to-speech/node_modules/fs.realpath/index.js"></script>
and also wrapping the content of synthesizeToAudioFile() with
require(["node_modules/fs.realpath/index.js"], function (fs) { });
but I get the following error:
Uncaught ReferenceError: module is not defined
at index.js:1
After researching about this question I found out the next statement:
The fs package on npm was empty and didn't do anything, however many
packages mistakenly depended on it. npm, Inc. has taken ownership of
it.
It's also a built-in Node module. If you've depended on fs, you can
safely remove it from your package dependencies.
therefore what I have done is to access to the file that I was requiring with ScriptJS
require(["../text-to-speech/microsoft.cognitiveservices.speech.sdk.bundle.js"]
and directly remove that line on it. Note that, at least in my case, clearing the cache of the browser was needed.

Using different Class Methods, depending on the used target compiler option

How can I tell TypeScript to use different-written methods (on the same class), depending on the used target option within the tsconfig.json file?
I'm currently re-writing one of my scripts into TypeScript to just "manage" one source, because at the moment I'm working with an ES5 and an ES6 file next to each other. Since TypeScript supports to just change the output target in the tsconfig.json file, I would just need one version to update and maintain.
The problem is I'm using a generator in the ES6 version, which theoretically shouldn't be this issue because TypeScript "adds" a pseudo generator to the top of my ES5 file. BUT: My Pseudo-Generator code, which I'm currently using on the ES5 file, is "cleaner" and way less code.
The Question
Is it possible to overwrite the respective "generator" method or using any special comment annotation (such as //#ts-target) to tell the compiler which code (function body) should be used depending on the used target in the configuration file? (Even If I couldn't found such solution on the official documentation).
An additional function or script, which can be added into the TypeScript compiler process would also help, I guess, because I'm compiling them using a small node.js script (which compiles both ES files without changing the tsconfig.json file directly.)
Or is there any kind of extension, to move different methods of the same class into different files? This way I could "extract" the respective "generator" methods, but this would cause another question: How can I link them depending on the target, because I'm using /// <reference /> linking on the main script file to get all together.
Any other idea?
class Option {
///#ts-target ES5
__walkerVariable1:any undefined
__walkerVariable2:any undefined
__walkerVariable3:any undefined
walker() {
/* Some Pseudo-Walker Code for ES5 */
}
///#ts-target ES6
*walker() {
/* Real Walker Code for ES6 */
}
}
Currently, a Pseudo-Generator code gets added in the ES5 version of my script. I want to prevent this by using a different method / function body with my own Pseudo-Generator. Therefore, I need to tell TypeScript that he should "ignore" the Pseudo-Generator in ES6 / the Real-Generator in ES5 and just render one of them depending on the used target option.
That was a bit tricky, but I found a solution thanks to this GitHub issue.
As mentioned above, I'm using my own node.js script to compile the TypeScript files into two different JavaScript versions (ES5 and ES6). Therefore, I'm using the TypeScript API with the ts.createProgram method. This method allows to add a host object as third parameter, which takes over some compiler processes and one of those is the file loader, called getSourceFile.
The rest is then relatively easy: Searching for a custom comment annotation (in my case \\\#ts-target:ES5 and \\\#ts-target:ES6 respectively) and filter them using RegExp. Maybe not the best solution, but it works!
function compileTS(){
let config = readConfig("ts/tsconfig.json");
let host = ts.createCompilerHost(config.options);
let sourceFile = host.getSourceFile;
// ES5 JavaScript
(function(config){
host.getSourceFile = function(filename) {
if(filename === "ts/options.ts"){
let file = fs.readFileSync("./ts/options.ts").toString();
file = file.replace(/[ ]+\/\/\/\#ts\-target\:ES6\s+([\s\S]*)\/\/\/\#ts\-target\:ES6/gm, "");
return ts.createSourceFile(filename, file, ts.ScriptTarget.ES5, true);
}
return sourceFile.call(host, filename);
}
let program = ts.createProgram(config.fileNames, config.options, host);
let emitResult = program.emit();
report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
if(emitResult.emitSkipped){
process.exit(1);
}
}(config));
// ES6 JavaScript
config.options.target = 2;
config.options.outFile = "../dist/js/tail.select-es6.js";
(function(config){
host.getSourceFile = function(filename) {
if(filename === "ts/options.ts"){
let file = fs.readFileSync("./ts/options.ts").toString();
file = file.replace(/[ ]+\/\/\/\#ts\-target\:ES5\s+([\s\S]*)\/\/\/\#ts\-target\:ES5/gm, "");
return ts.createSourceFile(filename, file, ts.ScriptTarget.ES2015, true);
}
return sourceFile.call(host, filename);
}
let program = ts.createProgram(config.fileNames, config.options, host);
let emitResult = program.emit();
report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
if(emitResult.emitSkipped){
process.exit(1);
}
}(config));
}

How to fix 'variable is not constructor' error in discord.js node project?

i'm experemeting with discord bot and tried to create record in database, but there's some troubles with it.
mongodb server is running and fully functioning.
there's two files.
first, with code of command:
https://sourceb.in/6834bfe20e.js
and second. with mongoose scheme:
https://sourceb.in/9f0c7858df.js
acrually, there's third file index file with command handler and
librarys initializations, but that's does not participate in the error.
I expected to create a record in the database, but there's error what says:
'token is not constructor' in command file:13:19
Problem:
Simply put, you're declaring a constant token, but also passing a parameter named token into your callback. When you're attempting to construct a new object based on the constant, you're actually using the callback's token variable.
Take note of this example, which emits the same error with your setup:
const token = class {
constructor(guild) {
this.guild = guild;
}
};
console.log(new token('1234')); // Works fine.
function foo(token) {
console.log(new token('1234')); // Throws error.
}
foo({ someOtherVar: true });
Solution:
A quick rename of your variable(s) will do. I'd suggest naming your const tokenSchema to avoid conflict (and confusion).

require() doesn't consistently return methods appended to the exports object

I've been using require() to break my code up into modules, but the results of doing this seem to be sporadic and inconsistent.
For example, in main.js, I have two requires()s:
var moduleOne = require('cloud/moduleOne.js');
var moduleTwo = require('cloud/moduleTwo.js');
Calling methods which are appended to moduleOne via exports produces the correct result:
moduleOne.methodOne(argumentOne); // is defined
Where as doing the same thing to the second module doesn't. It tells me the method is undefined.
moduleTwo.methodTwo(argumentTwo); // is undefined
I'm really confused why this is so inconsistent. In each source file, I'm declaring the functions like so (There's no function wrapper to create a local namespace):
// moduleOne.js
exports.methodOne = function(argumentOne) {
// Code
}
// moduleTwo.js
exports.methodTwo = function(argumentTwo) {
// Code
}
My linter tells me all the code is valid, and code in moduleOne executes as expected and passes the tests I have for it. Has anyone else experienced this, and if so, what was the solution? Both files are indeed in the cloud directory and both of them are on Parse.
If both the files implement methods similarly, then it might be a caching issue.
Try adding a cache buster to your require config:
urlArgs: "bust=" + (new Date()).getTime()
See the docs for a reference.

Categories