如果我不需要 SSR,如何编译 JS 文件以在 WordPress 主题中使用 React 组件?

IT技术 javascript reactjs wordpress webpack create-react-app
2022-07-16 00:32:34

我有一个 WordPress 主题,其中一部分我想使用 React 组件(我不需要 SSR)。我过去曾使用过 create-react-app,但现在我有了以下代码:

<div id="react-nav-bar"></div>

<script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script>

<script src="<?php echo get_template_directory_uri() ?>/react-nav-bar/build/static/js/runtime-main.39639aca.js"></script>

它不起作用。请求runtime-main.39639aca.js成功,但它没有加载我的导航栏。

问题是 create-react-app 生成的不仅仅是一个 JS 文件,我只需要一个可以放入主题中的 JS 文件。

我用 webpack 尝试了一些东西但没有成功。我在GitHub上搜索了一些东西,我不知道该尝试哪一个。我尝试了react-embedded,但它给了我一个错误。我也试过这个,但它对我不起作用。

我也不喜欢 ES Lint 警告(我使用 VS Code)。

更新 1

此命令部分执行我想要的操作:

npx babel --watch react-nav-bar/src --out-dir react-nav-bar/dist --presets react-app/prod

这就是我在没有 WebPack 的情况下尝试过的方法,但是 VS Code 中的编辑器虽然编译得很好,但还是充满了红色的波浪线,而且我无法导入 npm module。有没有办法能够导入 npm module?自动补全让我更有效率。

1个回答

我试了一下Rollup,效果很好。

我在 DevTools 控制台中收到了一些警告,但它可以工作!包含自动完成和 npm module。

基于这个要点,我有这些文件:

src/index.tsx

import * as React from "react";
import { render } from 'react-dom';

const App = () => {
  return <button onClick={() => alert('React from WordPress !')}>Cool!!!</button>;
};

window.addEventListener('DOMContentLoaded', () => {
  render(<App />, document.getElementById('react-nav-bar'));
});

包.json

只有两个额外的脚本:

"build": "rollup -c",
"watch": "rollup -cw"

与上面链接的要点相比,不寻常的依赖关系:

"@rollup/plugin-commonjs": "^18.0.0",
"@rollup/plugin-node-resolve": "^11.2.1",
"rollup-plugin-typescript": "^1.0.1",

rollup.config.js

import typescript from 'rollup-plugin-typescript';
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';

export default {
    input: './src/index.tsx',
    output: {
        file: './dist/bundle.js',
    },
    format: 'iife',
    plugins: [ resolve(), typescript(), commonjs() ],
};

tsconfig.json

{
  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "module": "es6",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": "./dist",
    "preserveConstEnums": true,
    "target": "es5",
    "allowSyntheticDefaultImports": true
  },
  "exclude": [
    "node_modules"
  ]
}

为了让 React 使用它,我有特殊的行:"allowSyntheticDefaultImports": true.

../页脚.php

<div id="react-nav-bar"></div>

<script>try { process.env.NODE_ENV } catch(e) { var process = { env: { NODE_ENV: 'production' } }; }</script>
<script src="<?php echo get_template_directory_uri() ?>/react-nav-bar/dist/bundle.js"></script>

这有很大帮助:https ://github.com/hybridsjs/hybrids/issues/27#issuecomment-452346986