你已经了解了 modlet 工作流带来的优势,并且想要开始构建具有自己的测试和演示页面的组件。无论你是启动新项目还是更新现有项目,你都需要一个模块加载器和打包器,它不需要为你想创建的每个测试和演示页面都进行构建配置。
StealJS 就是答案。它可以加载任何格式的 JavaScript 模块(AMD、CJS 等),并使用插件加载其他文件类型(Less、TypeScript 等)。它只需要最少的配置,并且与 webpack 不同,它不需要构建即可在开发环境中加载你的依赖项。最后但并非最不重要的一点是,你可以将 StealJS 与任何 JavaScript 库或框架一起使用,包括 CanJS、React、Vue 等。
在本教程中,我们将向项目中添加 StealJS,使用 Preact 创建一个组件,创建一个交互式演示页面,并创建一个测试页面。
文章系列
- 构建大型 JavaScript 应用程序的关键:Modlet 工作流
- 使用 StealJS 提升你的开发工作流(你当前所在位置)
1. 创建新项目
如果你已经有了一个现有的 Node.js 项目:太好了!你可以跳到下一节,我们将把 StealJS 添加到你的项目中。
如果你还没有项目,首先确保你 安装了 Node.js 并更新了 npm。接下来,打开你的命令提示符或终端应用程序以创建一个新文件夹并初始化一个 `package.json` 文件
mkdir steal-tutorial
cd steal-tutorial
npm init -y
你还需要一个本地 Web 服务器来在浏览器中查看静态文件。如果你还没有安装像 Apache 这样的服务器,http-server 是一个不错的选择。
2. 将 StealJS 添加到你的项目中
接下来,让我们安装 StealJS。StealJS 由两个主要包组成:steal(用于 模块加载)和 steal-tools(用于 模块打包)。在本文中,我们将重点关注 steal。我们还将使用 Preact 来构建一个简单的头部组件。
npm install steal preact --save
接下来,让我们创建一个包含一些文件的 `modlet` 文件夹
mkdir header && cd header && touch demo.html demo.js header.js test.html test.js && cd ..

