How to polyfill setImmediate? - javascript

I use graphql's dataloader in a project. Unfortunately, it breaks Webpack 5 because:
setImmediate is not defined
I see where the issue is coming from in their source code. I forked the repo, made a patch and added it to my package.json. But the file that import dataloader can't resolve the path. So I need to add a polyfill for this function.
I've tried to write this in my file:
if(typeof Window.prototype.setImmediate !== "function") {
Window.prototype.setImmediate = function() {
return false
};
}
But typescript claims that:
Property 'setImmediate' does not exist on type 'Window'
How to fix this?

Related

How to use the TypeScript Compiler API to type-check modules imported using `require()`?

I am using TypeChecker from the TypeScript Compiler API in order to extract (inferred) type information for every node in the AST of my program. In particular, I try to find out the return values from imported module functions such as:
var vec3 = require('gl-matrix/vec3')
var myVec = vec3.fromValues(1, 2, 3) // $ExpectedType vec3
This works well for modules that were imported using the import { … } from '…' statement, but unfortunately, modules that were imported using require() like above are not recognized correctly, I only receive the type any for them. However, I have set both compiler options allowJs and checkJs.
Why are the types form require()d modules not inferred correctly? VS Code (which AFAIK relies on the same API?) is able to infer the types from require() statements as well, so I'd guess that in general, tsc is able of handling them. Are there any other compiler options that I need to set differently? Or is this indeed not supported and I need to use some other package for this?
Here is a minimum script to reproduce, I have also put it on repl.it together with two example files: https://replit.com/#LinqLover/typecheck-js
var ts = require("typescript")
// Run `node index.js sample-import.js`` to see the working TypeScript analysis
const files = process.argv[1] != "/run_dir/interp.js" ? process.argv.slice(2) : ["sample-require.js"]
console.log(`Analyzing ${files}:`)
const program = ts.createProgram(files, {
target: ts.ScriptTarget.ES5,
module: ts.ModuleKind.CommonJS,
allowJs: true,
checkJs: true
})
const checker = program.getTypeChecker()
for (const sourceFile of program.getSourceFiles()) {
if (!sourceFile.isDeclarationFile) {
ts.forEachChild(sourceFile, visit)
}
}
function visit(node) {
try {
const type = checker.getTypeAtLocation(node)
console.log(checker.typeToString(type))
} catch (e) {
// EAFP
}
ts.forEachChild(node, visit)
}
Thank you so much in advance!
For follow-up, this turned out to be an issue with the type definitions for gl-matrix. I should better have tried out multiple packages before suspecting that the TypeScript engine itself could be broken ...
gl-matrix issue: https://github.com/toji/gl-matrix/issues/429

Javascript define and module

