前言
https://beta.reactjs.org React 的新的文档已经 完成了 70 % 并且呼吁社区进行翻译工作。
新的文档采用了全新的架构 next.js
Tailwind CSS
,改版后的文档界面有种焕然一新的感觉,支持暗黑模式,我们可以在线学习,并且写代码,采用了这种所见即所得的形式,大大降低了学习者的成本,我也被这种形式所深深吸引,那么这种所见即所得的形式是如何实现的呢?
基本介绍
新文档地址在 https://github.com/reactjs/reactjs.org/ 中的 beta 目录下,外层代码是目前的文档代码,那么我们可以直接 git clone
并且拷贝 beta 目录下的内容
这里面有 yarn.lock
文件,跟绝大多数 next 项目一样 yarn install
之后,运行 yarn dev
就可以运行开发环境
启动速度非常快,仅仅 3.3s, 打开 http://localhost:3000,此时 next.js
会再次编译,大概 200ms,这种优势得益于 next.js 按需编译的优势,也就是是说当前启动的时候,并不会全站打包,而是当进入某个页面的时候编译当前页面,所以速度相当快。
约定式路由
next 是约定式路由,在 pages 文件夹下的目录默认生成路由,即 '/src/pages/learn/add-react-to-a-website.md' 生成路由 /learn/add-react-to-a-website
此时发现里面的文档都是.md
后缀的 Markdown 文件,那么 markdown 也可以写交互功能了吗?
打开 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 部分的配置
代码语言:javascript复制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 config;
},
首先是单独安装了 webpack-bundle-analyzer
这个是打包分析插件,通过 ANALYZE=true next build
就可以生成分析包含哪些模块包的网页
next.js 的分包也非常完美,每个 js 大小都差不多,并且根据页面按需加载。 下面配置是解析 markdown 的,只要是 md、mdx 都会走 @mdx-js/loader
, 就是这个 @mdx-js/loader
让 markdown 支持 jsx 了。
这里面还加了一个自定义 loader
代码语言:javascript复制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,我们一起来看看如何使用
代码语言:javascript复制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 中就可以使用了。 也可以改成嵌套模式:
代码语言:javascript复制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')
);
在线沙箱
文档中还有一种写法, 可以直接再网页中渲染一个 https://codesandbox.io/
并且文件可以引用文件,这就比较你牛了
我们发现 Sandpack 里面使用了 "@codesandbox/sandpack-react" 这个包, 打开 https://sandpack.codesandbox.io/ 官网,非常酷炫的效果映入眼帘
简单几个配置就可以渲染出在线代码编辑器
代码语言:javascript复制<Sandpack
customSetup={{
dependencies: {
"react-markdown": "latest"
},
files: {
"/App.js": `import ReactMarkdown from 'react-markdown'
export default function App() {
return (
<ReactMarkdown>
# Hello, *world*!
</ReactMarkdown>
)
}`
}
}}
/>;
小结
1、React 新文档的架构我很喜欢,代码和目录也非常清晰,非常适合阅读
2、我们一些组件库文档是否可以往next架构迁移?
希望这篇文章对大家有所帮助,也可以参考我往期的文章或者在评论区交流你的想法和心得,欢迎一起探索前端。