Basically i have two .js files ,let it is A.js and B.js and i have code like this
A.js
function details(age,address,name){
//some code
//some code
getData(age);
//some code
}
function getData(ag){
return ag;
}
B.js
here how can i access that getData(?) ??? , i don't want to use global variable and i just want to know is it possible in any way or choosing global variable is last option.
Until now, plain JavaScript doesn't provide a built-in namespace management for JS resources.
Recently, import feature appeared.
The import statement is used to import functions, objects, or
primitives which are defined in and exported by an external module,
script, or the like.
But beware :
This feature is only just beginning to be implemented in browsers
natively at this time. It is implemented in many transpilers, such as
the Traceur Compiler, Babel, Rollup, and Webpack.
In A.js, you could export getData() as clients need it :
function details(age,address,name){
//some code
//some code
getData(age);
//some code
}
export function getData(ag){
return ag;
}
and in the client code could import it :
import { getData} from '/modules/A.js';
getData(...);
If you want to keep plain JS fully supported, a classic workaround used by the authors of JS libraries is using a single global variable that holds all public resources that the client needs.
In this way, you reduce the risk to have conflict with other libraries or client resources.
If you can change the code of these files, you could define a single global variable :
var myNameSpace = {
details : function(age,address,name){
//some code
//some code
getData(age);
//some code
},
getData : function getData(ag){
return ag;
}
....
};
And access to the function by prefixing with the single global variable : myNameSpace.
myNameSpace.getData(...);
In your A.js file store the returning data that is ag in local/session storage.
You can access this data in B.js which will be in local/session storage.
localStorage.setItem("key", "value");
Related
I have a Javascript frontend that does Ajax calls to my backend. To do that, it needs a "backend_URL" that I hard-coded in the Ajax get() call, say "http://myservice/backend".
Now if I want to deploy my app on different machines, some of which will use this url with HTTPS: "https://myservice/backend", and some not (because they lack a proper certificate and do not expose valuable data).
Where should I put the "USE_HTTPS=1" config variable so that someone deploying the app can choose to use or not SSL ? Of course the question extends itself to other config variables.
I thought about adding a ".config" file at the project root, but then I don't know how to import it in my code. Or should I export environment variables ? Or a node.js feature ?
I ended up writing a conf.js file with content
window.CONFIG = {
SOME_CONSTANT: 22,
}
and included it in a new <script> in my index.html before the other scripts.
The window is not mandatory but shows where it comes from when I call that as window.CONFIG anywhere in the rest of the javascript.
CONFIG = (function(){
var conf_info = {};
conf_info["url"] = 'http://codepen.io/pen/';
return{
getValue : function(param){
return conf_info[param];
}
}
})();
//some where in different file
document.getElementById("result").innerHTML = CONFIG.getValue('url');
I am currently using the following package where the readme illustrates the following
final bool loaded = await JsIsolatedWorker().importScripts(['test.js']);
I am using the isolate worker package so my code can work on web and outside of web. I would like to generate javascript code from my dart code. I have one file with a top level function and I use
dart compile js -O0 -o test.js test.dart
which I found here
https://dart.dev/tools/dart2js
this is my dart file
void main(List<String> args) {
doComputation('');
}
String doComputation(String input) {
return 'output';
}
I can generate javascript only if I have a main function but this generates a javascript file where the doComutation is not a top level function, so I am not sure if the package can call the function. It looks like it generates an entire program instead of just generating one function.
The generated file is too long to post
So what my question comes down to is this. Is there a way to generate javascript from dart for 1 function with its dependencies included instead of having to generate the entire program? So that I can call this function from dart.
I am not an expert but I also had this problem. Here's what worked for me:
In web_worker.dart:
import 'package:js/js.dart';
main(){
allowInterop(doComputation);
}
#JS('doComputation')
String doComputation(String computationInput) {
// Replace this with your actual computation.
final String computationOutput = "output";
return computationOutput;
}
Compile it using:
$ dart compile js web_worker.dart -o webWorker.js
Manually edit webWorker.js, the JS file generated by the compiler:
Delete this line at the top of the file:
(function dartProgram() {
and the line at the bottom of the file with the corresponding closing brace:
})();
I don't understand what's going on here but I found the Javascript version of the function doComputation() defined in webWorker.js as a property of the object "A".
I defined a wrapper at the top of the file like this:
function doComputation(computationInput) {
return A.doComputation(computationInput)
}
and then I was able to use the file with JsIsolatedWorker like this:
final bool loaded =
await JsIsolatedWorker().importScripts(['../web/webWorker.js']);
if (loaded) {
final String computationResult = await JsIsolatedWorker()
.run(functionName: 'doComputation', arguments: computationInput);
} else {
debugPrint('Web worker is not available');
}
If someone who understands this better can elaborate or improve on this solution, that would be great. I don't really have any idea what I'm doing. I'm just posting this to hopefully help other people save time in the future by sharing what worked for me.
You can use js package to call JavaScript APIs from Dart code, or vice versa. To make a Dart function callable from JavaScript by name, use a setter annotated with #JS().
#JS()
library callable_function;
import 'package:js/js.dart';
/// Allows assigning a function to be callable from `window.functionName()`
#JS('functionName')
external set _functionName(void Function() f);
/// Allows calling the assigned function from Dart as well.
#JS()
external void functionName();
void _someDartFunction() {
print('Hello from Dart!');
}
void main() {
_functionName = allowInterop(_someDartFunction);
}
JavaScript code may now call functionName() or window.functionName().
Check google chartjs https://github.com/google/chartjs.dart/tree/master/example for a complete example.
From dart2js "Helping dart2js generate better code" there is a tip :
Don’t worry about the size of your app’s included libraries. The dart2js compiler performs tree shaking to omit unused classes, functions, methods, and so on. Just import the libraries you need, and let dart2js get rid of what you don’t need.
Related to this post https://stackoverflow.com/a/21124252/3733730.
You can do this instead by using the package dart2js
one make a program for your main.dart dart2js where the function or command you wanted to make is there, then create a separate dart file what function you wanted to call, and it will fix your problem, it is a separate file but will only execute one function that you needed to do so and that is the separate file
I have a large (~15k LoC) JS app (namely a NetSuite app) written in old-style all-global way. App consists of 26 files and dependencies between them are totally unclear.
The goal is to gracefully refactor the app to smaller modules. By gracefully I mean not breaking\locking the app for long time, but doing refactoring in smaller chunks, while after completing each chunk app remains usable.
An idea I have here is to concat all the JS files we have now into single-file bundle. After that some code could be extracted into modules. And the legacy code could start importing it. The modules & imports should be transpiled with webpack\whatever, while legacy code remains all-globals style. Finally all this is packed into single JS file and deployed.
My questions are
is there a better approach maybe? This sounds like a typical problem
are there any tools available to support my approach?
I gave webpack a try and I haven't managed to get what I want out of it. The export-loader and resolve-loader are no options because of amount of methods\vars that needs to be imported\exported.
Examples
Now code looks like
function someGlobalFunction() {
...
}
var myVar = 'something';
// and other 15k lines in 26 files like this
What I would ideally like to achieve is
function define(...) { /* function to define a module */ }
function require(moduleName) { /* function to import a module */ }
// block with my refactored out module definitions
define('module1', function () {
// extracted modularised code goes here
});
define('module2', function () {
// extracted modularised code goes here
});
// further down goes legacy code, which can import new modules
var myModule = require('myNewModule');
function myGlobalLegacyFunction() {
// use myModule
}
I'm following an approach similar to that outlined here: https://zirho.github.io/2016/08/13/webpack-to-legacy/
In brief:
Assuming that you can configure webpack to turn something like
export function myFunction(){...}
into a file bundle.js that a browser understands. In webpack's entry point, you can import everything from your module, and assign it to the window object:
// using namespace import to get all exported things from the file
import * as Utils from './utils'
// injecting every function exported from utils.js into global scope(window)
Object.assign(window, Utils).
Then, in your html, make sure to include the webpack output before the existing code:
<script type="text/javascript" src="bundle.js"></script>
<script type="text/javascript" src="legacy.js"></script>
Your IDE should be able to help identify clients of a method as you bring them into a module. As you move a function from legacy.js to myNiceModule.js, check to see if it still has clients that are aware of it globally - if it doesn't, then it doesn't need to be globally available.
No good answer here so far, and it would be great if the person asking the question would come back. I will pose a challenging answer saying that it cannot be done.
All module techniques end up breaking the sequential nature of execution of scripts in the document header.
All dynamically added scripts are loaded in parallel and they do not wait for one another. Since you can be certain that almost all such horrible legacy javascript code is dependent on the sequential execution, where the second script can depend on the first previous one, as soon as you load those dynamically, it can break.
If you use some module approach (either ES7 2018 modules or require.js or you own) you need to execute the code that depends on the loading having occurred in a call-back or Promise/then function block. This destroys the implicit global context, so all these spaghetti coils of global functions and var's we find in legacy javascript code files will not be defined in the global scope any more.
I have determined that only two tricks could allow a smooth transition:
Either some way to pause continuation of a script block until the import Promise is resolved.
const promise = require("dep1.js", "dep2.js", "dep3.js");
await promise;
// legacy stuff follows
or some way to revert the scope of a block inside a function explicitly into the global scope.
with(window) {
function foo() { return 123; }
var bar = 543;
}
But neither wish was granted by the javascript fairy.
In fact, I read that even the await keyword essentially just packs the rest of the statements into function to call when promise is resolved:
async function() {
... aaa makes promise ...
await promise;
... bbb ...
}
is just, I suppose, no different from
async function() {
... aaa makes promise ...
promise.then(r => {
... bbb ...
});
}
So this means, the only way to fix this is by putting legacy javascript statically in the head/script elements, and slowly moving things into modules, but continue to load them statically.
I am tinkering with my own module style:
(function(scope = {}) {
var v1 = ...;
function fn1() { ... }
var v2 = ...;
function fn2() { ... }
return ['v1', 'fn1', 'v2', 'fn2']
.reduce((r, n) => {
r[n] = eval(n);
return r;
}, scope);
})(window)
by calling this "module" function with the window object, the exported items would be put on there just as legacy code would do.
I gleaned a lot of this by using knockout.js and working with the source readable file that has everything together but in such module function calls, ultimately all features are on the "ko" object.
I hate using frameworks and "compilation" so generating the sequence of HTML tags to load them in the correct order by the topologically sorted dependency tree, while I could write myself such a thing quickly, I won't do this, because I do not want to have any "compilation" step, not even my own.
UPDATE: https://stackoverflow.com/a/33670019/7666635 gives the idea that we can just Object.assign(window, module) which is somewhat similar to my trick passing the window object into the "module" function.
I need to use the functions of a javaScript file in another javaScript file, but I do not have an HTML linking the 2, how to share it?
const {Builder} = require('selenium-webdriver')
var chrome = new Builder().forBrowser('firefox').build()
login(chrome);
this is my code main and i need get this other method to other JavaScript File.
function login(chrome, user, senha){
chrome.get('https://testerbeta.crm2.dynamics.com/main.aspx');
}
now the code is small, but the software that I have to test is great and I need to separate the methods in different javascripts files
I think what you're looking for are import and export, added in ES6.
Basically, in the file you want to get your functions from, just add export keyword before function declarement, just like that:
export function foo() {
return bar;
}
Then, in the file you want to inject your function in, you add this at the beginning of the file:
import { foo } from 'path/to/your/file_with_function_to_export.js'
More about that you can read here.
When using MVC, I sometimes pass the server's model data to the client-side JavaScript by using Razor injected into the JavaScript, as follows:
<script type="text/javascript">
var myClientGuid = '#Model.MyServerGuid';
</script>
This sets a JavaScript variable named myClientGuid to the value of the server-side model property MyServerGuid. When it reaches the client, the code looks something like this inside the browser:
<script type="text/javascript">
var myClientGuid = 'EF0077AB-0482-4D91-90A7-75285F01CA6F';
</script>
This allows external JavaScript files to use this variable.
My question is, in TypeScript, since all code must be referenced via external files, what is the best way to pass server-side fields to TypeScript code? External code files cannot contain Razor code. Should I use the same technique as above, in the View, mixing JavaScript and Typescript within the project?
The TypeScript compiler just needs to know that your server-side fields exist. The easiest way to do that is to use ambient declarations (see section 10 of the spec). For example, if you had a .ts file that needed to use myClientGuid, you could do
declare var myClientGuid: string;
at the top of your main .ts file. The compiler will not generate code for this var declaration, so you won't clobber anything. Now any files that reference that .ts file will know that there is a myClientGuid string available in global scope.
Another solution (to avoid global variables) is to wrap the TypeScript code in a function that takes the needed server-side fields as parameters:
In TypeScript file:
function setupMyPage(myGuid:string) {
...
}
In .cshtml:
<script src='#Url.Content("<path-to-typescript>")'></script>
<script>
setupMyPage('#Model.MyServerGuid');
</script>
If you are using RequireJS, you can also export the setupMyPage function as a module, to avoid adding the function to global namespace:
In TypeScript file:
export = setupMyPage;
In .cshtml:
<script>
require(['#Url.Content("<path-to-typescript>")'], function(setupMyPage) {
setupMyPage('#Model.MyServerGuid');
};
</script>