I'm a newbie on javascript and i encountered this piece of code:
(function (root, factory) {
if(typeof define === "function" && define.amd) {
define([], function(){ return factory(root.MyObject);});
} else if(typeof module === "object" && module.exports) {
module.exports = factory(root.MyObject);
} else {
root.MyObject= factory(root.MyObject);
}
}(typeof window !== "undefined" ? window : this, function (MyObject) { ... }
When i debug this, i can not see what's inside of define and module. What are these and what data they are holding (especially define.amd)? And would you kindly explain me why this approach is good (or bad or necessary) to inject MyObject? Are there any new or better approaches to do this in javascript?
Thanks in advance
This is the old universal method for importing files.
With modern browsers and with nodejs 14, now, you can use es6 modules with the es6 sintax. For nodejs they should have "mjs" extension.
import * as myModule from "./path/to/file.mjs"
Some documentation could be found here and here.
Otherwise, if you have to import old JavaScript, then you can use the UMD script that you have posted. You can find some documentation on modules here and in particular on UMD here.
UMD is a method to integrate your module with other modules, using a few well known (but also quite old) requiring methods.
Anyway you can also use an npm library such as Babeljs in order to transpile your code from es6 to old JavaScript (some configuration could be required), and their output is what should be imported.

How to use CodeMirror runmode standalone version in a webpack setup

I'm using CodeMirror as a simple syntax highlighter (≠ code editor) with the runmode addon. In order to save some bandwidth to users, i want to switch to runmode-standlone.js version, which is also included in the package but doesn't bring the whole CodeMirror power and weight attached.
The problem, as referenced by the library author is that CodeMirror library is listed as dependency of each mode (the lang packages):
you have to somehow convince your bundler to load the runmode-standalone shim instead of the regular core library for that dependency. — Author
Anyone managed to do this?
What i've already tried
Note, i've setup an alias so when i reference codemirror, it imports the standalone version (just FYI, because i've also tried without it)
// webpack.config.js
resolve: {
alias: {
codemirror$: path.resolve(__dirname, "node_modules/codemirror/addon/runmode/runmode-standalone.js")
}
}
All combinations of script-loader, imports-loader to try to execute mode modules as normal scripts
import "codemirror";
// same as import "codemirror/addon/runmode/runmode-standalone.js";
// nope
import "script-loader!codemirror/mode/javascript/javascript";
// nope
import "imports-loader?define=>false!codemirror/mode/javascript/javascript";
// nope
import "imports-loader?define=>false,module=>false,require=>false!codemirror/mode/javascript/javascript";
A similar strategy to what's suggested for ignoring moment.js locales (repo, SO thread, using webpackIgnorePlugin
// codemirror/mode/javascript/javascript.js import looks like
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
...
So i've tried to make it ignore
new webpack.IgnorePlugin({
resourceRegExp: /^\.\.\/lib\/codemirror$/,
contextRegExp: /^codemirror\/mode\/(.*)/
});
Setup details
Using codemirror#5.47.0 and webpack#4.29.6
Configure webpack to use externals.
The externals configuration option provides a way of excluding dependencies from the output bundles. Instead, the created bundle relies on that dependency to be present in the consumer's (any end-user application) environment.
externals: {
'../lib/codemirror': 'CodeMirror', // for mode/meta.js
'../../lib/codemirror': 'CodeMirror' // for mode/[mode]/[mode].js
}

Why do I see TypeScript in Vue.js source code?

I went through the vue.js source code just to have a look, and I saw some strange code, which I learnt was TypeScript syntax after some research. My problem is, this syntax is in a ".js" file, which I don't understand because I know TypeScript files (.ts) should compile to pure JS. So why do I still see the type annotation in the function parameter in a .js file?
function hasAncestorData (node: VNode) {
const parentNode = node.parent
return isDef(parentNode) && (isDef(parentNode.data) || hasAncestorData(parentNode))
}
This is actually a Flow code. You can see the /* #flow */ comment at the beginning of some files that enables the tool's type checking. It's a bit similar to TypeScript, but those are not the same things.
A quick look through the src folder of the Vue.js github repo shows that they do indeed use .js for their JavaScript w/Flow code, for instance in src/core/vdom/create-component.js:
const componentVNodeHooks = {
init (vnode: VNodeWithData, hydrating: boolean): ?boolean {
But if we look in the dist folder, we can see that those Flow type annotations have been removed for distribution. For instance, here's the above in dist/vue.js (that line number will rot over time):
var componentVNodeHooks = {
init: function init (vnode, hydrating) {

How grunt plugin get initialized?

I have understood the concept of "require" and "module.export". Now as per my understanding if one file is exporting a module another file invoking that by using "require".
Now in writing grunt task , we write
module.exports = function(grunt){}
Now who requires the module and how grunt argument is passed? I mean how does it work?
Also if some one can tell me what is the life cycle of a node plugin?
Basically grunt is doing the require and than calling that exported function with its instance of grunt.
you can see it in: task.js
// Load taskfile.
fn = require(path.resolve(filepath));
if (typeof fn === 'function') {
fn.call(grunt, grunt);
}

Categories

Resources