Code Kitchen:一个支持多文件与私有库的离线React Playground方案
Posted 前端之巅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Code Kitchen:一个支持多文件与私有库的离线React Playground方案相关的知识,希望对你有一定的参考价值。
CSS Module 支持。FreeWheel 内部 UI 大多数还是以 CSS Module 方式管理样式,示例代码同样如此。
纯静态 部署,支持离线访问。静态部署可以显著降低部署和维护成本。
最终,我们选择借助 esbuild 等开源库,实现了一套 FreeWheel 自研的解决方案,它能比较好的覆盖上述需求。这套方案已经为 FreeWheel 的 UI 文档页面服务了几个月的时间,并且得到了业务团队的认可。
我们认为此方案不光应用于 FreeWheel 的场景。同时为了回馈社区,因此在最近正式以 Code Kitchen 的名称在 GitHub 开源。你可以在此找到项目的代码仓库 https://github.com/freewheel/code-kitchen。
接下来,此文会聊一聊 Code Kitchen 诞生的故事。
```
```css styles.css
img
height: 200px;
```
</Sandpack>
在上面的例子中,<Sandpack />
是一个自定义的 Sandpack 组件。
解析嵌入的代码块并将它们作为虚拟文件使用
将解析好的文件传入 Sandpack,以初始化 playground
熟悉 MD 语法的读者可得知,我们可以通过给代码块增加语言缩写(如js
, css
),让常见的 MD 应用为其激活代码高亮。进一步的,我们还可以在语言后面增加自定义后缀,比如为代码块增加文件名。
假定所有文件处于一个虚拟的文件目录下,那么文件模块之间可以通过如 import \'./styles.css\'
的方式以相对路径进行访问。同时,假设我们把第一个文件看做虚拟文件的入口,就得到了一个标准的 ESM 模块树。
用上面的思路,我们就可以在 MD 中为一个代码示例提供多文件支持,让 playground 有类似于 IDE 般的体验。
对于我们的用法,我们需要为 UI 组件的 playground 导入来自于私有 registry 的 npm 包。Sandpack 给出了一个 定制 bundler 服务器导入私有包 的解决方案,但我们之后意识到我们真正需要的不是导入远程私有包,而是直接在 playground 里使用内部依赖源代码,这样可以降低本地开发时的版本管理难度。
此外,Sandpack 的打包器和组件预览运行于一个指向到远程服务的 iframe 内执行。如果需要自己定制这个远程服务,就会增加更多的人力成本、消耗额外的计算资源。如果可能的话,我们希望能找到一个纯静态的解决方案。
支持 CSS Module
与 MDX 有良好的兼容性
纯静态 方案
有 类型提示 功能的编辑器
接下来,我们会简单说明一下 code kitchen 使用 esbuild-wasm 的一些工作细节。
code: string;
一个 Code Kitchen 的输入可能会有一个或者多个文件。默认情况下,我们会以第一个文件作为入口文件。对于 Code Kitchen 来说,它的入口文件需要是一个 jsx/tsx ESM 模块,并且它的 default export
需要是一个合法的 React 函数组件。
打包过程中,esbuild 会遍历模块树,并解析所有的导入路径。导入的路径可能有两种:
相对路径:如果一个文件路径以 ./
开头,那么我们认为这个文件可以在 Code Kitchen 的文件列表参数中找到。这些文件会被转译并打包到最终结果内。
外部标识符:任何除了相对路径的模块导入都被识别为外部依赖项目,比如 React、Spark UI (FreeWheel 内部的 React 组件库) 等。外部模块导入项会以 CJS 模式转译为 require("react")
的形式存在于打包结果中。
打包后的内容实际上是一个完整的 JS 字符串。我们会将其包裹到 new Function
中,然后以下面的形式替代模块中的 require
函数:
(function (require)
// bundled js script ...
)(myCustomRequire);
假定你需要 react
与 my-private-lib
,那么就可以这样定义你自己的 require
,为运行时提供外部依赖:
import * as React from "react";
import * as privateLib from "my-private-lib";
const dependencies =
react: React,
"my-private-lib": privateLib,
;
const require = (key: string) =>
const res = (dependencies as any)[key];
if (res)
return res;
throw new Error("DEP: " + key + " not found");
;
.module.css
后缀修饰 CSS 文件,分别指定全局生效的 CSS,或是使用 CSS Module。对于每一种模式,我们都使用了类似于 Webpack style-loader 的方式,将 CSS 通过 Stylis 库转译,然后转成 JS 语句放入打包结果中。这样在打包的脚本执行时,将自动把 CSS 作为 style 标签插入到 DOM 树中。
由于 esbuild 目前还没有支持 CSS Module,并且市面上也没有找到能在浏览器中运行的替代库,因此我们借助 Stylis 解析 CSS AST 的能力实现了一种适合于 playground 的 CSS Module 标准的一个子集。
以上是 FreeWheel 开发 Code Kitchen 的主要背景。
Code Kitchen 已于不久前在 GitHub 开源。我们认为,这套方案可能是 目前最廉价的实现多文件、支持私有库的离线 React playground 方案。
如果正在阅读这篇文章的你也有类似需求,欢迎你来使用它,并在 GitHub 上提供你的看法或者反馈使用上遇到的问题。未来,我们会考虑给它增加如下功能:
增加类似于 React Live 的模块化支持,让用户自己组合相关功能,定制 Playground
目前 Code Kitchen 与 React 框架绑定。我们会持续探索如 Vue/Angular 等其他框架结合的可能性。
体积优化。由于 Code Kitchen 核心依赖于 esbuild-wasm,本身体积较大(经过压缩后依然有 2.5M),与 React Live 这样的方案相比不够轻量。
感谢阅读!
肖鹏
FreeWheel 应用平台技术团队高级开发工程师,主要负责前端工程化工作。
引用链接:
[1] https://github.com/freewheel/code-kitchen:
[2] 新的 React 文档: https://beta.reactjs.org/
[3] Sandpack: https://codesandbox.io/post/sandpack-announcement
[4] 定制 bundler 服务器导入私有包:
https://github.com/codesandbox/sandpack/discussions/58
[5] Semi Design: https://semi.design/en-US/
[6] React Live: https://github.com/FormidableLabs/react-live
[7] Fluent UI React: https://developer.microsoft.com/en-us/fluentui#/controls/web
[8] esbuild playground: https://esbuild.egoist.sh/
[9] esbuild 的 WASM 版本: https://esbuild.github.io/getting-started
[10] Webpack style-loader: https://webpack.js.org/loaders/style-loader
[11] Stylis: https://stylis.js.org/
[12] esbuild 目前还没有支持 CSS Module: https://github.com/evanw/esbuild/issues/20
[13] GitHub 开源: https://github.com/freewheel/code-kitchen
具有私有存储库的 Elastic Beanstalk 多容器 Docker CannotPullContainerError
【中文标题】具有私有存储库的 Elastic Beanstalk 多容器 Docker CannotPullContainerError【英文标题】:Elastic Beanstalk Multicontainer Docker with private repository CannotPullContainerError 【发布时间】:2015-11-03 02:01:28 【问题描述】:之前我使用的是单个 docker 容器弹性 beanstalk 环境。它能够使用我存储在 S3 上的登录凭据从私有 docker hub 存储库下载容器。 但是,我创建了一个新的多容器 docker 环境,从那时起我总是收到错误:
change="TaskArn:arn:aws:ecs:eu-west-1:188125317072:task/dbf02781-8140-422a-9b81-93d83441747d
ContainerName:aws-first-test Status:4
Reason:CannotPullContainerError:
Error: image test/awstest:latest not found ExitCode:<nil> PortBindings:[] SentStatus:NONE"
(我使用的容器与以前完全相同)
容器确实存在,并且环境与登录凭据位于同一位置(爱尔兰)
我的 Dockerrun.aws.json:
"AWSEBDockerrunVersion": 2,
"authentication":
"Bucket": "docker-ireland",
"Key": ".dockercfg"
,
"containerDefinitions": [
"name": "aws-first-test",
"image": "test/awstest",
"memory": 250
,
"name": "aws-second-test",
"image": "test/awstest",
"memory": 250
]
【问题讨论】:
您带有凭据的 json 有任何空格字符吗? 他们有。它们是由 docker 自动创建的。我刚刚删除了所有制表符、空格和换行符。但是,我得到了相同的结果。 【参考方案1】:Dockerrun.aws.json
区分大小写,在 2.0 版中,键 authentication
、bucket
和 key
已更改为小写。
此答案来自亚马逊 AWS 论坛:https://forums.aws.amazon.com/message.jspa?messageID=667098
【讨论】:
【参考方案2】:在我的情况下,这个错误是因为我的 S3 配置文件中有以下内容:
"server" :
"auth" : "*****",
"email" : "*****"
不是开玩笑,我有关键字“服务器”而不是注册表 url 服务(https://index.docker.io/v1/ 用于 docker)。
我一定是从一些博客或文档 idk 中复制的。感觉已经倾倒了。
【讨论】:
以上是关于Code Kitchen:一个支持多文件与私有库的离线React Playground方案的主要内容,如果未能解决你的问题,请参考以下文章