如何使用一个命令
运行本地的多帧构图故事书实例tl; dr
问题:我们不能在同一过程中撰写多个故事书,而无需获得cors错误
典型的解决方案:运行一个故事书,打开一个新的终端选项卡,运行下一个,新标签,启动主要组成的故事书
一键式解决方案:使用concurrently
和wait-on
在一个终端选项卡中运行多个故事书。
有关工作代码,请参见此example of a multi-framework composition Storybook。
先决条件知识
注意:本文特定于Running Storybook 本地。
问题:故事书构图CORS错误
使用Storybook组成时最常见的错误似乎与CORS(跨原素资源共享)有关。您可以看到searching Storybook's GitHub repo's issues for CORS + Composition时提到CORS的频率。
基本上,如果父母故事书(引用儿童故事书的故事书实例)是在儿童故事书完全启动之前就开始启动的,并且在浏览器中可以查看,那么父母故事书将丢下错误。 CORS错误将阻止父母故事书加载子女故事书。对于此问题,找不到明确的修复 - 我尝试了一堆。
常见的解决方案是使用多个终端窗口,并在启动父母故事书之前全面启动儿童故事书。
为什么我们必须这样做?
请参阅:âthiste:
nodejs是单线程...
在nodejs进程中运行脚本时,它是当时唯一可以在该过程中运行的脚本。因此,如果您在终端窗口中,则不能在第一个脚本完成之前在该窗口中运行另一个脚本。
...故事书的作品需要等待
在Dev模式下本地运行Storybook时,它不会退出或以其他方式表示该故事书已经开始。在儿童故事书运行之前,编写的故事书不应启动。但是,当父母/组成的故事书实例在同时运行的脚本列表中,使用concurrently
或npm-run-all
之类的脚本并不始终为我工作。。
当然,您可以为每个命令打开一个新的选项卡/终端窗口,但这意味着您的存储库中的所有用户也都需要知道该技巧。效率低下!
以下是一种与单个NPM脚本一致工作的解决方案。
示例代码
Astro的厨房水槽
我们将使用Astro的Kitchen Sink: Microfrontends with Astro,它展示了Astro对多个框架的内置支持(React,preaxct,Svelte和Vue(v3.x
))。这是一个多框架应用程序,这意味着它可以使用UI中多个JS框架的组件 - 非常酷!
StoryDocker Storybook
我们将添加StoryDocker的模块StoryDocker-storybook,该模块注入了设置故事书所需的典型依赖项。
github上的工作代码库
引用的代码可通过the astro-framework-multiple example在Storydocker-examples repo中的the astro-framework-multiple example上找到。
在本地撰写故事书的步骤
步骤1:并行启动儿童故事书
我们将使用concurrently
,一个NPM模块,该模块允许同时运行多个命令。 (Concurrently on npmjs)
儿童故事书不需要彼此存在,因此可以同时开始。
使用concurrently
,我们将并行运行每本儿童故事书。
步骤1.A:运行一本儿童故事书
此命令将运行一个儿童故事书:
npm run storybook -- --config-dir .framework-storybooks/.storybook-preact --port 6001 --no-open
让我们分解该命令:
npm run storybook
是通过package.json
中的NPM脚本storybook
运行故事书的命令。该脚本用命令storybook dev
调用Storybook CLI。
--
额外的双键使我们可以将标志和选项直接发送到storybook dev
--config-dir .framework-storybooks/.storybook-preact
是用preact
特定配置在本地目录中找到的故事书的命令
--port 6001
是在港口6001
上运行故事书的命令
--no-open
告诉故事书启动时不要打开浏览器窗口。
因此,所有这些都意味着我们使用.framework-storybooks/.storybook-preact
中的配置启动了故事书实例,并且我们正在端口6001
上运行它,并告诉Storybook跳过它打开浏览器窗口的默认行为。
步骤1.B:其他儿童故事书
示例代码还有其他3个儿童故事书,因此我们也需要运行这些书籍。他们是:
react:npm run storybook -- --config-dir .framework-storybooks/.storybook-react --port 6002 --no-open
svelte:npm run storybook -- --config-dir .framework-storybooks/.storybook-svelte --port 6003 --no-open
查看:npm run storybook -- --config-dir .framework-storybooks/.storybook-vue --port 6004 --no-open
p>
步骤1.C:并行运行所有儿童故事书
将它们放在一起,我们将使用concurrently
并行运行所有儿童故事书。这是我们将使用的NPM脚本:
"sbook-children": "npx concurrently \"npm run storybook -- --config-dir .framework-storybooks/.storybook-preact --port 6001 --no-open\" \"npm run storybook -- --config-dir .framework-storybooks/.storybook-react --port 6002 --no-open\" \"npm run storybook -- --config-dir .framework-storybooks/.storybook-svelte --port 6003 --no-open\" \"npm run storybook -- --config-dir .framework-storybooks/.storybook-vue --port 6004 --no-open\"",
运行npm run sbook-children
将并行启动所有儿童故事书。我们使用npx
代替npm
,因此我们可以避免将concurrently
添加为依赖项。
步骤2:运行父母故事书
我们不想在所有子故事书都在浏览器中运行和可查看之前启动父母故事书。
。步骤2.a:父母故事书
主要组成的故事书被配置为.storybook
目录中的普通故事书。唯一的添加是由main.js
进口的koude30 file,并包含对儿童故事书的参考。 refs.js
的内容是:
export default {
"astro_preact": {
"title": "preact",
"url": "http://localhost:6001",
},
"astro_react": {
"title": "react",
"url": "http://localhost:6002",
},
"astro_svelte": {
"title": "svelte",
"url": "http://localhost:6003",
},
"astro_vue": {
"title": "vue",
"url": "http://localhost:6004",
},
}
步骤2.b:等待一本儿童故事书
我们将使用wait-on
,一个NPM模块,该模块可以阻止节点继续过程,直到满足条件。在这种情况下,wait-on
将在继续之前检查每个localhost
端口。 (wait-on on npmjs)
此命令:
npx wait-on http://localhost:6001
将等到localhost:6001
打开并返回2xx
响应,然后再继续进行。
port 6001
是
步骤2.C:等待所有儿童故事书
我们将在每个Localhost检查之间添加一个双关节,这意味着wait-on
将等待每个端口依次。毕竟wait-on
s,我们将使用npm run storybook
启动Storybook。
以下NPM脚本将等待所有儿童故事书打开,然后继续打开父母故事书。
"sbook-parent": "npx wait-on http://localhost:6001 && npx wait-on http://localhost:6002 && npx wait-on http://localhost:6003 && npx wait-on http://localhost:6004 && npm run storybook",
步骤3:单个命令运行所有故事书
再次使用concurrently
,我们将同时运行子女NPM脚本:
npx concurrently "npm run sbook-children" "npm run sbook-parent"
和package.json中的NPM脚本:
"sbook": "npx concurrently \"npm run sbook-children\" \"npm run sbook-parent\""
步骤4:利润!
愉快的编码人员!