【问题标题】:Importing node_modules into Laravel via Mix通过 Mix 将 node_modules 导入 Laravel
【发布时间】:2020-08-24 21:41:12
【问题描述】:

我正在尝试在 Laravel 5.7 项目中使用 OpenLayers (v5.3.0),但是从 node_modules 导入 o​​l 时遇到了很多麻烦。

我安装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 的最佳方式,但我不知道为什么它不起作用。非常感谢一些帮助。

【问题讨论】:

  • 你解决了吗?我有同样的问题。
  • 我遇到了同样的问题..你解决了吗??

标签: javascript laravel-5 npm openlayers openlayers-5


【解决方案1】:

经过反复试验,我让 OpenLayers 6.1 与 Laravel 6.2 一起使用 Mix、Webpack 和 ES6 模块导入。诀窍是将所有 javascript 编写在一个单独的文件中,并将其捆绑到 app.js 中。

使用 npm 将 openlayers 安装到您的 Laravel 项目中:

npm install ol

在您的 Laravel 项目中创建一个新文件 resources/js/myMap.js(与 bootstrap.jsapp.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.jsnpm run devmyMap.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>

注意:

  1. div id="osm_map" 匹配 openlayers 目标。
  2. OpenLayers CSS 也被捆绑并在此处引用。这设置了 OpenLayers 控件的样式。
  3. 当我们调用 my_map.display() 方法时,地图就会显示出来。

这成功地在 Laravel 刀片模板中显示了交互式 OpenLayers 地图。

【讨论】:

  • 这太棒了。让基本示例成功运行!不能感谢你。仅供参考,我只需要删除 myMap.js 中“关闭方法”行末尾的分号。
【解决方案2】:

安装ol 包:

npm install ol

在 js 文件夹中的资源目录中(bootstrap.js 和 app.js 所在的位置)创建文件名 map.js

resources/js/map.js

在 map.js 中编写您的 Openlayer 代码(示例代码):

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: 'map',
layers: [
    new TileLayer({
        source: new OSM()
    })
],
view: new View({
    center: [0, 0],
    zoom: 0
             })
});

现在,转到webpack.mix.js,通常在最后。

在文件末尾添加.js('resources/js/map.js', 'public/js')

webpack.mix.js 将如下所示:

const mix = require('laravel-mix');
/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.js('resources/js/map.js', 'public/js');

现在,npm run dev 在终端中

您的*.blade.php 代码应如下示例代码:

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>Using Webpack with OpenLayers</title>
    <style>
        #map {
            height: 100%;
            width: 100%;
            left: 0;
            top: 0;
            overflow: hidden;
            position: fixed;
        }
    </style>
</head>

<body>
    <div id="map"></div>
    <script type="text/javascript" src="{{ asset('/js/map.js') }}"></script>
</body>
</html>

不允许直接从公用文件夹导入节点模块。在这里,我们在项目中导入模块,并在公共文件夹中的webpack 的帮助下使用它。

用于生产:终端中的npm run production

【讨论】:

    猜你喜欢
    • 2019-08-27
    • 2022-01-25
    • 2018-08-09
    • 2021-04-13
    • 2019-09-14
    • 2019-09-04
    • 2020-08-23
    • 2022-09-30
    • 2021-04-11
    相关资源
    最近更新 更多