Search code examples
javascriptfileimportbrowser

JS in Browser: create JS file and import it dynamically


Is it possible for browser javascript to create a new JS-file programmatically and then import it?

Here is some code that I tried out but didn't work:

const file = new File([`export function main() {console.log("AAA")}; main();`], "transpiled.js", {
    type: "text/javascript"
})
import("./transpiled.js") // this says: net::ERR_ABORTED 404 (Not Found)  
import("transpiled.js") // this says: Uncaught (in promise) TypeError: Failed to resolve module specifier 'transpiled.js'

The task is to get AAA as console output.


Solution

  • To import a script, you have to get a url that points to the file, could be an absolute url, relative url or a data url. In your case you have the file but since you created it programmatically, it is not bound to any url.

    You could convert it to a data url as in the suggested answer but I don't think that will scale for very huge files, to circumvent that you could use URL.createObjectURL.

    This will create a reference blob url from the file using the current location as the origin

    const file = new File([`export function main() {console.log("AAA")}; main();`], "transpiled.js", {
        type: "text/javascript"
    })
    
    // Create blob url
    const url = URL.createObjectURL(file)
    
    import(url).then(module => {
      // Use module
      console.log(module)
    })

    You could also use URL.revokeObjectURL to remove the reference to the file when you are done using it

    // After using the url
    URL.revokeObjectURL(url)