前言

beta.reactjs.org React 的新的文档已经 完成了 70 % 并且呼吁社区进行翻译工作。

React 新的文档用到了哪些技术?_ide

新的文档采用了全新的架构 ​​next.js​​​ +​​ Tailwind CSS​​ ,改版后的文档界面有种焕然一新的感觉,支持暗黑模式,我们可以在线学习,并且写代码,采用了这种所见即所得的形式,大大降低了学习者的成本,我也被这种形式所深深吸引,那么这种所见即所得的形式是如何实现的呢?

基本介绍

新文档地址在 github.com/reactjs/rea…​ 中的 beta 目录下,外层代码是目前的文档代码,那么我们可以直接 ​​git clone​​ 并且拷贝 beta 目录下的内容

这里面有 ​​yarn.lock​​​ 文件,跟绝大多数 next 项目一样 ​​yarn install​​​ 之后,运行 ​​yarn dev​​ 就可以运行开发环境

React 新的文档用到了哪些技术?_bundle_02

启动速度非常快,仅仅 3.3s, 打开 http://localhost:3000,此时​ ​​next.js​​ 会再次编译,大概 200ms,这种优势得益于 next.js 按需编译的优势,也就是是说当前启动的时候,并不会全站打包,而是当进入某个页面的时候编译当前页面,所以速度相当快。

约定式路由

React 新的文档用到了哪些技术?_ide_03

next 是约定式路由,在 pages 文件夹下的目录默认生成路由,即 '/src/pages/learn/add-react-to-a-website.md' 生成路由 ​​/learn/add-react-to-a-website​​​此时发现里面的文档都是​​.md​​后缀的 Markdown 文件,那么 markdown 也可以写交互功能了吗?

React 新的文档用到了哪些技术?_前端_04

打开 index.md,我们发现里面的代码不仅仅是 markdown 还有 react 组件,那么 ​​<HomepageHero />​​ 这个组件是如何被解析成 react 组件的?

next 支持 Markdown

首先 ​​next.js​​​ 是不支持 ​​Markdown​​​ 的,我们需要让 ​​next.js​​​ 支持 ​​Markdown​​​, 我们打开 ​​next.js​​​ 的配置文件 ​​next.config.js​​,

pageExtensions: ['jsx', 'js', 'ts', 'tsx', 'mdx', 'md'],

先让 next 支持 md、 mdx 格式,接下来我们来看下 webpack 部分的配置

webpack: (config, {dev, isServer, ...options}) => {
if (process.env.ANALYZE) {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
config.plugins.push(
new BundleAnalyzerPlugin({
analyzerMode: 'static',
reportFilename: options.isServer
? '../analyze/server.html'
: './analyze/client.html',
})
);
}

// Add our custom markdown loader in order to support frontmatter
// and layout
config.module.rules.push({
test: /.mdx?$/, // load both .md and .mdx files
use: [
options.defaultLoaders.babel,
{
loader: '@mdx-js/loader',
options: {
remarkPlugins,
},
},
path.join(__dirname, './plugins/md-layout-loader'),
],
});

return

首先是单独安装了 ​​webpack-bundle-analyzer​​​ 这个是打包分析插件,通过 ​​ANALYZE=true next build​​ 就可以生成分析包含哪些模块包的网页

React 新的文档用到了哪些技术?_React.js_05

next.js 的分包也非常完美,每个 js 大小都差不多,并且根据页面按需加载。 下面配置是解析 markdown 的,只要是 md、mdx 都会走 ​​@mdx-js/loader​​​, 就是这个 ​​@mdx-js/loader​​ 让 markdown 支持 jsx 了。

这里面还加了一个自定义 loader

module.exports = async function (src) {
const callback = this.async();
const {content, data} = fm(src);
const pageParentDir = path
.dirname(path.relative('./src/pages', this.resourcePath))
.split(path.sep)
.shift();
const layoutMap = {
blog: 'Post',
learn: 'Learn',
reference: 'API',
};
const layout = layoutMap[pageParentDir] || 'Home';

const code =
`import withLayout from 'components/Layout/Layout${layout}';

export default withLayout(${JSON.stringify(data)})


` + content;

return callback(null, code);
};

通过判断父级目录自动增加 Layout,有了 layout,结构就出来了,所以 webpack 的 loader 就是一个函数,可以直接修改代码。

MDX

MDX 让 markdown 支持 jsx,我们一起来看看如何使用

import React from 'react';
import ReactDom from 'react-dom';
import Post from './post.mdx';
import {Heading, /* … */ Table} from './components/index.js';

const components = {
h1: Heading.H1,
// …
table: Table,
};

ReactDom.render(
<Post components={components},
document.querySelector('#root')
);

在 components 传入自定义组件,在 markdown 中就可以使用了。 也可以改成嵌套模式:

import React from 'react';
import ReactDom from 'react-dom';
import Post from './post.mdx';
import {Heading, /* … */ Table} from './components/index.js';
import {MDXProvider} from '@mdx-js/react';

const components = {
h1: Heading.H1,
// …
table: Table,
};

ReactDom.render(
<MDXProvider components={components}>
<Post
</MDXProvider>,
document.querySelector('#root')
);

在线沙箱

文档中还有一种写法, 可以直接再网页中渲染一个 codesandbox.io/

并且文件可以引用文件,这就比较你牛了

React 新的文档用到了哪些技术?_前端_06

React 新的文档用到了哪些技术?_analyzer_07

我们发现 Sandpack 里面使用了 "@codesandbox/sandpack-react" 这个包,打开 sandpack.codesandbox.io/ 官网,非常酷炫的效果映入眼帘

简单几个配置就可以渲染出在线代码编辑器

<Sandpack
customSetup={{
dependencies: {
"react-markdown": "latest"
},
files: {
"/App.js": `import ReactMarkdown from 'react-markdown'

export default function App() {
return (
<ReactMarkdown>
# Hello, *world*!
</ReactMarkdown>
)
}`

React 新的文档用到了哪些技术?_前端_08

小结

1、React 新文档的架构我很喜欢,代码和目录也非常清晰,非常适合阅读

2、我们一些组件库文档是否可以往next架构迁移?

希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。