Ignore cache import modules es6 - javascript

I'm working with the webcomponents standard, but in reality, the same thing happens with any import of es6 modules.
When I update a web component and upload it to the server, since these are imported with es6 modules, users do not see the update until they force to refresh the browser's cache.
This is a problem when it is a hotfix or when the update requires a component that the user already has in cache, but this component has had some update in the code necessary for the operation of the new component.
I've been looking, but haven't found anything that really works for me to force the browser to request the javascript modules from the server. Not even by uncaching the .htaccess, the browser keeps caching a copy and serving it from the cache itself.
I used to use the trick of putting the version in the src attribute of the script tag.
<script src="https://example.com/src/js/myscriptfile.js?v=1.1.2"></script>
But when importing with an import statement inside the javascript file this is no longer an option.
Any ideas that work?

I used the following import statement for a file that is transpiled by Babel & minified by Webpack, and it is also served directly as a <script type="module"....
This technique causes Chrome v102 to download the file each time the "v" value changes (i.e., cache the imported file until I change tye hard-coded URL query parameter that I used in the import statement), which I change when I update the file so that the new file will be downloaded by the browser.
import { myFunction } from './myFile.js?v=2022-06-17T12.48';
NOTE: There is a chain reaction, so you'll need to do the same thing for any files that are imported from within myFile.js, assuming you want to control the caching of those files also.

Related

Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”)

Apologies if this is a repetitive question however I have looked all over and found no suitable solution for my particular issue.
I am attempting to build a simple JavaScript game but am having issues with importing images.
For reference, here is my relevant code:
index.html
<canvas id="gameScreen" width="1420" height="965"></canvas>
<script src="src/index.js" type="module"></script>
And from my index.js file:
import platform from "../assets/platform.png";
I am receiving the following error when trying to import this image:
Script from “http://127.0.0.1:5500/assets/platform.png” was blocked because of a disallowed MIME type (“image/png”).
I have tried changing the 'type' specified in the script tag, to no avail.
Also, I should note I am using the Live Server extension.
Any help is much appreciated.
In JavaScript, the ES6 import statement can't be used to import anything except JavaScript modules.
Tools like Webpack — which pre-process import statements to convert JS programs using ES6 modules into a format that browsers which doesn't support modules can use — can do things with non-JS resources.
They aren't executing the JavaScript, so the rules for them are different.
At the simple end of the scale, this involves copying the non-JS file to the build directory and replacing the import with a variable declaration and assigning a URL (in a string) to that variable.
Since you aren't using a bundler, you need to do that yourself.
Replace:
import platform from "../assets/platform.png";
with something like
const platform = "/path/to/platform.png";

Importing files from a either src/ or lib/

I have a package (let's call it preset) that imports a component (component). Both are maintained by me. For backwards compatibility, preset additionally has to import a specific function from component, which is only available from a specific file (not the one in the main field). To do this, I use the require('component/lib/file.js') syntax.
However, file.js has side-effects. This is fine normally, but for Webpack builds I also have lib-mjs (with ES module syntax for tree shaking). This causes file.js to be loaded twice, once indirectly in lib-mjs via component, and once directly in lib.
A few options:
I could move file.js out of lib/lib-mjs altogether. However, this complicates the build process and messes up the repo structure.
I could export the specific function anyway. However, since component follows the same pattern with a lot of different components, I'd have to change that in a lot of places.
I could remove the side-effect to some init function. However, this would be a breaking change and involve quite some work.
I could make sure the side-effect only happens if it hasn't happened already. However, that and the previous change still has the file loaded twice. On top of that, it would require some semi-global state, I don't think I can pull off duck-typing for this one.
Is there some option like require(require.resolve('component') + '/file.js') that actually works for both Node and Webpack?

Import function from sister file Node.JS

I hope to explain this in a non-abstract way. I have a problem and I believe that I am pushing the boundaries of Node because there doesn't seem to be much documentation on this particular subject.
To start out, this is my file layout.
//main.js
var 1 = require('1.js');
var 2 = require('2.js');
The purpose of this first file is to load two child files into the process.
//1.js
console.log('Test');
module.exports = function msgUSR(text){
console.log(text);
}
The purpose of this file is to create an export, this export could very obviously be imported into Main.js , however, I have a situation where I need to import a function from 1.js into 2.js without reloading the entire file into memory.
for example.
//2.js
var msgUSR = require('1.js');
msgUSR('blah');
The problem with this setup is that when you require 1.js, it reloads the entire file, including any code that isn't an export.
How could I only import the exports of a file without loading the unrelated code.
Thank you! I know someone has a solution to this.
EDIT:
I understand that the code here wouldn't replicate any useful data. My point is, how do I require a function in another JS file that is already required by a parent file. Instead of writing two long hefty functions that are exactly alike in two different files, I need to be able to call the function from a sister file.
Here is why this is an issue.
If you were to require the file after the parent has required it, 'Test' would appear two times, symbolically meaning that other complex code would also be loaded.
My hopeful result from this question would be a result where I could require the file in such a way as to only import a function from it.
Thanks again.
The problem with this setup is that when you require 1.js, it reloads
the entire file, including any code that isn't an export.
When you require something the file will be loaded once and then is cached
How could I only import the exports of a file without loading the
unrelated code?
You would never have to reload the file once it is already required since Node will use the cached version.
The require function normally has 5 steps:
Resolving: To find the path of the file
Loading: To determine the type of the file content
Wrapping: To give the file its private scope. This is what makes both the require and module objects local to every file we require.
Evaluating: This is what the VM eventually does with the loaded code.
Caching: So that when we require this file again, we don’t go over all the steps another time.

Is it correct in terms of principle, to use `import` statement to import file types other than JS

Does using the JavaScript import statement for images, css and others defeat the purpose of import statement which was designed to import only the JS Modules ?
Of course, for now it gets transpiled to ES5 require using webpack. But that same question comes up again. Is it incorrect to use import statement to import images or css or files ?
EDIT:
I like the idea of controlling imports that we can control the assets on build time in such a clean way - The idea that I use the image path to import the image, and
on different environments the image path would contain different values - url or path
this image can be compressed on build time
the JS module importing this image can contain the image dimensions through a custom loader
assets dependency tree is maintained at one place and un-imported items gets chucked away automatically
rebuild time is fast - DX(developer experience) would be good
I guess, this is much better than using any templating, using placeholders in the JS files to inject URLs or paths based on environment during pre-build (webpack).
But using the import statement feels not right to do so in terms of principle or semantics.
This is from Mozilla Developer Network:
The import statement is used to import functions that have been exported from an external module, another script, etc.
From everything I've read on MDN and other sources its purpose is to make a module/script methods and properties available within the current scope it's being imported into.

less.js: Use custom import function

less.js is using an internal xhr() function to load #imported .less files dynamically via ajax.
I want to know if there is anything I can do the hand a custom function over to the less parser to get the imported files loaded through this function and NOT through the default loading function.
As a wild example: I may have stored the .less file I want to import in my localStorage and want less.js to load it from there, instead via AJAX.
You could always create a fork and override or change loadStyleSheets and have it check in localStorage first.
Since the entire system is designed to run a closure it'll be hard (if not impossible -- I've never tried to modify a closure from outside the closure) to make any additions post-library load.

Categories

Resources