Current script path with type="module" - javascript

I'm trying to access a file that I want to reference relative to a script file while using <script type="module">. Normally, without type="module", people seem to be looking up the script tag and using its src attribute to get the path, but this obviously isn't possible after using imports.
The scenario looks roughly like this:
File structure:
js/
script.js
other/
imported.js
index.html
index.html:
<html><head><script type="module" src="js/script.js"></script></head></html>
script.js
import "other/imported.js";
imported.js
// ??? should with some code magic become "js/other/imported.js" or similar
console.log("The path to this script is: " + "???");
I saw some thread somewhere where it was discussed that the reason document.currentScript is null when using type="module" is because they wanted to figure out a better alternative. I suppose this alternative is not yet available?
So, to recap, with the file structure above, how can one find the path to js/other/imported.js in that script dynamically?

To answer my own question almost 2 years later, there's now a thing called import.meta which is used to provide arbitrary information about the current module. In this case, import.meta.url would be the thing I was looking for.
You can read more on this MDN page: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import.meta

Related

Import from Adjacent Script Tag with ES6 Modules

With ES6 modules, is there a current method, or one in the pipeline, to import a module from a <script> tag already on the page? For example, if I have 2 <script> tags,
<script id="a">
export const a = 'a';
</script>
<script id="b">
import a from ?;
console.log(a);
</script>
what do I put into the import statement in the second <script> tag, in place of the question mark?
The id attribute is for identification purposes, as, obviously, there needs to be some way to identify the <script> tag you need. It could be done with classes or any other way, but IDs must be unique (though many browsers just use the last tag with an id), so I thought it was a good way to ensure you have the correct tag. It could also be done by getting the <script> tag by position in the document: for example, here you are getting the second script tag, so perhaps you could do something like
import a from window.scripts[1];
One more thing: if this could work across HTML imports, that would be great, too. My original purpose was to re-use React components across different pages of a site, where they may not be able to be imported with relative paths, and, at least with Webpack, absolute paths are not always relative to the server's root: sometimes they are relative to the computer's root, or at least the webserver's root.
How do I import values directly from another <script> tag on the page?
I know it's an old question and if my reputation was higher I probably would have added this as a comment...
The unsatisfactory way I hade to use in a similar case was to place every variable from the first module on the window
[I read something about using eval() but haven't tried to test it. as I detest the eval function.]
#T.J. Crowder: I have the following structure
/app
/modules
main.js
other.js
feature.js
/customer-page1
index.html
/data
data.js
/page2
index.html
/data
data.js
/Page3
index.html
/data
data.js
It's a kind of complicated quiz-app. We add new features and the customers update there index.html.
Questions are in the HTML an the data/data.js contain complex structured data.
We want/need modules as we load the feature.js dynamically.
The data.js sometimes needs to have evaluation function in addition to the raw data, which can differ from client to client, so a pure JSON isn't cutting it, and we still would have the path-problem, as main.js has to work on all pages
and is referenced as
<script type='module' src="/app/modules/main.js"></script>
while data is easily referenced as
<script type='module' src="data/data.js"></script>
from index.html
As we work with pure (no framework) Typescript we also need the modules is data for type-checking to see definitions in /app...
I would be very happy to find a more elegant solution though.

How to put THREEjs code into separate JS file with meteor

Okay so I have a meteor app and I am trying to make templates that have THREEjs animations in them so I can load a specific animation by loading a specific template. I wanted to de-clutter my HTML file by taking out the script tags and moving them to a separate JavaScript file but that wasn't working. I ended up just putting the JavaScript into my HTML and it worked. I was going to just keep doing that and live with the cluttered code but now I have run into a problem.
For some odd reason even if a for loop is inside the script tags, the computer will see the < sign and expect a html tag. At first I thought I had forgotten a closing tag or something but I checked and I haven't. If I delete the for loop (only create one particle) everything works perfectly again. I could fix this by just using escape character for the < sign (<) but I think I should find a solution to the overarching problem so I don't run into similar problems in the future.
I want to put the least amount of JavaScript in my HTML file as possible. (Meteor doesn't like it and neiter do I.)
If I try to just copy and paste my JavaScript into a separate file, it won't find the min.three.js file (it tells me THREE isn't defined)
I would prefer not to use another framework like require.js mainly because I'm not sure how but I will as a last resort if that's the only way to do it
All the examples for THREEjs put the code directly in the HTML file but how can I put it into a separate javascript file and make sure the javascript file finds min.three.js?
This is an overview of what the template looks like. I used jQuery to find actualAnimation2 and appended the container to that. You can also find all the code here
<template name = "animation2">
<div id = "animation2" class = "centered">
<div class = "line"></div>
<h1>Animation 2</h1>
<div class = "line"></div>
{{> animationButtons}}
<!--Put in a threejs animation here -->
<div id = "actualAnimation2" class = "animation">
<script src="client/three.min.js"></script>
<script>
//THREEjs stuff here
//This is what I want to move
</script>
</div>
</div>
</template>
tl;dr: How can I make THREEjs play nice with Meteor?
Any suggestions are welcome and let me know if I can clarify anything. Thank you for your help!
Quoting http://docs.meteor.com/ :
Some JavaScript libraries only work when placed in the
client/compatibility subdirectory. Files in this directory are
executed without being wrapped in a new variable scope. This means
that each top-level var defines a global variable. In addition, these
files are executed before other client-side JavaScript files.
This is exactly what needs to be done with three.min.js because the beggining of the file looks like :
// threejs.org/license
'use strict';var THREE={REVISION:"68"};
So you need to put three.min.js inside cient/compatibility/.
But you are probably better off using a package, choose carefully the one who is more likely to upgrade to revision 69 quickly in a few weeks or so.
If I try to just copy and paste my JavaScript into a separate file, it won't find the min.three.js file (it tells me THREE isn't defined)
It sounds like you're running into an issue where your JS files are loaded before min.three.js. You might be able to fix that by taking advantage of Meteor's JS load order - files in directories called lib are loaded first, so if you put your min.three.js file inside /client/lib it will load before source files outside that directory.
Another option would be to use a package - for example, meteor add aralun:three.

