如何用Rollup设置一个Svelte应用程序

523 阅读9分钟

Svelte是一个相对较新、速度极快的前端UI库。像其他一些前端库(如React)一样,Svelte代码不能立即被浏览器解释和执行。相反,你必须添加一个构建步骤,将你的Svelte代码变成浏览器能够理解的HTML、CSS和JavaScript。

这篇文章将探讨如何使用Rollup构建用于开发和生产的Svelte应用程序的基础知识。

创建一个基本的Svelte应用程序

让我们先创建一个超级简单的Svelte应用程序。首先,我们将创建我们的应用程序目录,我们将其称为my-svelte-app

mkdir my-svelte-app

接下来,让我们导航到该目录,并初始化一个新的npm项目。我们将使用-y 标志来使用默认设置。

cd my-svelte-app
npm init -y

很好,我们现在有一个基本的package.json 文件。当然,这是一个精简的项目,所以我们要做的第一件事是把svelte 作为一个开发依赖。

npm i svelte

按照惯例,我们将在src 目录下编写我们的应用程序代码。我们将创建这个目录,一个用于我们的组件代码的App.svelte 文件,以及一个main.js 文件,该文件将实例化我们的应用程序,并告诉它在哪里被插入DOM。

mkdir src
touch src/App.svelte src/main.js

在我们的App.svelte 文件中,我们将只是有一段输出 "Hello [name]",其中这个名字是一个道具。

App.svelte

<script>
  export let name;
</script>

<p>Hello {name}</p>

接下来,我们将配置main.js 。在这里,我们创建一个我们的App 的新实例,计划在文档的主体中加载我们的应用程序(document.body),我们将为我们的组件提供一个name"Daffodil"

main.js

import App from './App.svelte';

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

export default app;

很完美!我们已经完成了对我们的Svelage的设置。我们已经完成了我们的Svelte应用程序的设置,但我们没有办法在开发模式或生产中运行它;它现在只是一堆Svelte代码。

正如我之前所说,我们将使用Rollup将我们的Svelte代码转换为浏览器可读的HTML、CSS和JavaScript。

添加Rollup

Rollup是一个用于JavaScript应用程序的模块捆绑器。它采用模块化代码,如我们的Svelte应用程序,并将其捆绑成浏览器可以随时解析并显示给用户的文件。这意味着将像我们的.svelte 文件及其各种导入、道具等转换为HTML、CSS和JavaScript文件。Webpack是另一个这样的模块捆绑器,也可用于Svelte项目。不过,今天我们重点讨论Rollup。

开始使用Rollup

当你克隆一个Svelte模板(或其他UI库如React的模板)时,你可能会注意到一件事,那就是模块捆绑器的配置文件看起来很复杂,难以接近。事实上,这些文件很多内容,但如果我们从头开始创建它们,并逐步增加功能,我们就能看到这一切都很有意义,而且是非常可行的。

既然如此,让我们动手去做吧!我们要做的第一件事是为我们的项目添加rollup 作为开发依赖。

npm i -D rollup

接下来,我们需要添加两个额外的rollup开发依赖项。

  • @rollup/plugin-node-resolve,它用于帮助rollup解决第三方插件
  • rollup-plugin-svelte 一个第三方插件,用于帮助rollup了解如何处理Svelte应用程序
npm i -D @rollup/plugin-node-resolve rollup-plugin-svelte

请记住,我们正在使用-D 标志来安装这些开发依赖项。毕竟,我们只在开发中使用rollup;当我们进入生产阶段时,我们的应用已经被构建成HTML、CSS和JavaScript。

创建卷积配置文件

让我们创建一个非常简单的rollup配置文件。目前,它所要做的就是将我们的Svelte应用捆绑到一个public/build 文件夹中的JavaScript。

touch rollup.config.js

在该文件中,我们的默认输出将是rollup config对象。

rollup.config.js

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';

