简体   繁体   English

使用 craco 和 yaml-loader 在 React 中导入一个 YAML 文件

[英]Import a YAML file in React with craco and yaml-loader

I am having a quite difficult time trying to import a YAML file as a JS object in my React code.我很难尝试在我的 React 代码中将 YAML 文件导入为 JS object

I made this simple and reproductible CodeSandbox example built with create-react-app to show my problem.我制作了这个使用create-react-app构建的简单且可重现的 CodeSandbox 示例来展示我的问题。

All I am doing is:我所做的只是:

  • configuring Webpack in a craco.config.js file (as recommended in the craco docs ),craco.config.js文件中配置 Webpack(如craco文档中所推荐),
  • adding some Webpack configuration code for the YAML loader (as recommended in the yaml-loader docs ).为 YAML 加载程序添加一些 Webpack 配置代码(如yaml-loader文档中所推荐)。
  • importing the YAML file in the index.js file so I can use it as a JS object.index.js文件中导入 YAML 文件,这样我就可以将它用作 JS object。
// craco.config.js

module.exports = {
  webpack: {
    configure: {
      module: {
        rules: [
          {
            test: /\.yaml$/,
            use: "yaml-loader"
          }
        ],
      },
    },
  },
};
// index.js
...
import testYamlFile from "./testYamlFile.yaml"

ReactDOM.render(
  <>
    <p>Parsed test YAML file object: {testYamlFile}</p>
    <p>Type of parsed object: {typeof testYamlFile}</p>
  </>,
  document.getElementById("root")
);

// Output in CodeSandbox browser:

Parsed test YAML file object: data:application/octet-stream;base64,aGVsbG9Xb3JsZEZvck1vZGVsOiBIZWxsbywgZGVhciBtb2RlbCAhCg==
Type of parsed object: string

In the CodeSandbow example, I am getting a base64 string, so you would tell me that I simply need to decode it and get the content.在 CodeSandbow 示例中,我得到一个 base64 字符串,所以您会告诉我,我只需要解码它并获取内容。 But there are two things:但是有两件事:

  • first, this is not what is intended: I should get a JS object according to the yaml-loader docs首先,这不是预期的:根据 yaml-loader 文档,我应该得到一个 JS object
  • and second, what I get on my PC -- and I can only reproduce it on my machine, despite my best efforts to reproduce the exact same project in CodeSandox -- is even weirder.其次,我在我的 PC 上得到的东西——我只能在我的机器上复制它,尽管我尽了最大努力在 CodeSandox 中复制完全相同的项目——甚至更奇怪。 Actually, I only get the bundled file path, and that's all:实际上,我只得到了捆绑的文件路径,仅此而已:

它在我的机器上做了什么

// Output in my own local browser:

Parsed test YAML file object: /static/media/testYamlFile.5a3cab37.yaml
Type of parsed object: string

I suppose that because Webpack added its unique ID to the file name, it is recognizing and bundling the yaml file.我想因为 Webpack 将其唯一 ID 添加到文件名中,所以它识别并捆绑了 yaml 文件。 But I don't understand why I can't access its content in my code.但是我不明白为什么我不能在我的代码中访问它的内容。

Also tried with js-yaml-loader instead of yaml-loader : same issue.还尝试使用js-yaml-loader而不是yaml-loader :同样的问题。 What am I doing wrong?我究竟做错了什么? Thanks for your help.谢谢你的帮助。

Same problem here.同样的问题在这里。 I originally thought it was the craco version issue (As I add the package via yarn add craco instead of yarn add -D @craco/craco ) but no, same result.我最初认为这是 craco 版本问题(当我通过yarn add craco而不是yarn add -D @craco/craco )但不是,结果相同。 It took me days to find a solution for this, tried different configurations in craco.config.js, but still no luck.我花了几天时间才找到解决方案,在 craco.config.js 中尝试了不同的配置,但仍然没有成功。 I eventually use workarounds for this until the root cause found.我最终为此使用了解决方法,直到找到根本原因。

  1. Use fetch method, retrieve the yaml files as static content via http requests使用fetch方法,通过http请求获取yaml文件为static内容
  2. Use "i18next-http-backend" if the yaml is for react-i18next如果 yaml 用于 react-i18next,则使用“i18next-http-backend”

Update, I finally made it work by doing some magic in craco.config.js .更新,我终于通过在craco.config.js中做了一些魔术让它工作了。 The craco helpers did not help much, my goal is to make the assets loader (without loader name, you have to use your own matcher to find the loader) ignore the yaml extensions, then add new rule to resolve the yaml content. craco 帮手没有太大帮助,我的目标是让资产加载器(没有加载器名称,你必须使用自己的匹配器来查找加载器)忽略 yaml 扩展,然后添加新规则来解析 yaml 内容。 Final code is like below:最终代码如下:

module.exports = {
    
plugins: [
    {
        plugin: {
            overrideWebpackConfig: ({ context, webpackConfig }) => {
                console.log(webpackConfig.module.rules.find(rule => rule.hasOwnProperty('oneOf')));
                const { isFound, match: fileLoaderMatch } = getLoader(
                    webpackConfig,
                    rule => rule.type === 'asset/resource'
                );

                if (!isFound) {
                    throw {
                        message: `Can't find file-loader in the ${context.env} webpack config!`
                    };
                }

                fileLoaderMatch.loader.exclude.push(/\.ya?ml$/);

                const yamlLoader = {
                    use: 'yaml-loader',
                    test: /\.(ya?ml)$/,
                };
                webpackConfig.module.rules.push(yamlLoader);
                return webpackConfig;
            },
        }
    },
],
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM