im using Pheonix LiveView for a WebApp that relies on reading/writing the users clipboard.
Thus i rely on some regular Javascript to be executed. At the moment i have a fairly large <script> tag in my component that contains all this code.
While developing some new features, i needed this Javascript code in two different compoents, also i wanted to trim down my component and outsource all the Javascript contained in the <script> tag there.
Using Javascript only, this is a fairly simple task, but using Phoenix/LiveView it’s unclear for me how to accomplish this. First attemp was to create a clipboard.js file, along app.js. This contains all my functions and exports them for import and use anywhere else.
function copyTo() { /*...*/ }
function copyFrom() { /*...*/ }
export { copyTo, copyFrom }
So in app.js i can simply write
import {copyTo} from "./clipboard"
copyTo("Hello")
This works, because the code from both file runs through webpack.
But when trying to user this code in the <script> section of any component it’s a different story. The code there is just plain, unprocessed Javascript, so it’s not possible to use import ... and access all my clipboard function.
Current workaround for me is to import the functions in app.js and then assign them to the global window object. But in order to get this working i had to remove the defer attribute from the <script> tag in root.html.leex, in order to get the Code in app.js executed before the Javascript code in my component. This all seems very hacky to me for such a seemingly simple task.
So my question is, what is the correct (or at leat more elegant way) to share Javascript code between components and how to use Javascript code that is organized in modules that need to be imported outside app.js?
Isnt this a common scenario with all packages/libraries installed via npm?
Using "type="module" on your script tags allow you to use imports and such, but it doesn’t seem to work on IE (if that’s a concern) .
Other than that probably using web pack to generate other entry points that can then be used as a regular scripts?
I think modules in JS and JS in overall are complex and hacky, that’s why you need bundlers, transpilers, syntax fixers, pre and post processors and everything else since it has to produce code for different targets each one following it’s own whims, syntax that is not implemented directly by vendors while they work on it, etc. This works sort of okeish when staying completely in nodejs realm, but easily breaks down outside of it.
I also don’t see much issue with having a namespace in window from where I can access shared functions, but yeah, it’s not as clean as using import.
Great suggestions, didn’t know about this.
Browser support is also pretty okay: https://caniuse.com/es6-module
I changed my webpack.config.js to include my clipboard module:
For the life of me I couldn’t get this setup working for some reason.
I keep getting the error message could not find a name export named default from my “clipboard.js” file.
Is there anything else that you had to add into your webpack configuration to implement this solution? I’ve, unfortunately, had to revert to attaching behavior onto the window for now.