Cassette Add Individual Javascript Script Link Reference Inline

Is there a way to add an inline script link reference using Cassette?
What I want is to be able to add something like the following to my page:
#Bundles.AddInlineScriptReference("/MyScripts/TheScript.js")
(note: Bundles.AddInlineScriptReference doesn't exists, just an example)
and have Cassette write out the script link including handling the minification, etc.
<script src="/cassette.axd/asset/MyScripts/TheScript.js?voB4kL0uy2HIpjkJnSuycghlp-8=" type="text/javascript"></script>
I see a way to add inline scripts and bundles but not script link references. I could setup bundles that include individual files. However that seems like it's unnecessarily tedious for a single script that's used throughout an entire section of a site.
Reading the Cassette Bundle helper documentation I thought something like this would work.
#Bundles.Reference("/MyScripts/TheScript.js")
However it throws the following error:
Cannot find an asset bundle containing the path
I'd appreciate any advice. I feel like this is such a simple question that I must be missing something obvious.
bundles.Add<ScriptBundle>("MyBundle", new[]{ "path/to/script/script.js"});

Multiple sources for a javascript file

I am working on a project where I need to include somewhat around 10-15 .js files in the HTML head section directly like
<script type="text/javascript" src="http://localhost:9020/website1/wa/min/soundmanager2.js,vars.js,utils/md5.js,utils/utils.js></script>
what is the way I can give refrences correctly
the files I need to refre are in the same hierarchy like
1.....2,3
2.........4,5
3........6,7
I need to refer 1,4,7 please help.
somewhere I read this method what's it?
<script type="text/javascript" src="http://localhost:9020/wordplus/root/child/?b=scripts&f=soundmanager2.js,vars.js,utils/md5.js,utils/utils.js></script>
The example you posted looks exactly like the query string interface for the minify PHP library: http://github.com/mrclay/minify
Using it you use it in the fashion <script src="min/?b=path&f=script1.js,script2.js,ui/script3.js"></script>.
Where path is the path from your web root that you want it to look for scripts under.
I've used it before and I've found it quite effective. It concatenates, minifies, caches, and serves JS and CSS.
I'm sure there are other libraries to achieve the same effect, alternatively you can create a build script to concatenate and minify all your scripts and then deploy a single JS file to your site, in a single script tag.
It is not possible to load multiple javascript files in a single <script> element.
You have to have to have an individual <script> element for each script you are referencing..
<script type="text/javascript"
src="http://localhost:9020/wordplus/root/child/?b=scripts&f=soundmanager2.js"></script>
<script type="text/javascript"
src="http://localhost:9020/wordplus/root/child/?b=scripts&f=vars.js"></script>
I think you'll get what you need from dynamically loading external javascript files:
http://ntt.cc/2008/02/10/4-ways-to-dynamically-load-external-javascriptwith-source.html
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
The second line you posted requests scripts from the server dynamically. the b parameter of the request tells it you want scripts and the f parameter tells the server which files you want. Then it concatenates these into one file and sends that back to the user agent. You need server-side scripting to handle this; it is not something built into the URL specification.
http://localhost:9020/wordplus/root/child/
b=scripts
f=soundmanager2.js,vars.js,utils/md5.js,utils/utils.js
The simplest solution is just have one script tag per file as it will let you take advantage of caching:
<script src="http://localhost:9020/wordplus/root/child/soundmanager2.js"></script>
<script src="http://localhost:9020/wordplus/root/child/vars.js"></script>
<script src="http://localhost:9020/wordplus/root/child/utils/md5.js"></script>
<script src="http://localhost:9020/wordplus/root/child/utils/utils.js"></script>
Another solution is to use some JavaScript builder to join all your files, generating just one. The pros of this approach is that your result file will be "compressed" (minified). Some builders:
Google Closure Compiler (I like and use this since 2009).
YUI Compressor

jQuery Intellisense: Common reference file (stdafx) for vsdoc

I moved the jQuery in my project over to Microsoft's CDN yesterday so finally have jQuery intellisense back. Yay! However, I apparently need to include the following in all my .js files:
//These references should enable intellisense within this file
///<reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.4.js" />
///<reference path="http://ajax.aspnetcdn.com/ajax/jquery.ui/1.8.16/jquery-ui.min.js" />
I would prefer to have a single js file which contains the above references such that I have a single, unchanging reference in all my js files like so:
//These references should enable intellisense within this file
///<reference path="/shared/js/stdafx.js" />
The idea is that stdafx.js would be the file containing the jQuery references. Then I have only one place to update the versions or add additional references. I gave it a quick go, but it didn't seem to work. Can anyone figure out a way to make this happen?
Actually the above common reference did work in the end. I didn't realize how quirky VS was in regards to js intellisense. Funny enough it kicked in after compiling the project.
I did try Ctrl-Shift-J which refreshes the JavaScript as well. It takes a few seconds for it to kick in so give it a chance. Another tip I read was dragging the common.js file into the editor of the .js file I wanted to add the common reference to. This sanity check ensured I had the correct path (it did). It added a relative path (../shared/stdafx.js) but I was able to use an absolute path (/shared/js/stdafx.js) which means I can modify the VS .js template for new js files.
So I would suggest anyone who comes across this question to persevere, refresh the JavaScript, compile, even close and reopen VS as it will hopefully kick in for you eventually.
For anyone still wanting jQuery intellisense in their .js files (and why wouldn't you) you need to 'reference' the correct jQuery VSDOC file, that MS created for Visual Studio intellisense:
///<reference path="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2-vsdoc.js" />
To test it, type:
$(
You should see full intellisense with PARAMETERS, as well as members. If you only see a single list of members, it's not working.

Categories

Resources