我们的 `header` 文件夹包含五个文件
demo.html
,以便我们可以在浏览器中轻松演示组件demo.js
,用于演示的 JavaScriptheader.js
,用于组件的主要 JavaScripttest.html
,以便我们可以在浏览器中轻松测试组件test.js
,用于测试的 JavaScript
我们的组件将非常简单:它将导入 Preact 并使用它来创建一个函数式组件。
使用以下内容更新你的 `header.js` 文件
import { h, Component } from "preact";
export default function Header() {
return (
<header>
<h1>{this.props.title}</h1>
</header>
);
};
我们的组件将接受一个 `title` 属性并返回一个 `header` 元素。现在我们还看不到我们的组件在起作用,所以让我们创建一个演示页面。
3. 创建演示页面
modlet 工作流 包括为每个组件创建一个演示页面,以便在处理组件时更容易查看组件,而无需加载整个应用程序。拥有一个专门的演示页面还可以让你有机会在多种场景中查看组件,而无需在整个应用程序中分别查看这些场景。
让我们使用以下内容更新我们的 `demo.html` 文件,以便我们可以在浏览器中查看组件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Header Demo</title>
</head>
<body>
<form>
<label>
Title
<input autofocus id="title" type="text" value="Header component" />
</label>
</form>
<div id="container"></div>
<script src="../node_modules/steal/steal.js" main="header/demo"></script>
</body>
</html>
我们的演示文件主体主要包含三个部分
- 一个带有输入的表单,以便我们可以动态更改传递给组件的 `title`
- 一个 `#container`,用于将组件渲染到其中
- 一个 `script` 元素,用于加载 StealJS 和 demo.js 文件
我们在 `script` 元素中添加了一个 `main` 属性,以便 StealJS 知道从哪里开始加载你的 JavaScript。在本例中,演示文件查找 `header/demo.js`,它将负责将组件添加到 DOM 并监听 `input` 值的变化。
让我们使用以下内容更新 `demo.js`
import { h, render } from 'preact';
import Header from './header';
// Get references to the elements in demo.html
const container = document.getElementById('container');
const titleInput = document.getElementById('title');
// Use this to render our demo component
function renderComponent() {
render(<Header title={titleInput.value} />, container, container.lastChild);
}
// Immediately render the component
renderComponent();
// Listen for the input to change so we re-render the component
titleInput.addEventListener('input', renderComponent);
在上面的演示代码中,我们获取了对 `#container` 和 `input` 元素的引用,以便我们可以附加组件并监听输入值的变化。我们的 `renderComponent` 函数负责重新渲染组件;我们在脚本运行时立即调用该函数,以便组件显示在页面上,并且我们还使用该函数作为输入值变化的监听器。
在我们的演示页面生效之前,我们还需要做最后一件事:通过加载 transform-react-jsx Babel 插件来设置 Babel 和 Preact。你可以通过将此添加到你的 `package.json` 中来 使用 StealJS 配置 Babel(来自 Preact 的文档)
...
"steal": {
"babelOptions": {
"plugins": [
["transform-react-jsx", {"pragma": "h"}]
]
}
},
...
现在,当我们在浏览器中加载 `demo.html` 页面时,我们会看到我们的组件和一个用于操作它的表单
太棒了!通过我们的演示页面,我们可以看到我们的组件在不同输入值下的行为。在开发应用程序时,我们可以使用此演示页面来查看和测试**仅此组件**,而不必加载整个应用程序来开发单个组件。
4. 创建测试页面
现在让我们为我们的组件设置一些测试基础设施。我们的目标是拥有一个可以在浏览器中加载的 HTML 页面来运行仅组件的测试。这使得开发组件变得更容易,因为你无需运行整个测试套件或在测试代码中散布 `only` 语句,这些语句最终会被遗忘并在代码审查中被错过。
我们将使用 QUnit 作为我们的测试运行器,但你可以将 StealJS 与 Jasmine、Karma 等一起使用。首先,让我们将 QUnit 作为开发依赖项安装
npm install qunitjs --save-dev
接下来,让我们创建我们的 `test.html` 文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Header Test</title>
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="../node_modules/steal/steal.js" main="header/test"></script>
</body>
</html>
在上面的 HTML 中,我们有两个用于 QUnit 的 `div` 元素和一个用于加载 Steal 并将我们的 `test.js` 文件设置为主要入口点的 `script` 元素。如果你将其与 QUnit 主页 上的内容进行比较,你会注意到它非常相似,**除了**我们使用 StealJS 加载 QUnit 的 CSS 和 JavaScript。
接下来,让我们将此添加到我们的 `test.js` 文件中
import { h, render } from 'preact';
import Header from './header';
import QUnit from 'qunitjs';
import 'qunitjs/qunit/qunit.css';
// Use the fixture element in the HTML as a container for the component
const fixtureElement = document.getElementById('qunit-fixture');
QUnit.test('hello test', function(assert) {
const message = 'Welcome to your first StealJS and React app!';
// Render the component
const rendered = render(<Header title={message} />, fixtureElement);
// Make sure the right text is rendered
assert.equal(rendered.textContent.trim(), message, 'Correct title');
});
// Start the test suite
QUnit.start();
你会注意到我们正在使用 Steal 导入 QUnit 的 CSS。默认情况下,StealJS 只能加载 JavaScript 文件,但你可以使用 插件 来加载其他文件类型!要加载 QUnit 的 CSS 文件,我们将安装 steal-css 插件
npm install steal-css --save-dev
然后更新 Steal 的 `package.json` 配置以使用 `steal-css` 插件
{
...
"steal": {
"babelOptions": {
"plugins": [
["transform-react-jsx", {"pragma": "h"}]
]
},
"plugins": [
"steal-css"
]
},
...
}
现在我们可以加载浏览器中的 `test.html` 文件了

成功了!我们只是在浏览器中运行了该组件的测试,并且 QUnit 提供了一些其他筛选功能来运行特定测试。在处理组件时,你可以仅运行该组件的测试,从而更早地反馈你的更改是否按预期工作。
其他资源
我们已经成功地遵循了 modlet 模式,为我们的组件创建了单独的演示和测试页面!当我们对应用程序进行更改时,我们可以使用演示页面轻松地在不同场景中测试我们的组件,并使用测试页面运行仅该组件的测试。
使用 StealJS,只需要很少的配置就能加载我们的依赖项并创建单个页面,而且我们无需在每次修改后都运行构建。如果您对它提供的其他功能感兴趣,StealJS.com 上提供了有关更高级主题的信息,例如构建生产版本、渐进式加载和使用 Babel。您也可以在Gitter或StealJS 论坛上提问!
感谢您抽出时间学习本教程。请在下面的评论中告诉我您的想法!
文章系列
- 构建大型 JavaScript 应用程序的关键:Modlet 工作流
- 使用 StealJS 提升你的开发工作流(你当前所在位置)
与 Steal 进行某种 JIT 编译相比,像 Webpack 那样预先构建代码是否能提供更好的性能?
是的,这一点非常重要!StealJS 的渐进式加载指南有一节关于创建生产构建的内容,其中包含捆绑所有文件、压缩文件等操作。