You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SolidJS SSR 水化脚本编译错误排查求助

关于SolidJS同构开发水化失败的问题排查与解决

我正在尝试SolidJS的同构开发方案,严格遵循官方文档操作。页面视觉渲染正常,但水化成功本该出现的浏览器日志未出现,反而报错。

相关代码

服务器代码

app.get('/', (req, res) => {
    return res.send(getBasicHTMLSkeleton())
})

getBasicHTMLSkeleton函数

import {renderToString, generateHydrationScript, Dynamic} from "solid-js/web";
import HelloWorld from "../../hybrid/components/HelloWorld";

export const getBasicHTMLSkeleton = () =>  {
    const hello = renderToString(() => <HelloWorld />)
    return `
  <html lang="en">
    <head>
      <title>🔥 Solid SSR 🔥</title>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0" />
      <link rel="stylesheet" href="/_index.min.css" />
      <script src="hydrate.js" />
      ${generateHydrationScript()}
    </head>
    <body>${hello}</body>
  </html>
`;
}

HelloWorld组件

import {createEffect} from "solid-js";

const HelloWorld = () => {
    createEffect(() => {
        console.log('lel!')
    })

    return <div>
        <h1>Hello</h1>
    </div>
}

export default HelloWorld

客户端hydrate.js脚本

import {hydrate} from "solid-js/web";
import HelloWorld from "../hybrid/components/HelloWorld";

hydrate(() => <HelloWorld/>, document)

浏览器控制台报错

Uncaught TypeError: (0 , solid_js_web__WEBPACK_IMPORTED_MODULE_0__.template) is not a function
    at ./src/hybrid/components/HelloWorld.tsx (hydrate.js:25:83)
    at __webpack_require__ (bootstrap:19:1)
    at publicPath:1:1
    at hydrate.js:3421:3
    at hydrate.js:3423:12

Webpack客户端编译配置

const tsAndTsxRuleClient = {
    test: /\.(ts|tsx)$/i,
    exclude: ['/node_modules/'],
    use: [
        {
            loader: 'babel-loader',
            options: {
                presets: [["solid", {"generate": "dom", "hydratable": true}]],
            },
        },
        {
            loader: 'ts-loader',
        },
    ]
}


const configClient = {
    ...configServer,
    entry: './src/client/hydrate.tsx',
    module: {
        rules: [tsAndTsxRuleClient]
    },
    output: {
        filename: 'hydrate.js',
        path: path.resolve(__dirname, 'dist-client')
    }
}

打包后hydrate.js相关代码

(() => {
  console.log('HYDRATING?');
  (0,solid_js_web__WEBPACK_IMPORTED_MODULE_1__.hydrate)(() => (0,solid_js_web__WEBPACK_IMPORTED_MODULE_2__.createComponent)(_hybrid_components_HelloWorld__WEBPACK_IMPORTED_MODULE_0__["default"], {}), document); // this code breaks everything
})();

我尝试过调整Webpack配置(如将generate设为ssr)、检查语法、更换水化目标节点,但问题依旧。请问我遗漏了什么?


问题原因及解决方案

这个错误核心是客户端与服务端的组件编译格式不兼容,或Webpack配置存在加载顺序、预设冲突。以下是针对性修复方案:

1. 调整Babel与ts-loader的执行顺序

当前规则先执行babel-loader再执行ts-loader,会导致SolidJS的Babel预设无法正确处理TypeScript代码。需将ts-loader前置,先转译TS为JS,再让Babel处理SolidJS编译逻辑:

const tsAndTsxRuleClient = {
    test: /\.(ts|tsx)$/i,
    exclude: ['/node_modules/'],
    use: [
        {
            loader: 'ts-loader',
            options: {
                transpileOnly: true, // 仅做类型检查,转译交给Babel
                compilerOptions: {
                    jsx: 'preserve' // 保留JSX让Babel处理
                }
            },
        },
        {
            loader: 'babel-loader',
            options: {
                presets: [["solid", {"generate": "dom", "hydratable": true}]],
            },
        },
    ]
}

2. 确保服务端与客户端编译目标一致

  • 服务端编译时,SolidJS预设的generate需设为ssr;客户端保持generate: "dom"且hydratable: true,避免组件被编译为两种不兼容格式。
  • 检查configServer中的TS/TSX规则,确认服务端Babel预设为["solid", {"generate": "ssr"}]。

3. 修正HTML脚本加载顺序

generateHydrationScript()会输出SolidJS初始化脚本,必须在你的客户端水化代码之前加载,调整HTML模板中的顺序:

${generateHydrationScript()}
<script src="hydrate.js"></script>

4. 验证TS配置与Webpack解析

  • 确保tsconfig.json中的jsx设为preserve,让Babel负责JSX编译,避免与ts-loader冲突。
  • 在Webpack客户端配置中添加解析规则,确保正确识别SolidJS模块:
resolve: {
    extensions: ['.ts', '.tsx', '.js', '.jsx'],
    alias: {
        'solid-js/web': require.resolve('solid-js/web'),
        'solid-js': require.resolve('solid-js')
    }
}

内容的提问来源于stack exchange,提问作者Thomas Opdebeeck

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:03:22