I am currently exploring Bucklescript/ReasonML with Svelte 3 for my next project. Typical Svelte ponent is a .svelte
file:
<script>
let name = 'world';
</script>
<h1>Hello world!</h1>
Instead, can I have script
tag with src
or equivalent to keep JS code in a separate file?
<script src='./some-file.js'></script>
By moving the js
code to a separate file, the target of the Bucklescript piler (which is a JS file) could be used for the ponent.
Vue.js already supports this with their SFC .vue
file.
On a side note: I could use Vue.js for this but the presence Virtual DOM is problematic for legacy codebase. And, Svelte is diminishing at runtime and thus very much desirable. Also, the use
this
in Vue makes things awkward in Ocaml/Reason.
I am currently exploring Bucklescript/ReasonML with Svelte 3 for my next project. Typical Svelte ponent is a .svelte
file:
<script>
let name = 'world';
</script>
<h1>Hello world!</h1>
Instead, can I have script
tag with src
or equivalent to keep JS code in a separate file?
<script src='./some-file.js'></script>
By moving the js
code to a separate file, the target of the Bucklescript piler (which is a JS file) could be used for the ponent.
Vue.js already supports this with their SFC .vue
file.
Share Improve this question asked Aug 8, 2019 at 7:18 Harshal PatilHarshal Patil 21k16 gold badges73 silver badges149 bronze badgesOn a side note: I could use Vue.js for this but the presence Virtual DOM is problematic for legacy codebase. And, Svelte is diminishing at runtime and thus very much desirable. Also, the use
this
in Vue makes things awkward in Ocaml/Reason.
2 Answers
Reset to default 13This is possible with the svelte.preprocess API, which you'd most monly reach via the preprocess
option in rollup-plugin-svelte or svelte-loader. Something like this should work (though I haven't tested it):
const path = require( 'path' )
const fs = require( 'fs' )
...
plugins: [
svelte({
// ...
preprocess: {
script: ({ content, attributes, filename }) => {
if ( 'string' === typeof attributes.src ) {
const file = path.resolve(path.dirname(filename), attributes.src);
const code = fs.readFileSync(file, 'utf-8');
return {code, dependencies: [file]};
}
}
}
})
]
As far as I know, this isn't possible right now.
What you could do is export everything you need from the js file, and then import them in the ponent: https://svelte.dev/repl/1d630ff27a0c48d38e4762cf6b0c2da5?version=3.7.1
<script>
import { name } from './mycode.js'
</script>
<h1>Hello {name}!</h1>
export let name = 'World';
However that would only be a partial solution as any mutation of data occurring within the file would not trigger a re-render of the DOM, as Svelte would not pile the .js file and would not be able to add its own code invalidating the values: https://svelte.dev/repl/c4b41b769ed747acb01a02a9af33e545?version=3.7.1
<script>
import { name, handleClick } from './mycode.js'
</script>
<h1 on:click={handleClick}>Hello {name}!</h1>
export let name = 'World';
export const handleClick = () => {
name = 'Everyone';
}
But that doesn't mean you can't be tricky if you are willing to go the extra mile to achieve this: https://svelte.dev/repl/8e259df629614ac99cb14cfae2f30658?version=3.7.1
<script>
import { name, handleClick } from './mycode.js'
const onClick = () => {
handleClick();
name = name;
}
</script>
<h1 on:click={onClick}>Hello {name}!</h1>
export let name = 'World';
export const handleClick = () => {
name = 'Everyone';
}
The extra line name = name
forcing the DOM update.