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的过程,足以让你继续配置它,实现你的愿望。