Rails 6.1存量应用接入Stimulus与Importmaps报错如何解决?
根本原因
- 重复加载
application.js且属性配置错误
你初始的布局文件里先后用<%= javascript_include_tag "application" %>和<%= javascript_importmap_tags %>加载了两次入口脚本:
- 第一次用
javascript_include_tag加载的脚本默认会被浏览器识别为普通JS脚本,不会识别为ES模块,而你的application.js里包含import语句,普通脚本不支持顶层import声明,直接触发第一个语法错误。 - 第二次
javascript_importmap_tags已经内置了加载application入口的逻辑,生成的是带type="module"属性的脚本标签,本身是合法的,但因为前面已经错误加载过一次入口,所以会重复执行逻辑。
裸模块导入没有匹配的上下文
你第一次加载的普通application.js里用到了类似@hotwired/stimulus-importmap-autoloader的裸导入声明,这种声明只有在ES模块上下文、且配置了对应的importmap映射才能被正常解析,普通脚本下浏览器无法识别这种非相对路径的导入,直接触发第二个模块解析错误。脚本加载顺序错误
你初始配置里把javascript_importmap_tags放在了所有JS标签的最后,而es-module-shim和importmap配置必须要在所有ES模块脚本加载之前完成初始化,顺序错误也会导致polyfill失效,旧版Firefox无法正常解析模块。
其他需要注意的配置
- importmap路径匹配:你把JS文件存放在
app/assets/javascripts下而非默认的app/javascript,要在importmap.rb里明确指定入口路径,比如pin "application", to: "application.js",避免默认路径匹配错误。 - manifest.js去重:你当前的manifest.js里同时写了
//= link_directory ../javascripts .js和//= link_tree ../javascripts,两者功能重叠,保留任意一个即可,避免预编译阶段重复处理JS文件。 - Turbo引入方式:不需要单独用
javascript_include_tag加载Turbo,直接在importmap.rb里pin Turbo的路径,再在application.js里导入即可,javascript_importmap_tags会自动处理模块类型属性,不需要手动加module-shim标识。 - 旧浏览器兼容:Firefox 91本身不原生支持importmap,完全依赖
es-module-shimpolyfill,不要修改javascript_importmap_tags生成的shim脚本的async属性,也不要在shim加载之前引入任何ES模块脚本。 - Sprockets版本要求:你用Asset Pipeline处理ES模块代码,需要确保
sprocketsgem版本 >= 4.0,低版本sprockets不支持ES模块语法的预编译处理。
内容的提问来源于stack exchange,提问作者map7
相关产品推荐
相关产品推荐

