Reputation: 47081
I've been really intrigued by Svelte when I went through the documentation yesterday, but I'm struggling to set up even a pretty basic project and I can't seem to figure out what I'm doing wrong.
I'm starting out with the following HTML :
<!doctype html>
<html>
<head>
<title>My first Svelte app</title>
</head>
<body>
<main></main>
<script src='App.js'></script>
<script>
const application = new App({
target: document.querySelector( 'main' ),
data: {
name: 'world'
}
});
</script>
</body>
</html>
Then, I create the following App.html
component :
<div class="app">Hello {{name}}</div>
<div class="lines"></div>
<script>
export default {}
</script>
I run svelte compile --format iife App.html > App.js
, and everything works fine.
So far, so good!
Now, I create a Line.html
component with the following content :
<div class="line">{{value}}</div>
<script>
export default {}
</script>
I modify my App.html
component like this :
<div class="app">Hello {{name}}</div>
<div class="lines"></div>
<script>
import Line from './Line.html';
export default {
oncreate() {
const line = new Line({
target: document.querySelector( 'lines' ),
data: {
value: 'test'
}
});
}
}
</script>
I would expect this code to add something like <div class="line">test</div>
to the DOM as a child of <div class="lines"></div>
.
However, I get the following warning when I compile this code :
No name was supplied for imported module './Line.html'.
Guessing 'Line', but you should use options.globals
And when I try to run the compiled code, I just get the following output in my console :
App.js:250 Uncaught ReferenceError: Line is not defined at App.js:250
index.html:10 Uncaught TypeError: App is not a constructor at index.html:10
What am I doing wrong here?
I also raised this issue on Github.
Upvotes: 1
Views: 1594
Reputation: 29585
Copying the answer from GitHub:
svelte-cli
works on individual files — you would need to compile Line.html
separately, and include it on the page like so:
<!doctype html>
<html>
<head>
<title>My first Svelte app</title>
</head>
<body>
<main></main>
<script src='Line.js'></script> <!-- one for each component! -->
<script src='App.js'></script>
<script>
const application = new App({
target: document.querySelector( 'main' ),
data: {
name: 'world'
}
});
</script>
</body>
</html>
It will guess that Line.js
is defining a global variable called Line
, which is how App.js
is able to reference it — but it prefers that you're explicit about that, by using the --globals
option.
Needless to say, this is a huge pain — it doesn't scale at all past a certain point. For that reason we recommend that you use a build tool with Svelte integrated. That way, you don't have to worry about juggling all the different imported files, and as a bonus Svelte is able to generate more compact code (because it can deduplicate some helper functions between components).
The easiest way to get started — and I keep meaning to write a very short blog post about this — is to click the 'download' button in the REPL. That will give you a basic project setup that you can get running with npm run dev
and npm start
. Under the hood it uses Rollup to create a bundle that can run in the browser.
Here's your test app running in the REPL. Notice that the way we use the <Line>
component is by declaring it using components
, and just writing it into the template, rather than manually instantiating it with oncreate
.
Upvotes: 3