使用 create-react-app 和 Typescript 时如何在构建时加载 .md 文件?
How to load an .md file on build when using create-react-app and Typescript?
我正在尝试加载要在构建时加载的降价文件。我已经设置了一个使用 Typescript 并使用 material_ui 博客主题的 create-react-app。
import ReactMarkdown from 'markdown-to-jsx';
import post1 from './blog-post.1.md';
export default function Main(props: MainProps) {
const classes = useStyles();
const { posts, title } = props;
return (
<Grid item xs={12} md={8}>
<Typography variant="h6" gutterBottom>
{title}
</Typography>
<Divider />
{posts.map((post) => (
<Markdown className={classes.markdown} key={post.substring(0, 40)}>
{post}
</Markdown>
))}
</Grid>
);
}
如果将 post 指定为降价,它将正确呈现:const post = '# Sample blog post #### April 1, 2020 by [Olivier](/)'
所以问题是 .md 文件没有加载到变量中。
当npm start
为运行时,html显示:/static/media/blog-post.1.09e7833f.md
为什么会这样,那个数字是多少:文件路径中的 09e7833f?
理想情况下,我希望在构建期间加载该文件,以便它可以更快地在 Netlify 等地方提供。我不想使用 答案建议的异步获取。
我假设我必须创建一个 webpack 加载器?这个问题是 create-react-app 在 node_modules
中有 webpack.config.js
这意味着自定义它会在新构建期间被覆盖。如果我无法配置它,我认为使用 raw-loader 没有帮助。
我也按照建议 import post1 from 'raw-loader!./blog-post.1.md';
尝试过 here 但 Typescript 不知道该怎么做。
任何建议都会有所帮助。
这似乎是之前被问到的问题 (https://github.com/facebook/create-react-app/issues/3025),但不幸的是,现在似乎无法直接将 markdown 作为字符串导入 JavaScript/TypeScript.
当要求 create-react-app
导入一个 md
文件时,它似乎得到一个 URL(带有十六进制字符串)到文件而不是其中包含的原始字符串。解决方法如下:
- 创建一个
.d.ts
文件来告诉 TypeScript 如何解释 md
文件:
declare module '*.md' {
const value: string; // markdown is just a string
export default value;
}
- 按如下方式导入您的
md
文件 (the_text.md
)
import theTextFile from './the_text.md';
fetch
文件内容获取实际markdown(https://github.com/facebook/create-react-app/issues/2961#issuecomment-322916352)
const [postMarkdown, setPostMarkdown] = useState('');
// useEffect with an empty dependency array (`[]`) runs only once
useEffect(() => {
fetch(theTextFile)
.then((response) => response.text())
.then((text) => {
// Logs a string of Markdown content.
// Now you could use e.g. <rexxars/react-markdown> to render it.
// console.log(text);
setPostMarkdown(text);
});
}, []);
- 将 markdown 文本放入 Markdown 标签中,它将被渲染:
<Markdown className={classes.markdown}>
{post}
</Markdown>
请记住,您还可以覆盖用于显示最终内容的 JSX 元素。对于 Material-UI,这可能类似于:
import { Typography } from '@material-ui/core';
import { MarkdownToJSX } from 'markdown-to-jsx';
const Foo = (): JSX.Element => {
const MdOverrideTypography = ({
children,
}: // ...props
React.DetailedHTMLProps<
React.HTMLAttributes<HTMLParagraphElement>,
HTMLParagraphElement
>): JSX.Element => (
<Typography paragraph>
{children}
</Typography>
);
const mdOverrides: MarkdownToJSX.Overrides = {
// "p" paragraph elements are substituted with MUI "Typography"
p: MdOverrideTypography,
};
// ...
return (
<Markdown options={{ overrides: mdOverrides }}>
{post}
</Markdown>
)
}
一个简单的方法似乎是使用 raw.macro 包(我从它的自述文件的开头引用):
Installation
In order to use raw.macro in your own project, you can use one of the
following commands:
# or $ npm install --save-dev raw.macro
Make sure babel-plugin-macros already installed. If you're using
Create React App, it's installed by default.
Usage
raw.macro is similar to Node’s require call:
import raw from "raw.macro";
const markdown = raw("./README.md");
TypeScript 将 markdown
变量视为类型 string
。
一个问题是编辑 markdown 文件不会导致项目重建,以包含更改。相反,您必须触摸(例如 re-save)导入它的源文件。
我正在尝试加载要在构建时加载的降价文件。我已经设置了一个使用 Typescript 并使用 material_ui 博客主题的 create-react-app。
import ReactMarkdown from 'markdown-to-jsx';
import post1 from './blog-post.1.md';
export default function Main(props: MainProps) {
const classes = useStyles();
const { posts, title } = props;
return (
<Grid item xs={12} md={8}>
<Typography variant="h6" gutterBottom>
{title}
</Typography>
<Divider />
{posts.map((post) => (
<Markdown className={classes.markdown} key={post.substring(0, 40)}>
{post}
</Markdown>
))}
</Grid>
);
}
如果将 post 指定为降价,它将正确呈现:const post = '# Sample blog post #### April 1, 2020 by [Olivier](/)'
所以问题是 .md 文件没有加载到变量中。
当npm start
为运行时,html显示:/static/media/blog-post.1.09e7833f.md
为什么会这样,那个数字是多少:文件路径中的 09e7833f?
理想情况下,我希望在构建期间加载该文件,以便它可以更快地在 Netlify 等地方提供。我不想使用
我假设我必须创建一个 webpack 加载器?这个问题是 create-react-app 在 node_modules
中有 webpack.config.js
这意味着自定义它会在新构建期间被覆盖。如果我无法配置它,我认为使用 raw-loader 没有帮助。
我也按照建议 import post1 from 'raw-loader!./blog-post.1.md';
尝试过 here 但 Typescript 不知道该怎么做。
任何建议都会有所帮助。
这似乎是之前被问到的问题 (https://github.com/facebook/create-react-app/issues/3025),但不幸的是,现在似乎无法直接将 markdown 作为字符串导入 JavaScript/TypeScript.
当要求 create-react-app
导入一个 md
文件时,它似乎得到一个 URL(带有十六进制字符串)到文件而不是其中包含的原始字符串。解决方法如下:
- 创建一个
.d.ts
文件来告诉 TypeScript 如何解释md
文件:
declare module '*.md' {
const value: string; // markdown is just a string
export default value;
}
- 按如下方式导入您的
md
文件 (the_text.md
)
import theTextFile from './the_text.md';
fetch
文件内容获取实际markdown(https://github.com/facebook/create-react-app/issues/2961#issuecomment-322916352)
const [postMarkdown, setPostMarkdown] = useState('');
// useEffect with an empty dependency array (`[]`) runs only once
useEffect(() => {
fetch(theTextFile)
.then((response) => response.text())
.then((text) => {
// Logs a string of Markdown content.
// Now you could use e.g. <rexxars/react-markdown> to render it.
// console.log(text);
setPostMarkdown(text);
});
}, []);
- 将 markdown 文本放入 Markdown 标签中,它将被渲染:
<Markdown className={classes.markdown}>
{post}
</Markdown>
请记住,您还可以覆盖用于显示最终内容的 JSX 元素。对于 Material-UI,这可能类似于:
import { Typography } from '@material-ui/core';
import { MarkdownToJSX } from 'markdown-to-jsx';
const Foo = (): JSX.Element => {
const MdOverrideTypography = ({
children,
}: // ...props
React.DetailedHTMLProps<
React.HTMLAttributes<HTMLParagraphElement>,
HTMLParagraphElement
>): JSX.Element => (
<Typography paragraph>
{children}
</Typography>
);
const mdOverrides: MarkdownToJSX.Overrides = {
// "p" paragraph elements are substituted with MUI "Typography"
p: MdOverrideTypography,
};
// ...
return (
<Markdown options={{ overrides: mdOverrides }}>
{post}
</Markdown>
)
}
一个简单的方法似乎是使用 raw.macro 包(我从它的自述文件的开头引用):
Installation
In order to use raw.macro in your own project, you can use one of the following commands:
# or $ npm install --save-dev raw.macro
Make sure babel-plugin-macros already installed. If you're using Create React App, it's installed by default.
Usage
raw.macro is similar to Node’s require call:
import raw from "raw.macro"; const markdown = raw("./README.md");
TypeScript 将 markdown
变量视为类型 string
。
一个问题是编辑 markdown 文件不会导致项目重建,以包含更改。相反,您必须触摸(例如 re-save)导入它的源文件。