Rails 6出现Uncaught TypeError: $(...).sortable is not a function错误如何解决
报错原因排查
- jQuery未正确挂载到全局作用域:Rails 6默认使用Webpacker管理前端依赖,不会默认将
$、jQuery对象暴露到window全局作用域,而jquery-ui的组件依赖全局jQuery对象完成方法注册,因此会出现方法找不到的报错。 - 资源引入顺序错误:jquery-ui的相关组件必须在jQuery引入完成后再加载,若引入顺序颠倒,会导致sortable方法无法正常挂载到jQuery原型上。
- jQuery版本冲突:如果项目中同时存在多个版本的jQuery实例(例如Webpacker管理的jQuery和layout中通过script标签引入的CDN版jQuery共存),会导致sortable方法注册到了非当前使用的jQuery实例上。
- Turbolinks重复初始化问题:页面多次触发turbolinks:load事件导致重复初始化,也可能偶发方法调用异常。
解决方案
- 配置Webpacker暴露全局jQuery
打开config/webpack/environment.js文件,添加如下配置:
const { environment } = require('@rails/webpacker') const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery' }) ) module.exports = environment
- 调整
application.js的引入顺序,新增初始化防重复判断
// 优先引入jQuery并绑定到全局 import $ from 'jquery' window.$ = $ window.jQuery = $ // 再引入jquery-ui组件 require("jquery-ui/ui/widget") require("jquery-ui/ui/widgets/sortable") // 最后编写初始化逻辑 $(document).on("turbolinks:load", () => { // 先校验sortable方法存在且未初始化过,避免异常 if ($.fn.sortable && !$("#employeeLevel").hasClass('sortable-initialized')) { $("#employeeLevel").addClass('sortable-initialized').sortable({ handle: '.handle', update: function(e, ui) { Rails.ajax({ url: $(this).data("url"), type: "PATCH", data: $(this).sortable('serialize'), success: function(result){ console.log('my msg'+result); } }); } }); } })
- 清理缓存重新编译
依次执行以下命令,清除旧的编译资源后重启服务:
yarn install rails assets:clobber
执行完成后重启Rails服务和Webpack Dev Server即可。
4. 排查重复jQuery引入
检查项目app/views/layouts/下的布局文件,确认没有通过<script>标签额外引入jQuery CDN资源,保证全局只有Webpacker管理的一个jQuery实例。
内容的提问来源于stack exchange,提问作者Sanju Basnet
相关产品推荐
相关产品推荐

