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 诞生的故事。

    return <img src="https://i.imgur.com/MK3eW3Am.jpg" />;

    ```

    ```css styles.css
    img
    height: 200px;

    ```

    </Sandpack>

    在上面的例子中,<Sandpack /> 是一个自定义的 Sandpack 组件。

  • 解析嵌入的代码块并将它们作为虚拟文件使用

  • 将解析好的文件传入 Sandpack,以初始化 playground

  • 熟悉 MD 语法的读者可得知,我们可以通过给代码块增加语言缩写(如js, css),让常见的 MD 应用为其激活代码高亮。进一步的,我们还可以在语言后面增加自定义后缀,比如为代码块增加文件名。

    假定所有文件处于一个虚拟的文件目录下,那么文件模块之间可以通过如 import \'./styles.css\'  的方式以相对路径进行访问。同时,假设我们把第一个文件看做虚拟文件的入口,就得到了一个标准的 ESM 模块树。

    用上面的思路,我们就可以在 MD 中为一个代码示例提供多文件支持,让 playground 有类似于 IDE 般的体验。

    的 iframe ,并在这个域名所在的远程服务解析 react 和 react-dom 等外部依赖项。不过,这个服务仅提供可以在 npmjs.org 中找到的公共包。

    对于我们的用法,我们需要为 UI 组件的 playground 导入来自于私有 registry 的 npm 包。Sandpack 给出了一个 定制 bundler 服务器导入私有包 的解决方案,但我们之后意识到我们真正需要的不是导入远程私有包,而是直接在 playground 里使用内部依赖源代码,这样可以降低本地开发时的版本管理难度。

    此外,Sandpack 的打包器和组件预览运行于一个指向到远程服务的 iframe 内执行。如果需要自己定制这个远程服务,就会增加更多的人力成本、消耗额外的计算资源。如果可能的话,我们希望能找到一个纯静态的解决方案。

    在线编辑

  • 支持 CSS Module

  • MDX 有良好的兼容性

  • 纯静态 方案

  • 类型提示 功能的编辑器

  • 执行打包好的文件,最后将 React 组件渲染到预览视图中。

    接下来,我们会简单说明一下 code kitchen 使用 esbuild-wasm 的一些工作细节。

    filename: string;
    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);

    假定你需要 reactmy-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 版中,键 authenticationbucketkey 已更改为小写。

    此答案来自亚马逊 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方案的主要内容,如果未能解决你的问题,请参考以下文章

    本地私有库的实现 pod

    远程私有库的创建 pod

    Maven私有库和本地库的安装与配置 Sonatype Nexus + Maven

    “去获取”私有存储库的正确方法是啥?

    Sonatype Nexus3 搭建私有仓库

    linux学习:持续集成篇--Maven私有库和本地库的安装与配置-03