升级Webpack 5与Shakapacker 7后jQuery未初始化问题排查
import $ from 'jquery';
window.jQuery = $;
window.$ = $;
import 'jquery-ui-dist/jquery-ui';
...
## app/views/layouts/application.html.erb ```erb ... <%= stylesheet_pack_tag 'application', :media => "all", :data => {:turbo => {:track => 'reload'}} %> <%= javascript_pack_tag 'application', :data => {:turbo => {:track => 'reload'}, :defer => false} %> ...
Webpack配置未合并自定义规则:当前
webpack.config.js仅调用generateWebpackConfig(),未传入customConfig,导致custom.js中的expose-loader规则完全未生效。修改为:const { generateWebpackConfig } = require('shakapacker') const customConfig = require('./custom') module.exports = generateWebpackConfig(customConfig)Expose Loader在Webpack 5中的语法变更:Webpack 5对expose-loader的配置格式要求更严格,原写法可能无法正确暴露全局变量。更新
custom.js中的loader规则:{ test: require.resolve('jquery'), loader: 'expose-loader', options: { exposes: [ { globalName: '$', moduleLocalName: 'default' }, { globalName: 'jQuery', moduleLocalName: 'default' } ] } }或改用Webpack 5推荐的
exports-loader替代expose-loader。SplitChunks拆分导致jQuery延迟加载:
custom.js中开启了splitChunks: { chunks: 'all' },可能将jQuery拆分为独立chunk,若页面内联脚本在该chunk加载前执行,就会报错。可调整配置将jQuery强制打包进主chunk:optimization: { splitChunks: { chunks: 'all', cacheGroups: { jquery: { test: /[\\/]node_modules[\\/]jquery[\\/]/, name: 'jquery', chunks: 'all', enforce: true } } } }或临时关闭splitChunks验证是否为此问题。
Turbo加载机制影响全局变量:Turbo的页面重载可能导致全局变量丢失,若页面内有依赖jQuery的内联脚本,需确保其在
javascript_pack_tag之后执行,或在turbo:load事件中重新初始化jQuery相关逻辑:document.addEventListener('turbo:load', function() { // 重新挂载jQuery插件或执行相关逻辑 });ES模块默认导出的赋值问题:部分情况下,ES模块的默认导出需通过
.default获取,修改application.js中的赋值语句:import * as jQuery from 'jquery'; window.$ = jQuery.default; window.jQuery = jQuery.default;冗余别名与路径错误:
custom.js中jquery: 'jquery'别名冗余,typeahead: 'core-typeahead'应改为typeahead: 'corejs-typeahead'(与package.json中的依赖名一致),虽不直接影响jQuery,但需修正避免其他潜在问题。
内容的提问来源于stack exchange,提问作者s0rin

