前言
在之前,已经有在react框架中加载makdown文件的经验,本想着这是件简单的事情,没想到给create-react-app脚手架创建的开发框架中融合此能力遇到了问题:[object Module]。最终通过各种测试,找到了解决方案,现将其记录下来,供大家遇到此类问题可以快速解决。
解决方案
框架介绍
- 框架使用create-react-app创建,创建请参考我的博文《create-react-app4.x搭建react开发框架(React17+antd4.x+typescript4.x)》
- 框架没有通过npm run eject解开项目脚手架相关配置及依赖
解决步骤
- 安装html-loader(必须是1.x以下版本,不然会报错TypeError:this.getOptions is not a function)、markdown-loader
npm install html-loader@1.x markdown-loader --save-dev
- 配置webpack的module参数,按正常流程,是这样,可这不是结果,继续往下看,可参考craco配置文档和markdown-loader配置文档
module.exports = {
webpack: {
configure: {
module: {
rules: [{
test: /\.md$/,
use: [
{
loader: require.resolve("html-loader")
},
{
loader: require.resolve('markdown-loader'),
}]
},]
}
}
}
};
- 编写解析组件
import * as React from "react";
import * as Markdown from './README.md';
export interface TestProps {
}
export interface TestState {
}
export class Test extends React.Component<TestProps, TestState>{
constructor(props: TestProps) {
super(props);
this.state = {
}
}
componentDidMount() {
}
componentWillReceiveProps(nextProps: TestProps) {
if (this.props !== nextProps) {
}
}
render() {
console.log(Markdown);
const html: any = Markdown
return <div style={{ padding: 10 }} dangerouslySetInnerHTML={{ __html: html }}></div>
}
}
- 在react-app-env.d.ts中添加声明文件
declare module "*.md" {
const content: string;
export default content;
}
-
运行看结果
从上面的结果和打印可以看出,loader并没有起到正常作用。看到这种结果很懵逼,于是再去之前的项目打印同样的内容,发现结果如下,这才是正常的加载方式!
-
刨根问底
鉴于这种情况,必须得一探究竟。于是重新搭建了个新的框架,并执行npm run eject看其配置到底做了什么?打开webpack.config.js一看,才知道问题出在什么地方了!请仔细看下面,意思是除了js、mjs、jsx、ts、tsx、html、json几种类型的文件,都用file-loader加载,在这里需要排除.md。
脚手架改成这样,便可正常显示markdown文件了
[{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/,/\.md$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},{
test: /\.md$/,
use: [
{
loader: "html-loader",
},
{
loader: 'markdown-loader',
}]
},]
- 解决问题
没有eject的项目怎么办了?我不想改它的file-loader加载类型的配置,那么我们可不可以将这个markdown-loader放在file-loader配置之前?试了一下,果真可以!!!
修改craco.config.js代码如下,便可正常加载markdown文件了。
module.exports = {
webpack: {
configure: (config) => {
const markdown = {
test: /\.md$/,
use: [
{
loader: require.resolve("html-loader")
},
{
loader: require.resolve('markdown-loader'),
}]
}
config.module.rules[1].oneOf.unshift(markdown)
return config
}
}
};
总结
凡遇到file-loader不能加载的格式文件的加载都可用这种方式解决。