export default {
  // This `main.js` file we wrote
  input: 'src/main.js',
  output: {
    // The destination for our bundled JavaScript
    file: 'public/build/bundle.js',
    // Our bundle will be an Immediately-Invoked Function Expression
    format: 'iife',
    // The IIFE return value will be assigned into a variable called `app`
    name: 'app',
  },
  plugins: [
    svelte({
      // Tell the svelte plugin where our svelte files are located
      include: 'src/**/*.svelte',
    }),
    // Tell any third-party plugins that we're building for the browser
    resolve({ browser: true }),
  ],
};

希望这一次不会太多input 字段告诉rollup应用程序的主要入口在哪里,output 字段指定了关于捆绑结果的信息,plugins 文件告诉rollup如何处理输入的应用程序。

将Rollup添加到我们的NPM脚本中

在我们的应用程序进行试运行之前,我们需要做的最后一件事是使我们能够(a)用npm脚本运行rollup,以及(b)服务于添加到public 文件夹中的内容。

用npm脚本运行rollup

为了用npm脚本运行rollup,让我们在我们的package.json 文件中添加一个新的脚本。

package.json

/* other package.json content here */
{
  "scripts": {
    "dev": "rollup -c -w"
  }
}
/* other package.json content here */

-c 标志表明我们希望rollup使用一个配置文件。由于我们没有提供文件的位置,rollup会认为我们遵循了一个惯例,当我们把我们的配置文件命名为rollup.config.js-w 标志是非常方便的,因为它告诉rollup观察我们包含的应用程序文件是否有变化。当有任何变化时,rollup将帮助我们重建我们的应用程序到public/build/bundle.js

现在,如果我们去命令行并运行npm run dev ,我们应该看到rollup已经将我们的应用程序捆绑到一个新的public/build/bunde.js 文件中。成功了!

提供内容

我们有了捆绑的JavaScript,但如果没有一个html文件,浏览器就不知道该怎么处理它。因此,让我们在我们的public 文件夹中添加一个index.html 文件。

touch public/index.html

在这个index.html 文件中,让我们创建一个HTML文件,正文中没有任何内容。然而,我们要确保添加一个scrpt 标签,从/build/bundle.js 中加载我们捆绑的JavaScript。

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>My Svelte App</title>
    <script defer src="build/bundle.js"></script>
  </head>
  <body></body>
</html>

现在,我们需要一个简单的网络服务器来服务我们的index.html 文件。我们将使用一个叫做sirv-cli 的流行的npm包来做这件事。由于这只是为了开发,我们将再次只添加sirv-cli 作为开发依赖。

npm i -D sirv-cli

现在让我们添加一个npm脚本来为我们的应用服务。我们将把它放在start 脚本下。

/* other package.json content here */
{
  "scripts": {
    "dev": "rollup -c -w",
    "start": "sirv public"
  }
}
/* other package.json content here */

现在,我们终于可以构建和启动我们的应用程序了现在,我们将首先运行dev 脚本,然后运行start 脚本。

npm run dev && npm run start

现在你应该能够导航到http://localhost:5000,并看到你的Svelte应用程序的所有荣耀

现在,如果我们把src/main.js 文件中的name 道具改为"Nick" (或你自己的名字),rollup将帮助我们重建应用程序。请注意,我们的应用程序不会自行刷新,我们必须继续刷新http://localhost:5000,以看到这些变化。

这些是基础知识

恭喜你,这些就是使用rollup来构建和服务你的Svelte应用程序的基础知识!这是很好的信息。这是一大块信息,所以如果你想就此打住也是合理的。然而,我们还可以做一些增强和改进如果你还有胃口,那就和我一起前进,让我们的开发过程更强大一些。

增强和改进

我们可以对我们的项目做出相当多的改进。我们将在这篇文章中解决两个主要的改进:让rollup为我们启动开发服务器,并在项目中加入热重载。

