javascript - 通过 Mix 将 node_modules 导入 Laravel
问题描述
我正在尝试在 Laravel 5.7 项目中使用 OpenLayers (v5.3.0),但是从 node_modules 导入 ol 时遇到了很多麻烦。
我安装 ol 如下(基于https://www.npmjs.com/package/ol):
npm install ol
然后我更新了我的 resources\js\app.js,它现在只包含以下内容:
require('./bootstrap');
require('ol');
编辑:我还在 resources\js\app.js 中尝试了以下操作,但没有成功:
require('./bootstrap');
const ol = require('ol');
我的 webpack.mix.js 包含以下内容:
const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/js/app.js', )
.sass('resources/sass/app.scss', 'public/css');
我在一个名为 map.blade.php 的文件中也有以下相关行,我想在其中显示 OpenLayers 地图:
<script src="{!! mix('js/app.js') !!}"></script>
...
<div id='map' style='z-index: 1; width: 100%; height:calc(100% - 56px);'>
<script>
import Map from 'ol/Map';
import View from 'ol/View';
import TileLayer from 'ol/layer/Tile';
import XYZ from 'ol/source/XYZ';
new Map({
target: 'map',
layers: [
new TileLayer({
source: new XYZ({
url: 'https://{a-c}.tile.openstreetmap.org/{z}/{x}/{y}.png'
})
})
],
view: new View({
center: [0, 0],
zoom: 2
})
});
</script>
</div>
我也跑了npm run dev
。
在 Chrome 中进行测试时,我得到“Uncaught SyntaxError: Unexpected identifier”,指的是 map.blade.php 中的以下行:
import Map from 'ol/Map';
编辑:我还运行了以下命令以确保安装了所有依赖项:
npm install --save-dev parcel-bundler
运行上述程序时我没有收到任何错误,但 Chrome 中的相同错误仍然存在。
编辑:我还尝试将 javascript 从我的 map.blade.php 转移到一个新文件(mapscript.js)中,然后将其导入 map.blade.php(在“map”div 之后),如下所示:
<script src="{!! asset('js/mapscript.js') !!}" type="module"></script>
但后来我收到以下错误:
Uncaught TypeError: Failed to resolve module specifier "ol/Map". Relative references must start with either "/", "./", or "../".
之后,我尝试将以下行移出 app.js 并移入 mapscript.js:
require('ol');
并且还尝试了相同的方法:
const ol = require('ol');
但同样的 Uncaught TypeError 在这两种情况下都存在。
我已经尝试过 Stack Overflow 和其他地方的很多类似问题的解决方案,我也尝试过在 npm 之外使用 ol ,但我没有找到任何可以为我解决问题的方法。我相信使用 npm 和 Mix 是在我的项目中构建 OpenLayers 的最佳方式,但我不知道为什么它不起作用。非常感谢一些帮助。
解决方案
经过一些试验和错误后,我让 OpenLayers 6.1 与 Laravel 6.2 一起使用 Mix、Webpack 和 ES6 模块导入。诀窍是将所有 javascript 编写在一个单独的文件中,并将其捆绑到 app.js 中。
使用 npm 将 openlayers 安装到你的 Laravel 项目中:
npm install ol
在您的 Laravel 项目中创建一个新文件resources/js/myMap.js
(与bootstrap.js
和一起app.js
),然后将您的 OpenLayers javascript 代码放入其中。
让我们使用从https://openlayers.org/en/latest/doc/tutorials/bundle.html的官方文档复制的简短代码示例
import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
const map = new Map({
target: 'osm_map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
我们需要将其导出为文字对象以使其可用于其他代码,因此插入五行额外的行,如下所示。
import 'ol/ol.css';
import {Map, View} from 'ol';
import TileLayer from 'ol/layer/Tile';
import OSM from 'ol/source/OSM';
var my_map = { // <-- add this line to declare the object
display: function () { // <-- add this line to declare a method
const map = new Map({
target: 'osm_map',
layers: [
new TileLayer({
source: new OSM()
})
],
view: new View({
center: [0, 0],
zoom: 0
})
});
} // <-- close the method
}; // <-- close the object
export default my_map; // <-- and export the object
将这两行添加到末尾,bootstrap.js
以便它包含我们的代码,并将我们的对象 my_map 附加到全局窗口对象,以便我们可以从页面中引用它。
import my_map from './myMap.js';
window.my_map = my_map;
现在通过执行npm run dev
. 请注意,我们使用的是 Laravel 的默认 webpack 和混合配置——我们根本不需要编辑webpack.mix.js
。
npm run dev
将我们myMap.js
文件中的代码复制到app.js
. 我们每次编辑时都需要运行它myMap.js
。(npm run watch
可用于自动化此步骤)。
为了让地图显示在刀片模板中,我们需要一个与 OpenLayers 地图目标匹配的 div id,osm_map
在上面的示例代码中。这是一个最小的刀片。
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<style>
#osm_map {
position: absolute;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="app">
<div id="osm_map"></div>
</div>
<script src="{{ asset('js/app.js') }}" ></script>
<script type="text/javascript">
window.my_map.display();
</script>
</body>
</html>
笔记:
- div id="osm_map" 匹配 openlayers 目标。
- OpenLayers CSS 也被捆绑并在此处引用。这设置了 OpenLayers 控件的样式。
- 当我们调用 my_map.display() 方法时,地图就会显示出来。
这成功地在 Laravel 刀片模板中显示了交互式 OpenLayers 地图。
推荐阅读
- highcharts - 地图中固定的 highmaps/highcharts 图例
- intellij-idea - 我在新项目向导/工具窗口中看不到/运行 Gradle
- c++ - 如何检查一个类是否可以从多个参数显式构造?
- angular - 试图总结 grandTotal 是行不通的
- flutter - 如何正确声明数组
- r - 无法在 R 中订购条形图
- spring - 春季批处理执行,如何避免使用FlatFileItemWriter记录异常的文件名为空
- git - 使用 NPM 从 GitHub 存储库下载除 .gitignore 中的文件以外的所有文件?
- swift - URLSession(配置:URLSessionConfiguration.default)与 URLSession.shared
- html - 如何路由 url 以包括向下滚动到 Laravel 中的 div id