Rails 6中带有Webpack的传单L.timeline不起作用 [英] Leaflet with Webpack in Rails 6. L.timeline is not a function

查看:131
本文介绍了Rails 6中带有Webpack的传单L.timeline不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这就像@rossta为 Gmaps 回答的问题一样,但我不知道无法理解问题并回答得足够好以使他的建议生效.

This looks just like the question @rossta answered for Gmaps, but I don't understand the problem and answer well enough to make his suggestion work.

错误是:Uncaught TypeError: L.timeline is not a function at Object.success (mapTwo.js:14)第14行是var timelineData = L.timeline(data_data, {.完整的代码如下.

The error is: Uncaught TypeError: L.timeline is not a function at Object.success (mapTwo.js:14) Line 14 is var timelineData = L.timeline(data_data, {. Complete code below.

我删除了在Rails 5.2和控制台中工作的传单gem

I removed the leaflet gems that work in Rails 5.2 and in console

yarn add leaflet
yarn add leaflet.timeline

和代码:

// app/javascript/packs/application.js
import "core-js/stable"
import "regenerator-runtime/runtime"
import '../stylesheets/application'
window.jQuery = $
window.$      = $
import 'leaflet'
import "leaflet.timeline"
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("trix")
require("@rails/actiontext")
require("jquery") 
import "bootstrap"
import 'bootstrap/dist/js/bootstrap'

document.addEventListener("turbolinks:load", () => {
  $('[data-toggle="tooltip"]').tooltip()
  $('[data-toggle="popover"]').popover()
})

<!-- map/index.html.erb -->
<div id="map_two"></div>
<%= javascript_pack_tag 'mapTwo' %> 


// javascript/packs/mapTwo.js  called from map/index.html.erb
console.log('Hello from /javascript/packs/mapTwo.js')
var mapVar = L.map("map_two", {
  center: [34.040951, -118.258579],
  zoom: 13
});
L.tileLayer('https://crores.s3.amazonaws.com/tiles/bkm/{z}/{x}/{y}.png').addTo(mapVar);
$.getJSON("map/line_data.geojson", function(data_data) {
  var timelineData = L.timeline(data_data, {
    style: function(data_data) {
      return {
        stroke: true,
        fillOpacity: 0.5
      }
    }, // end style: function(data_data)
    waitToUpdateMap: true,
    onEachFeature: function(data_data, layer) {
        layer.bindTooltip(data_data.properties.popup, {
          direction: 'top'
        });
      } // onEachFeature: 
  }); // end let timelineData = L.timeline
  var timelineControl = L.timelineSliderControl({
    enableKeyboardControls: true,
    steps: 100,
    start: 1885,
    end: 1928,
  });
  timelineControl.addTo(mapVar);
  timelineData.addTo(mapVar);
  timelineControl.addTimelines(timelineData);
}); //  end $.getJSON

我尝试应用提供的解决方案:

My attempt at applying the solution offered:

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

environment.plugins.append('Provide',
  new webpack.ProvidePlugin({
    $: 'jquery',
    jQuery: 'jquery',
    jquery: 'jquery',
    // 'window.Jquery': 'jquery', 
    Popper: ['popper.js' ,'default'],
    L: 'leaflet' // didn't help
  }))

// https://stackoverflow.com/questions/59042437/gmaps-with-rails-6-webpack
environment.loaders.append('leaflet', {
  test: /map/,
  use: [
    {
      loader: 'imports-loader',
      options: 'this=>window',
    },
  ],
})

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

module.exports = environment

package.json

{
  "license": "ISC",
  "main": "application.js",
  "dependencies": {
    "@rails/actiontext": "^6.0.0",
    "@rails/ujs": "^6.0.1",
    "@rails/webpacker": "4.2.2",
    "bootstrap": "^4.4.1",
    "core-js": "^3.5.0",
    "imports-loader": "^0.8.0",
    "jquery": "^3.4.1",
    "jqueryui": "^1.11.1",
    "leaflet": "^1.6.0",
    "leaflet.timeline": "^1.2.1",
    "lodash": "^4.17.15",
    "mapbox": "^1.0.0-beta10",
    "ol": "^6.1.1",
    "ol-ext": "^3.1.7",
    "ol-layerswitcher": "^3.4.0",
    "ol-loupe": "^1.0.1",
    "popper.js": "^1.16.0",
    "regenerator-runtime": "^0.13.3",
    "trix": "^1.0.0",
    "turbolinks": "^5.2.0",
    "webpack": "^4.41.2"
  },
  "devDependencies": {
    "webpack-dev-server": "^3.10.0"
  }
}

推荐答案

设置存在一些问题:

  1. 'leaflet.timeline'插件假定传单模块可用作全局变量'L'.插件的源代码表明这是正确的(在发布本文时,此信息是掌握的): https://github.com/skeate/Leaflet.timeline/blob/b7a8406f5a9a66ccdbcaf73465baaedadec76d1f/src/Timeline.js#L1
  2. (我相信)您一次在页面上使用多个入口:'application.js''mapTwo.js'. Rails将入口点称为"packs",因此app/javascript/packs中的所有内容都是Webpack的单独入口点. Webpack建议每页1个入口点 ;如果没有额外的配置,则一页上的多个入口点可能会导致令人惊讶的行为,尤其是在全局变量方面(请参阅#1).
  1. The 'leaflet.timeline' plugin assumes the leaflet module is available as the global variable 'L'. The source code of the plugin shows this to be true (on master at the time of this post): https://github.com/skeate/Leaflet.timeline/blob/b7a8406f5a9a66ccdbcaf73465baaedadec76d1f/src/Timeline.js#L1
  2. (I believe) You are using more than one entry point on the page at one time: 'application.js' and 'mapTwo.js'. Rails calls entry points "packs", so everything in app/javascript/packs is a separate entry point to Webpack. Webpack recommends 1 entry point per page; without extra configuration, multiple entry points on one page can lead to surprising behavior, especially with regards to global variables (see #1).

要进一步解决问题2,使用当前配置,Webpack不知道您要在页面上使用两个入口点.它将应用程序包中的Leaflet模块的一个实例与mapTwo包中的Leaflet模块的另一个实例捆绑在一起.它将maplet捆绑了Leaflet模块,因为您添加了ProvidePlugin配置L: 'leaflet',该配置基本上说是将var L = require('leaflet')添加到引用L的每个模块.

To elaborate further on issue 2, with your current configuration, Webpack doesn't know you want to use two entry points on the page; it bundles one instance of the Leaflet module in the application pack and another instance of the Leaflet module in the mapTwo pack. It bundles the Leaflet module in mapTwo because you added the ProvidePlugin configuration L: 'leaflet', which says, basically, add var L = require('leaflet') to every module that references L.

因此,有一些可能的解决方法:

So there are a few possible fixes:

  1. 将您的import 'leaflet.timeline'移至mapTwo.js并从application.js中删除import 'leaflet'.在您的ProvidePlugin配置中,您不需要import 'leaflet'.这是解决L.timeline is not a function短期问题的最简单方法.当使用页面上的多个入口点时,它不会阻止您两次将Leaflet之类的模块捆绑在一起,比如说您是否需要在application.js依赖关系图中的某处添加import 'leaflet'. OR

  1. Move your import 'leaflet.timeline' into mapTwo.js and remove import 'leaflet' from application.js. You don't need import 'leaflet' given your ProvidePlugin config. This is the easiest fix to address the short-term issue of L.timeline is not a function. It does not prevent you from bundling modules like Leaflet twice when using multiple entry points on the page, say if you were to need to add import 'leaflet' somewhere in the application.js dependency graph. OR

不要分摊你的背包;将所有现有代码合并到'application.js'的依赖关系图中.您可能需要将现有的mapTwo代码包装在回调中,即document.addEventListener('DOMContentLoaded', callback). OR

Don't split up your packs; consolidate all your existing code in the dependency graph of 'application.js'. You may need to wrap your existing mapTwo code in callback, i.e., document.addEventListener('DOMContentLoaded', callback). OR

使用 SplitChunksPlugin ,这是一种共享方式Webpack块"中的模块,在您的情况下,意味着入口点application.js和mapTwo.js.这意味着,将现有代码与其他更改一起保存在单独的包中,这些更改将在Rails Webpack文档中进行更详细的描述:

Use the SplitChunksPlugin, which is a way of sharing modules across Webpack "chunks" which, in your case, means the entry points, application.js and mapTwo.js. This means, keep your existing code in separate packs along with additional changes described in more detail in the Rails Webpack docs: https://github.com/rails/webpacker/blob/master/docs/webpack.md#add-splitchunks-webpack-v4. You may need to also wrap mapTwo.js code in the DOMContentLoaded listener, as in 2.

最后,从您的配置中删除此代码;由于这是从其他解决方案复制而来的,因此不会为您的设置添加任何值:

Finally, remove this code from your configuration; as this was copied from another solution, it's not adding any value to your setup:

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

您还可以合并单独的ProvidePlugin组,即lodash不需要单独的组.

You can also likely combine the separate ProvidePlugin groups, i.e., you don't need a separate one for lodash.

这篇关于Rails 6中带有Webpack的传单L.timeline不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