【问题标题】:is there a way to build a react app in a single html file?有没有办法在单个 html 文件中构建反应应用程序?
【发布时间】:2022-05-07 18:39:45
【问题描述】:

我想构建一个 react 应用程序,并将静态 css 和 js 文件有效地嵌入到我调用 yarn build 时生成的 index.html 中。

我显然可以破解输出并将<script src"...<link href="/static/css/... 标记替换为内联版本,但希望有一个更优雅的解决方案。

【问题讨论】:

  • 为什么要一个 html 文件?

标签: reactjs


【解决方案1】:

我让它工作了。供将来参考(使用 react 16.7.0 & yarn 1.10.1)...

创建一个反应应用:

npx create-react-app my-app
cd my-app
yarn build

一切都好吗?很酷,运行 eject 以便您可以访问 webpack 配置:

yarn eject
rm -rf build node_modules
yarn install
yarn build

添加这个项目并更新 webpack:

yarn add html-webpack-plugin@4.0.0-beta.4
yarn add html-webpack-inline-source-plugin@1.0.0-beta.2

编辑config/webpack.config.js:

const HtmlWebpackPlugin = require('html-webpack-plugin');
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin'); <--- add this
...
plugins: [
  new HtmlWebpackPlugin(
    Object.assign(
      ...
      isEnvProduction
        ? {
            inlineSource: '.(js|css)$', <-- add this
            minify: {
              ...
  ),
  ...
  isEnvProduction &&
    shouldInlineRuntimeChunk &&
    new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin), <--- add this
    new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime~.+[.]js/]),
    ...

运行 rm -rf build &amp;&amp; yarn build &amp;&amp; serve -s build - 您加载的 index.html 现在应该包含所有内联的 js 和 css 内容。请注意,静态文件仍然在构建目录中创建,但页面不使用它们。

【讨论】:

    【解决方案2】:

    为此目的创建了一个 Webpack 插件:

    https://www.npmjs.com/package/html-webpack-inline-source-plugin

    正如 README 所指定的,这必须与 html-webpack-plugin 一起使用,并且您必须指定传入的 inlineSource

    plugins: [
      new HtmlWebpackPlugin({
            inlineSource: '.(js|css)$' // embed all javascript and css inline
        }),
      new HtmlWebpackInlineSourcePlugin()
    ]
    

    【讨论】:

    • 谢谢,但我无法正常工作。已将 html-webpack-inline-source-plugin 和 html-webpack-plugin 添加到我的 devDependencies,并创建了一个 webpack.config.js 文件(虽然不确定其中需要什么)。但是构建忽略了它。
    • 啊,我假设你已经在使用 webpack。你知道在引擎盖下编译的是什么吗?你在使用 create-react-app 之类的东西吗?
    • 2021 年的更新,我们可以将new HtmlWebpackInlineSourcePlugin() 替换为new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin) 以使其工作。
    【解决方案3】:

    以前的答案不起作用,因为作者不再支持html-webpack-inline-source-plugin,取而代之的是官方插件html-inline-script-webpack-pluginhtml-inline-css-webpack-plugin。以下方法适用于截至 2021 年 10 月的最新 React 17。步骤:

    创建一个 React 应用程序

    create-react-app my-app
    cd my-app
    yarn
    yarn start
    

    确保它正常工作,您对输出感到满意。然后,弹出你的配置(我认为这可以在不弹出配置的情况下完成,但我懒得去查找如何配置 CRA)

    yarn eject
    rm -rf build node_modules
    yarn
    yarn build
    

    然后,添加 Webpack 插件(假设您想要在这里嵌入 CSS 和脚本,如果您只想要另一个,只需删除一个)

    yarn add html-inline-css-webpack-plugin -D
    yarn add html-inline-script-webpack-plugin -D
    

    最后,将这些添加到 Webpack 配置 config/webpack.config.js。首先在文件顶部声明它们:

    const HTMLInlineCSSWebpackPlugin = require('html-inline-css-webpack-plugin').default;
    const HtmlInlineScriptPlugin = require('html-inline-script-webpack-plugin');
    

    然后将它们添加到plugins: [...] 集合中。搜索 new InlineChunkHtmlPlugin 并在之后添加它们:

          isEnvProduction &&
            shouldInlineRuntimeChunk &&
            new HTMLInlineCSSWebpackPlugin(),
          isEnvProduction &&
            shouldInlineRuntimeChunk &&
            new HtmlInlineScriptPlugin(),
    

    注意:包含isEnvProduction / shouldInlineRuntimeChunk 检查很重要!如果您跳过这些,则在运行yarn start 时热刷新将不起作用。您只想在生产模式下嵌入脚本,而不是在开发期间。

    现在,如果您运行yarn build,您会发现所有嵌入在build/index.html 中的CSS 和JS。如果你运行yarn start,它将启动一个热重载的开发环境,你可以在其中进行开发。

    【讨论】:

    • 执行这些步骤后,它看起来已将所有内容正确内联到我的 index.html 文件中,但是,构建目录中的发布 index.html 文件现在无法正确加载,只显示空白屏幕。知道这里可能是什么问题吗?我是这个世界的新手。
    • 您可能必须将其添加到您的 webpack.config.js 中的 HtmlWebpackPlugin 配置中。查找inject 属性并将其值更改为body。这可确保在您的 HTML 加载完成后加载您的 JavaScript。您可能遇到的问题是您的脚本在 HTML 准备好之前就已加载。
    • 感谢@StanleyThijssen,我无法将inject 属性的值更改为body(在我的项目中它看起来像一个布尔值),但你的推理很到位- 将我的内联脚本移动到 HTML &lt;body&gt; 的最后一行后,它按预期加载。大赞!
    【解决方案4】:

    我无法使用所有提供的答案。但是,我想通过提供一些我找到的与此问题相对应的链接来帮助任何试图找到解决方案的人:

    https://github.com/facebook/create-react-app/issues/3365#issuecomment-376546407

    Generate single physical javascript file using create-react-app

    Inline CSS with Webpack, without HtmlWebpackInlineSourcePlugin?

    https://pangyiwei.medium.com/building-a-react-app-as-a-single-html-file-with-create-react-app-no-eject-283a141e7635

    https://www.labnol.org/code/bundle-react-app-single-file-200514

    对于我非常简单的用例缩小等并不那么重要,所以我将只使用react website 示例的修改版本(示例下载here)。

    <!DOCTYPE html>
    <html>
    
    <head>
      <meta charset="UTF-8" />
      <title>Add React in One Minute</title>
    </head>
    
    <body>
    
      <h2>Add React in One Minute</h2>
      <p>This page demonstrates using React with no build tooling.</p>
      <p>React is loaded as a script tag.</p>
    
      <!-- We will put our React component inside this div. -->
      <div id="root"></div>
    
      <!-- Load React. -->
      <!-- Note: when deploying, replace "development.js" with "production.min.js". -->
      <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
      <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
      <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    
      <script type="text/babel">
        'use strict';
        class LikeButton extends React.Component {
          constructor(props) {
            super(props);
            this.state = { liked: false };
          }
    
          render() {
            if (this.state.liked) {
              return 'You liked this.';
            }
    
            return <button onClick={() => this.setState({ liked: true })} > Like </button >;
          }
        }
        const root = ReactDOM.createRoot(document.getElementById('root'));
    
        root.render(<LikeButton />)
      </script>
    </body>
    
    </html>
    

    希望对你有帮助

    【讨论】:

      猜你喜欢
      • 2019-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-23
      • 2022-01-20
      • 1970-01-01
      相关资源
      最近更新 更多