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

Rails7+shakapacker应用中Vue3未加载无控制台报错问题

Rails 7 + shakapacker 集成Vue组件无渲染无报错问题

问题背景

基于Rails 7与shakapacker新建Shopify应用项目,需要在.slim模板文件中使用Vue组件,但Vue未在应用中成功加载,全程无任何报错抛出。

现有配置

  • Vue loader配置:config/webpack/rules/vue.js
const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  resolve: {
    extensions: [
      '.vue'
    ]
  }
}
  • webpack主配置:config/webpack/webpack.config.js
const { webpackConfig, merge } = require('shakapacker')
const vueConfig = require('./rules/vue')

module.exports = merge(vueConfig, webpackConfig)
  • 入口pack文件:app/javascript/packs/application.js
import HelloWorld from '../components/HelloWorld'

import { createApp } from 'vue'
const app = createApp({
  el: '#app'
})

app.component('helloworld', HelloWorld)

document.addEventListener('DOMContentLoaded', () => {
  app
})
  • 示例组件:app/javascript/components/HelloWorld.vue
<template>
  <h1>Hello world</h1>
</template>

<script>
export default {
  name: 'HelloWorld'
}
</script>
  • 布局文件:app/views/layouts/embedded_app.slim
doctype html
html[lang="en"]
  head
    meta[charset="utf-8"]
    - application_name = ShopifyApp.configuration.application_name
    title
      = application_name
    = stylesheet_link_tag "application", "data-turbo-track": "reload"
    = javascript_pack_tag 'application', 'data-turbolinks-track': 'reload'
    = csrf_meta_tags

  body
    #app
      .wrapper
        main[role="main"]
          = yield

    = content_tag(:div, nil, id: 'shopify-app-init', data: { api_key: ShopifyApp.configuration.api_key,
        shop_origin: @shop_origin || (@current_shopify_session.shop if @current_shopify_session),
        host: @host,
        debug: Rails.env.development? })
  • 首页视图:app/views/home/index.slim,尝试渲染HelloWorld组件
helloworld

现象描述

配置完成后页面无内容展示,控制台无报错。曾在Vue实例的created钩子中添加console.log('ok')测试日志,修改后控制台仍无输出,已确认DOMContentLoaded事件可正常触发,无法判断Vue应用是否完成渲染。所有配置对照shakapacker文档编写,不确定是否存在配置错误。应用通过Ngrok隧道在Shopify测试店铺中渲染,已排除该因素影响。

根因与修复

1. Vue 3初始化逻辑错误(核心问题)

Vue 3的createApp不再支持Vue 2的el配置项,必须显式调用mount()方法完成应用挂载。现有代码在DOMContentLoaded回调中仅引用了app变量,没有执行挂载操作,Vue应用根本未启动,自然不会产生日志或渲染内容。
修复后的入口文件:

// app/javascript/packs/application.js
import HelloWorld from '../components/HelloWorld'
import { createApp } from 'vue'

document.addEventListener('DOMContentLoaded', () => {
  const app = createApp({})
  app.component('helloworld', HelloWorld)
  // 显式挂载到DOM节点
  app.mount('#app')
})

2. webpack resolve配置覆盖默认规则

现有vue规则中的resolve.extensions仅配置了.vue,会覆盖shakapacker默认的扩展名解析逻辑,导致.js等格式文件无法被正常识别。修改config/webpack/rules/vue.js,补充默认扩展名:

const { VueLoaderPlugin } = require('vue-loader')

module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ],
  resolve: {
    extensions: ['.vue', '.js', '.jsx', '.ts', '.tsx', '.json']
  }
}

3. 依赖版本校验

如果修改后仍有问题,检查本地依赖版本:vue需为3.x版本,vue-loader需为16.x及以上版本,版本不匹配会导致编译异常无输出。

验证

修改完成后重启shakapacker开发服务,刷新页面即可看到HelloWorld组件渲染的Hello world文本,自定义调试日志也会正常输出。现有slim模板中helloworld标签位于#app节点内部,符合Vue挂载范围要求,无需调整。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:42:14