Svelteをwebpackで動かしてTODOリストを作成してみた


私はsvelteに最近さわってみた者です。間違っていたら指摘お願いいたしますm(_ _)m

私が作成したtodoリストのサンプル


参考

.svelteファイルのシンタックスハイライトはsvelte-vscodeを使用して開発させていただきました

Install

yarn add -D svelte svelte-loader css-loader mini-css-extract-plugin webpack webpack-cli webpack-dev-server
  • svelte
  • svelte-loader
    • svelteコンポーネント用のローダー
  • css-loader
    • cssローダー
  • mini-css-extract-plugin
    • cssを抽出できるプラグイン

Hello World!

webpack.config.jsはこちらを参考にしました

webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
    mode: process.env.NODE_ENV || "development",
    module: {
        rules: [
            {
                test: /\.svelte$/,
                use: {
                    loader: "svelte-loader",
                    options: {
                        // tureにすることで、
                        // svelteファイルの<style>タグをのcssを
                        // 「test: /\.css$/」のフローでコンパイルできる
                        emitCss: true,
                    }
                },
            },
            {
                test: /\.css$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                ],
            },
        ]
    },
    resolve: {
        extensions: [".mjs", ".js", ".svelte"],
    },
    plugins: [
        // 出力する際のファイル名を指定する
        new MiniCssExtractPlugin({ filename: "[name].css" }),
    ],
    devServer: {
        port: 9000,
        contentBase: "./",
        publicPath: "/dist/",
        open: true
    }
};
src/index.js
import App from "./App";

const app = new App({
    target: document.body,
});

export default app;
src/App.svelte
<script>
  let value = "world";
</script>

<style>
  h1 {
    color: purple;
  }
</style>

<h1>Hello {value} !</h1>
index.html
<!DOCTYPE html>
<meta charset=UTF-8>
<title>Document</title>
<link rel=stylesheet href=dist/main.css>
<script src=dist/main.js defer></script>
yarn webpack-dev-server #http://localhost:9000/で確認できる

TODOリスト作成

src/App.svelte
<script>
  import { afterUpdate } from "svelte";
  afterUpdate(() => {
    document.querySelector(".js-todo-input").focus();
  });

  let todoItems = [];
  let newTodo = "";

  function addTodo() {
    newTodo = newTodo.trim();
    if (!newTodo) return;

    todoItems = [...todoItems, { text: newTodo, complete: false }];
    newTodo = "";
  }

  function toggleDone(index) {
    todoItems[index].complete = !todoItems[index].complete;
  }

  function removeTodo(index) {
    todoItems = todoItems.filter((_, i) => i !== index);
  }

  let value = "world";
</script>

<style>
  h1 {
    color: purple;
  }

  .done {
    text-decoration: line-through;
  }

  .delete {
    color: #777;
    text-decoration: none;
  }
</style>

<h1>Hello {value} !</h1>
<form on:submit|preventDefault={addTodo}>
  <input type="text" class="js-todo-input" bind:value={newTodo} />
  <button type="submit">Add Todo</button>
</form>
<ul>
  {#each todoItems as todo, index}
    <li>
      <input
        id={index}
        type="checkbox"
        bind:checked={todo.complete}
        on:click={() => toggleDone(index)} />
      <span class={todo.complete ? 'done' : ''}>{todo.text}</span>
      <a
        href="#hoge"
        class="delete"
        on:click|preventDefault={() => removeTodo(index)}>
        [x]
      </a>
    </li>
  {/each}
</ul>

TODOリストを作成することができました。最後まで読んでいただいてありがとうございました。m(_ _)m