首页 > 解决方案 > 使用 Rails 6/Webpack 的 Gmap

问题描述

我正在尝试让我以前与早期版本的 Rails 一起使用的 Google Maps 设置使用 Rails 6 显示。显然 Rails 6 现在使用 webpack 来处理 javascript 资产,我无法让我的应用程序识别 Gmaps 函数用于渲染地图。

一些基础知识:

宝石文件

gem 'geocoder'
gem 'gmaps4rails'
gem 'underscore-rails'
# maybe don't need ^ this underscore gem anymore

我安装了下划线yarn add underscore并添加了当前位于 vendor/javascripts 文件夹下的谷歌地图脚本,该脚本gmaps_google.js已添加到我在 webpacker.yml `app/javascript/packs/application.js 文件中的解析路径中,如下所示:

require("@rails/ujs").start()
require("@rails/activestorage").start()
require("channels")
require("gmaps_google")

import "bootstrap";
import 'underscore'
import "../stylesheets/application";

window.jQuery = $;
window.$ = $;

这是我的实际 show.html.erb 视图和地图的尝试加载

<div style='width: 800px;'>
  <div id="map" style='width: 800px; height: 400px;'></div>
</div>

<script>
  const handler = Gmaps.build('Google');
  handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
    markers = handler.addMarkers([
      {
        "lat": <%= @user.latitude %>,
        "lng": <%= @user.longitude %>,
        "infowindow": "<%= @user.full_name %>'s location"
      }
    ]);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
    handler.getMap().setZoom(17);
  });
</script>

然而,我仍然没有在页面上加载地图,显示错误 Uncaught ReferenceError: Gmaps is not defined

它确实加载了,当我从我的 HTML 头中的外部 CDN 源加载 gmaps 脚本时,错误消失了,正如这个问题所暗示的:Gmaps is not defined

所以这显然只是 google_maps.js 脚本的加载/可用性。文件太大,无法在此处显示,但这里是工作 CDN 版本的链接:cdn.jsdelivr.net/gmaps4rails/2.1.2/gmaps4rails.js

将其复制粘贴到我的 google_maps.js 文件中并没有帮助。而且我试图弄清楚如何让它与驻留在我的 Rails 应用程序中的 Google Maps 脚本一起工作,而 webpack Rails 6 世界对我来说仍然很新。任何建议将不胜感激。

标签: ruby-on-railsgoogle-mapswebpackruby-on-rails-6

解决方案


快速而简单的方法是从 CDN 而不是 Webpack 加载 gmaps4rails 代码(和下划线)。由于您只是使用<script>标签来构建地图,因此 Webpack 无法帮助您。

如果你还是想尝试使用 Webpack,请继续阅读。

了解 Webpack 将自身与全局范围隔离;<script>与 Sprocket 不同,您在 Webpack 中导入的对象或值在标签或浏览器控制台中不可用。如果你想要这种行为,你必须手动配置它。

查看 gmaps4rails 脚本,它似乎不支持模块,并假设它在全局范围内进行评估(下划线可用)。换句话说,它不是模块友好的。但我们可以让它玩得很好。

我们需要告诉 Webpackthis在 gmaps4rails 脚本中将其视为window,即全局范围,并“提供”下划线(或几乎可互换的 lodash,如下所示),因为它假定_lib 在其范围内可用。

在你的外壳中:

$ yarn add imports-loader lodash

config/webpack/environment.js

const { environment } = require('@rails/webpacker')
const webpack = require('webpack')

environment.loaders.append('gmap4rails', {
  test: /gmaps_google/,
  use: [
    {
      loader: 'imports-loader',
      options: 'this=>window',
    },
  ],
})

environment.plugins.append(
  'lodash',
  new webpack.ProvidePlugin({
    _: 'lodash',
  })
)

module.exports = environment

假设您已按照gmaps4rails README正确设置了您的 google 脚本,这应该可以解决问题。


我在example/gmap4rails分支中创建了一个带有工作示例的演示应用程序(带上您自己的 Google Maps API 密钥):https ://github.com/rossta/rails6-webpacker-demo/tree/example/gmaps4rails


推荐阅读