ReactJS 在构建时将文本文件内容复制到组件中

ReactJS copy text file content into component on build

我正在使用 ReactJS 编写“服务条款”页面,我的想法是在构建时将文件 tos-text.txt 的内容复制到组件中,以避免在页面打开。 我尝试如下,但效果不佳:

<h2>Terms of Service</h2>

<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas in scelerisque odio, sed
    consequat ante. Donec lectus tortor, ullamcorper quis risus nec, cursus hendrerit libero. In hac
    habitasse platea dictumst. Quisque et posuere urna. Suspendisse convallis faucibus nulla, non
    egestas libero aliquet non. Donec tincidunt purus sed sem suscipit feugiat. Pellentesque rutrum
    blandit gravida. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per
    inceptos himenaeos. Pellentesque erat urna, lobortis sed turpis a, aliquet aliquet lorem. Class
    aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla quis
    nibh et mi ullamcorper mattis eu eget lectus.
</p>
import { Container } from 'react-bootstrap'

// Page content
import TosText from 'config/tos-text.txt'

// --- Terms of Service ---
const Tos = () => {
    return (
        <Container className="flex-grow-1 tos">
            <div dangerouslySetInnerHTML={{ __html: TosText }} />
        </Container>
    )
}

export default Tos

目前页面只显示link到生成的txt文件(/static/media/tos-text.dc220bee.txt)。


编辑:
正如@jsejcksn 建议的那样 (source-assets),我尝试安装 react-app-rewired,使用这个 config-overrides.js:

module.exports = function override(config, _env) {
    let rules = config.module.rules[1].oneOf
    rules.splice(rules.length - 1, 0, {
        test: /\.txt/,
        type: 'asset/source',
    })

    return config
}

但是当我尝试启动测试服务器时,它显示:

$ react-app-rewired start
Failed to compile.

Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration.module.rules[1].oneOf[8].type should be one of these:
   "javascript/auto" | "javascript/dynamic" | "javascript/esm" | "json" | "webassembly/experimental"
   -> Module type to use for the module

error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

您可以简单地使用“嵌入”在 React 组件中显示您的静态文件。

使用<embed>:

const Tos = () => {
    return (
        <Container className="flex-grow-1 tos">
            <h2>Terms of Service</h2>
            <embed type="text/html" src={TosText} />
        </Container>
    )
}

请注意,使用这种方法,您不能在导入的文本文件中使用任何标记——它不会呈现为标记,而只是呈现为文本,这就是标题位于 <embed> 之外的原因上面的例子。

这应该呈现如下内容:

如果内容不适合默认 <embed> 框,则内容可以滚动 -- 但您可以使用样式或 widthheight 属性控制其大小。

使用<iframe>:

将您的静态文档移动到应用程序的 public 文件夹,并将扩展名更改为 .html,然后 link 简单地:

const Tos = () => {
    return (
        <Container className="flex-grow-1 tos">
            <iframe title="Terms of Service" src="./tos-text.html" />
        </Container>
    )
}

这应该是这样的:

同样,这只是默认外观,您可以通过样式进行更改。

您也可以使用 <embed> 和第二种方法(public 文件夹中的文件):

<embed type="text/html" src="./tos-text.html" />

你可以在codesandbox上看到一个live example

感谢@jsejcksn 给我的建议,我的意图成功了。
我会为任何需要它的人添加解决方案:

1。安装依赖项

$ yarn add react-app-rewired raw-loader

2。创建配置 ovverride

config-overrides.js:

module.exports = function override(config, _env) {
    let rules = config.module.rules[1].oneOf
    rules.splice(rules.length - 1, 0, {
        test: /\.txt$/i,
        use: 'raw-loader',
    })

    return config
}

3。将txt包含到组件中

// Page text
import PageText from 'content/page.txt'

const Component = () => {
    return (
        <div className="text">
            <div dangerouslySetInnerHTML={{ __html: PageText }} />
        </div>
    )
}

export default Component

(P.S。我敢打赌有一个加载程序可以将文件转换为 ReactComponent,就像 SVG 文件一样,但我没有做更多的事情)