这里的大部分工作都来自于位于这里的Svelte启动器模板。非常感谢该软件仓库的维护者。

让Rollup启动服务器

运行npm run dev && npm run start 是一件很麻烦的事情,我们应该只需要运行npm run dev 来启动我们的开发服务器。因此,让我们利用rollup插件的灵活性来创建我们自己的serve 插件。

我们的自定义serve 插件可以被添加到我们的rollup.config.js 文件的顶部。它需要导出一个带有writeBundle 键的对象,该键是一个函数。然后我们可以在我们的plugins 数组中调用我们的serve 函数。

rollup.config.json

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';

function serve() {
  return {
    writeBundle() {},
  };
}

export default {
  input: 'src/main.js',
  output: {
    file: 'public/build/bundle.js',
    format: 'iife',
    name: 'app',
  },
  plugins: [
    svelte({
      include: 'src/**/*.svelte',
    }),
    resolve({ browser: true }),
    serve(),
  ],
};

让我们填入serve 的函数。下面是该函数的一个完整版本,其中有一些内联注释。请注意,这篇博文不会详细讨论在node中生成一个子进程的问题,因为这有点超出了范围!

function serve() {
  // Keep a reference to a spawned server process
  let server;

  function toExit() {
    // kill the server if it exists
    if (server) server.kill(0);
  }

  return {
    writeBundle() {
      if (server) return;
      // Spawn a child server process
      server = require('child_process').spawn(
        'npm',
        ['run', 'start', '--', '--dev'],
        {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        }
      );

      // Kill server on process termination or exit
      process.on('SIGTERM', toExit);
      process.on('exit', toExit);
    },
  };
}

现在我们可以继续在终端运行npm run dev ,我们会看到我们的sirv 服务器已经为我们启动了!我们可以导航到http://localhost:5000,我们就可以开始运行了。

添加热重新加载

你可能注意到,当我们对Svelte应用程序进行修改时,rollup会重建我们的捆绑程序,但我们必须刷新浏览器才能看到修改。实际上,有一个非常简单的方法可以让这种情况发生,而不需要手动刷新--有一个叫rollup-plugin-livereload !的软件包。

npm i -D rollup-plugin-livereload

然后我们简单地把它添加到我们的滚动配置插件阵列中。它需要一个字符串参数,指定监视实时重载的文件夹。在这种情况下,我们希望观看public 中的任何内容。

rollup.config.js

import svelte from 'rollup-plugin-svelte';
import resolve from '@rollup/plugin-node-resolve';
import livereload from 'rollup-plugin-livereload';

function serve() {
  // Keep a reference to a spawned server process
  let server;

  function toExit() {
    // kill the server if it exists
    if (server) server.kill(0);
  }

  return {
    writeBundle() {
      if (server) return;
      // Spawn a child server process
      server = require('child_process').spawn(
        'npm',
        ['run', 'start', '--', '--dev'],
        {
          stdio: ['ignore', 'inherit', 'inherit'],
          shell: true,
        }
      );

      // Kill server on process termination or exit
      process.on('SIGTERM', toExit);
      process.on('exit', toExit);
    },
  };
}

export default {
  input: 'src/main.js',
  output: {
    file: 'public/build/bundle.js',
    format: 'iife',
    name: 'app',
  },
  plugins: [
    svelte({
      include: 'src/**/*.svelte',
    }),
    resolve({ browser: true }),
    serve(),
    livereload('public'),
  ],
};

现在,如果我们用npm run dev 来启动我们的应用程序,我们可以看到,每当我们对Svelte文件进行修改时,我们的服务器就会热重新加载应用程序。很好!

继续探索

你可以配置的东西还有很多(CSS/预处理器支持,生产与开发中的各种配置差异,非常酷的插件的广泛生态系统),所以希望这篇文章能帮助你涉足并真正了解Svelte/Rollup的过程,足以让你继续配置它,实现你的愿望。