I'm working on a webpage has js files that don't provide esm exports, and they define global variables that other files depend on. Something like this:
<!-- index.html -->
...
<script src="first.js"></script>
<script src="second.js"></script>
...
/* first.js */
var someGlobalVariable = 'value';
/* second.js */
function anImportantFunc() {
doSomethingWith(someGlobalVariable);
}
...
anImportantFunc();
The webpage does not use any UI framework.
I'm trying to minify these js files but the minifier understandably changes the names of the global variables without updating the other files that depend on them, so those other files throw errors when they hit undefined variables. Is there a way to make the minifier aware of this, possibly by specifying variables to ignore in some/all files? Similar to how eslint allows you to specify globals that shouldn't be marked as undefined. I understand this may be difficult because the files don't have clear dependency tree relationships in the way that modules have. I'm using esbuild but open to other build tools if they handle this scenario well. Thanks.
Related
I was learning about typescript but I am getting this duplicate function implementation problem in vs code intellisense whenever I open two different files having same function name but when I close one of the files the error goes away and there is also no errors present when I compile both the files.
Now when I close one of the files the error goes away.
I searched this problem but solutions were for projects and included some tsconfig.json file but here I am just learning the language not doing any projects.
What is happening here? And how can I remove this problem.
Your files do not have static imports or exports, making them ambient files. Similar to how when you link multiple JS files to your HTML without type=module, everything in your files shares one namespace. To fix this, add export {} to each of your files, making them modules with their own namespace.
// ...
export {}; // now a module with own namespace
What I mean by "ambient":
// foo.js
const x = 42;
// bar.js
console.log(x); // x is available in this file
<script src="foo.js"></script> // since you link it here
<script src="bar.js"></script>
Alternatively, I see that you are lacking a tsconfig.json, which is the source of two issues:
the one you are asking about now (conflicting declarations)
compiled js files being in the same folder as your ts files
Making a tsconfig.json will solve both of these. You can get started with that here.
I get JSLint errors in a file for undeclared functions and variables referenced from another file. Does brackets have a configuration/menu to remove these while keeping other linting errors?
JSLint complains whenever you reference an identifier that it can't see any declaration for in the file. So if you're using global variables/functions that were set by some other file, you'll get these warnings.
You can stop the warnings by individually specifying which undeclared globals you want to allow. To do that, place a directive like this at the top of your file:
/*jslint indent: 4 */
/*global ClassFoo, ClassBar, someFunction */
But of course, it's a pain to list things manually in each file.
Perhaps the best way to clean this up is to use a module loader like RequireJS. Then most your references to other files won't be through globals, and you'll only have to tell JSLint to ignore the few globals needed for RequireJS itself (usually just define).
Using a module loader has other benefits too. It eliminates "dependency spaghetti" by making cross-file dependencies very explicit, and it automatically load modules in proper dependency order. And there are easy tools that automatically concatenate all your modules into one file when you're ready for deployment.
In my project, I use a few RequireJS modules. I have used the Require JS optimizer (r.js)to package them further into various modules. So, if we have require modules like a.js, b.js, c.js and d.js after packaging we get this :
abc.js ( which is a combination of a.js and b.js)
a.js,
b.js
def.js ( which is a combination of c.js and d.js)
c.js,
d.js
We have made these modules abc.js and def.js available over CDN and end users use it. Is there a way to find out who is using a.js and who is using b.js? I mean, can we detect who downloaded which module in their application. This becomes a little tricky because sometimes it will be loaded from browser cache also. At least can we do it at the level of abc.js and def.js?
The problem is if you're distributing both modules in the same file then you need some way to track the usage of each module (right?) and to complicate thing further, browsers cache static files, other users could download your modules and self host, etc etc.
I think this is a slightly offside solution but it should work. You could grab a JavaScript analytics library like Segment.IO:
https://segment.com
and in your definition for module A (inside it's "factory" or definition block) you could track it's usage:
analytics.track('module A was required');
likewise in module B's definition:
analytics.track('module B was required');
and that way even though they're defined in the same file and could be cached, only when the user requires the individual module do you fire the tracking call, so you'll know exactly when a certain module of yours is used.
I'm just starting to migrate from internal modules to external modules in Typescript. Until now in my .d.ts files I have used the "declare var ..." part, because everything was used from the global namespace. But now with AMD I want my IDE to highlight errors if I use something without a corresponding import statement, so I do not want any ambiet declarations. How do I achieve that without modifying all my definition files manually (which would not work well with my tsd retrieval tool if I needed to do any updates)
Thanks!
Sorry : Can't be done without modifying the declaration files manually.
I'm working on a userscript - in particular this userscript - which has been designed to encapsulate functionality in modules. In order to be able to do some automated testing I would like to split the modules into their own files and use node.js's module exporting and require functions to combine into one file for use in Greasemonkey or simple browser extensions.
My first thought was to just copy the modules into their own files as such
module.js
var exportedModule = (function (){
var Module = {
// public functions and members
};
//private functions and members
return Module;
}());
module.exports = exports = exportedModule;
And then have a central file that requires each of these modules, perhaps compiling them with something like Browserify.
script.js
var importedModule = require(./module);
importedModule.init();
Is this possible?
It seems to me that you would be better off using Requirejs, which uses AMD style modules and is inherently more browser friendly. Node commonjs-style modules are synchronous and do not fit the browser model very well.
Of course, using requirejs will change your scripts a bit.
It's possible, and Browserify makes it easy:
browserify src/my.user.js -o dist/my.user.js
The metadata in the source file may get moved, but it's still parsed correctly (by Greasemonkey at least).
For a more complex example which compiles various assets, including CSS and images, see here.