有没有办法在单个 html 文件中构建 React 应用程序?

pom*_*omo 13 reactjs

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

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

pom*_*omo 15

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

创建一个反应应用程序:

npx create-react-app my-app
cd my-app
yarn build
Run Code Online (Sandbox Code Playgroud)

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

yarn eject
rm -rf build node_modules
yarn install
yarn build
Run Code Online (Sandbox Code Playgroud)

添加此项目并更新 webpack:

yarn add html-webpack-plugin@4.0.0-beta.4
yarn add html-webpack-inline-source-plugin@1.0.0-beta.2
Run Code Online (Sandbox Code Playgroud)

编辑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/]),
    ...
Run Code Online (Sandbox Code Playgroud)

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


Jan*_*sky 13

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

创建一个反应应用程序

create-react-app my-app
cd my-app
yarn
yarn start
Run Code Online (Sandbox Code Playgroud)

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

yarn eject
rm -rf build node_modules
yarn
yarn build
Run Code Online (Sandbox Code Playgroud)

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

yarn add html-inline-css-webpack-plugin -D
yarn add html-inline-script-webpack-plugin -D
Run Code Online (Sandbox Code Playgroud)

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

const HTMLInlineCSSWebpackPlugin = require('html-inline-css-webpack-plugin').default;
const HtmlInlineScriptPlugin = require('html-inline-script-webpack-plugin');
Run Code Online (Sandbox Code Playgroud)

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

      isEnvProduction &&
        shouldInlineRuntimeChunk &&
        new HTMLInlineCSSWebpackPlugin(),
      isEnvProduction &&
        shouldInlineRuntimeChunk &&
        new HtmlInlineScriptPlugin(),
Run Code Online (Sandbox Code Playgroud)

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

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

  • 您可能必须将其添加到 webpack.config.js 内的 HtmlWebpackPlugin 配置中。查找“inject”属性并将其值更改为“body”。这可以确保在 HTML 加载完成后加载 JavaScript。您可能遇到的问题是您的脚本在 HTML 准备好之前加载。 (2认同)

Kev*_*err 5

为此目的创建了一个 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()
]
Run Code Online (Sandbox Code Playgroud)


J.K*_*.K. 5

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

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

使用 create-react-app 生成单个物理 javascript 文件

使用 Webpack 内联 CSS,而不使用 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

对于我非常简单的用例,缩小等并不那么重要,所以我将只使用反应网站示例的这个修改版本(示例在此处下载)。

<!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>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助