V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
simonguo
V2EX  ›  程序员

让 Markdown 中的代码可以实时运行

  •  
  •   simonguo · 2018-08-28 17:18:37 +08:00 · 3570 次点击
    这是一个创建于 2315 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景

    让 Markdown 中的代码可以实时运行,为什么会有这样一个需求?

    在我们前端团队中,技术相关的文档都采用 Markdown 编写, 文档中往往会伴随很多示例代码,我们希望大家在阅读文档的时候,可以运行示例代码,看到效果。

    需求

    • 让 Markdown 中的代码可以运行,并预览效果。
    • 代码可以在线编辑。
    • 不影响整个文档流的布局。
    • 支持 React, 支持代码高亮。
    • 可以配置 babel。

    明确需求以后,写了一个 React 组件来满足这些功能, react-code-view , 首先看一下效果:

    preview

    在线预览: https://simonguo.github.io/react-code-view/

    原理

    • 就通过 markdown-loaderhtml-loader 解析 Markdown 文档。
    • 通过正则表达式取出 code,交给 codemirror
    • codemirror 中的代码通过 babel 编译,再通过 ReactDOM.render 渲染到指定的容器中。

    安装

    npm install react-code-view
    

    配置 webpack

    在 webpack 中需要添加对 markdown-loader 的支持。 需要安装:

    npm install html-loader --save-dev
    npm install markdown-loader --save-dev
    npm install react-markdown-reader --save-dev
    

    webpack.config.js 配置

    >=webpack 2.x +

    
    const markdownRenderer = require('react-markdown-reader').renderer;
    
    {
      test: /\.md$/,
      use: [{
        loader: 'html-loader'
      }, {
        loader: 'markdown-loader',
        options: {
          pedantic: true,
          renderer: markdownRenderer(/**languages:Array<string>**/)
        }
      }]
    }
    

    languages 默认值:["javascript", "bash", "xml", "css", "markdown", "less"];

    Github: https://github.com/simonguo/react-markdown-reader

    添加 Babel

    示例代码中通常是使用到 ES2015+ , React 等,需要对代码实时做编译,所以在 html 中引入 babel :

    <script type="text/javascript" src="//cdn.staticfile.org/babel-standalone/6.24.0/babel.min.js"></script>
    

    示例

    
    import CodeView from 'react-code-view';
    import '~react-code-view/lib/less/index.less';
    
    import { Button } from 'rsuite';
    
    
    <CodeView dependencies={{ Button }} >
      {require('./example.md')}
    </CodeView>
    
    

    源代码都统一写在 markdown 中,参考: example.md

    这里需要注意的是把需要运行的代码一定要放在 <!--start-code--><!--end-code--> 之间。

    谁在用?

    14 条回复    2018-08-29 15:08:03 +08:00
    XiaoXiaoNiWa
        1
    XiaoXiaoNiWa  
       2018-08-28 17:21:20 +08:00 via Android
    这个不错…
    litpen
        2
    litpen  
       2018-08-28 18:04:38 +08:00
    mark
    dlsflh
        3
    dlsflh  
       2018-08-28 18:14:21 +08:00 via Android
    Juypter Notebook 不好吗?
    wph95
        4
    wph95  
       2018-08-28 20:25:59 +08:00   ❤️ 1
    一种可实时修改的 https://github.com/mdx-js/mdx 的感觉
    Doragd
        5
    Doragd  
       2018-08-28 22:18:56 +08:00
    @dlsflh 看到题目,我也直接就想到了 Jupyter
    szetrov
        6
    szetrov  
       2018-08-28 22:56:41 +08:00
    Juypter + 1,可能因为 Juypter 支持的语言少?
    szetrov
        7
    szetrov  
       2018-08-28 22:57:35 +08:00
    @szetrovJuypter-> Jupyter..... mac 输入法直接更正了没反应过来
    strugglexiang
        8
    strugglexiang  
       2018-08-28 23:07:15 +08:00 via Android
    chuhemiao
        9
    chuhemiao  
       2018-08-28 23:45:49 +08:00
    vue 配置用 markdown-loader 解析 md 语法,排版显示有问题(基本纯输出,没有换行和适配),老哥知道是啥问题吗
    metrxqin
        10
    metrxqin  
       2018-08-29 09:07:44 +08:00
    为什么不试试 http://jsfiddle.net 呢?
    metrxqin
        11
    metrxqin  
       2018-08-29 09:09:46 +08:00
    我不确定你们文档怎么组织的,但 Highcharts API 文档示例是这样写的。
    simonguo
        12
    simonguo  
    OP
       2018-08-29 12:39:19 +08:00
    @chuhemiao 排版显示问题是 css 解决的。
    simonguo
        13
    simonguo  
    OP
       2018-08-29 12:43:02 +08:00
    @metrxqin 这样做的目的是维护起来会非常方便,比如这样一个文件: https://github.com/rsuite/rsuite.github.io/blob/master/src/components/button/appearance.md

    如果有人提 PR 的话也很方便。
    maggiefor
        14
    maggiefor  
       2018-08-29 15:08:03 +08:00
    mark
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2525 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 10:36 · PVG 18:36 · LAX 02:36 · JFK 05:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.