最近使用到superMap做三维地图,而项目又分为可视化大屏与后台管理系统两部分,所以项目配置了多入口,然引入cesium依赖就成了问题,在vue cli3 整合Cesium,处理build 时内存溢出问题虽然知道了整合原生的cesium的方法,

但是在实际开发中会发现superMap 官方扩展的接口是无法使用的,必须引入superMap官方重写的cesium.js才可以, 然而superMap官方并提供模块化的开发版本,所以只有使用原生script 引入了

一、使用script 标签加载cesium

于是我分别在public目录下创建了两个html文件

分别是admin 和screen,然后在页面中使用<script src="libs/Cesium/Cesium.js"></script>进行js引入,然而测试发现一个奇怪的问题是cli3的多入口。在初始化时会使用默认的index.html页面作为默认入口页面



发现我自己增加的script 都没有了。。。这个怎么办?于是想到了document.createElement("script");在vue 初始化的时候去动态加载js

于是引入了如下专门用于异步加载的函数


var Head = document.getElementsByTagName('head')[0], style = document.createElement('style'); //异步加载css,js文件
function linkScript(parm, fn) {
var linkScript;
if (/\.css[^\.]*$/.test(parm)) {
linkScript = document.createElement("link");
linkScript.type = "text/" + ("css");
linkScript.rel = "stylesheet";
linkScript.href = parm;
} else {
// debugger
linkScript = document.createElement("script");
linkScript.type = "text/" + ("javascript");
linkScript.src = parm;
}
Head.insertBefore(linkScript, Head.lastChild)
linkScript.onload = linkScript.onerror = function (res) {
if (fn) fn(res)
}
} linkScript("libs/Cesium/Cesium.js");

admin.js中import '../../components/common/js/asyncLoadExtraAssest'引入

这样是可以将cesium加载进来

二、刷新cesium 实例丢失

然而在点击浏览器左上角刷新按钮强制刷新页面时发现cesium在window中的实例丢失了引起了undefined异常

三、第一种处理方案(原型缓存)

开始我想到了是否是因为刷新后页面间window 上的实例都清除了,于是想到使用Vue的实例原型来缓存第一次加载进来的cesium实例(使用到了函数柯里化来进行cesium缓存)最后发现没有任何作用

四、第二种处理方案(更改 script 为同步)

再后来打断点一跟发现,



不对其实,window中的cesium实例是存在的只是较晚于页面中加载地图的组件,于是想到了是script 中异步加载解析cesium.js的锅,于是想将script加载解析更改为同步执行;

但是这个想法好像行不通,document加载的script 默认就是异步,就算为其增加 async:false也没用(浏览器会自动屏弃掉)

五、第三种处理方案(使用HtmlWebpackPlugin插件)

于是有想到了使用 HtmlWebpackPlugin为其设置页面配置



增加一个mutilPageConfig.js来配置每个页面的属性

const fs = require("fs");
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 通过页面配置文件过去页面json
function generateByConfig() {
return JSON.parse(fs.readFileSync("./src/page.json"));
} // 生成extraEntry
const extraEntry = generateByConfig(); let newExtraEntry = {}; // 生成HtmlWebpackPlugin
let extraHtmlWebpackPlugins = []; for (let i in extraEntry) {
let chunk = i;
newExtraEntry[chunk] = extraEntry[i].path;
extraHtmlWebpackPlugins.push(
new HtmlWebpackPlugin({
filename: chunk + ".html",
template: "public/index.html",
chunks: [chunk],
title: extraEntry[i].title,
favicon:extraEntry[i].favicon,
iconfont:' <link rel="stylesheet" href="//at.alicdn.com/t/font_1668594_l9pybqe35u.css">',
widgets:' <link rel="stylesheet" href="libs//Cesium/Widgets/widgets.css">',
cesium:' <script src="libs/Cesium/Cesium.js"></script>',
})
);
}; // 复制静态资源
// extraHtmlWebpackPlugins.push(
// new CopyWebpackPlugin([
// {
// from: './src/assets/libs',
// to: 'libs',
// ignore: ['.*']
// }
// ])
// ) exports.extraEntry = newExtraEntry;
exports.extraHtmlWebpackPlugins = extraHtmlWebpackPlugins;

vue.config.js引入

const multiBuilder = require("./multiPageConfig");
const { extraEntry, extraHtmlWebpackPlugins } = multiBuilder; module.exports = {
configureWebpack: {
entry: {
...extraEntry
},
plugins: extraHtmlWebpackPlugins,
}
}

再删除掉pages相关配置,运行发现提示

 ERROR  Failed to compile with 2 errors                                                                         11:17:52

This relative module was not found:

* ./src/main.js in multi (webpack)-dev-server/client?http://192.168.0.101:8081/sockjs-node (webpack)/hot/dev-server.js ./src/main.js, multi (webpack)/hot/dev-server.js (webpack)-dev-server/client?http://192.168.0.101:8081/sockjs-node ./src/main.js

转念一想,糊涂这是cli2的加载方式,cli3使用的是pages进行配置的,于是我将pages恢复并修改为

发现

虽然页面一片空白,但是页面title也icon可以加载正确!

六、最终处理方案(使用pages属性配置外部资源)

有了上面的初步测试发现多个页面可以使用一个index.html,

于是再到vue官网去看看



这个比较坑的是平时喜欢使用中文版的

看中文翻译是否漏了一段 哎,看来英语很重要呀

有了上诉经历,现在基本明白怎么进行接下来的操作了


修改page中的配置来更改页面加载的外部资源,而上一步配置的mutilPageConfig可改下,进行配置整合,再运行发现页面OK了,刷新cesium也不会再丢失了


最后在完整配置如下


1、page.json

{
"index": {
"entry": "./src/views/admin/admin.js",
"template": "public/index.html",
"filename": "index.html",
"favicon": "public/favicon_management.ico",
"title": "后台管理系统",
"iconfont":" <link rel='stylesheet' href='//at.alicdn.com/t/font_1668594_l9pybqe35u.css'>",
"widgets":" <link rel='stylesheet'' href='libs//Cesium/Widgets/widgets.css'>",
"cesium":" <script type='text/javascript'' src='libs/Cesium/Cesium.js'></script>",
"chunks": ["chunk-vendors", "chunk-common", "index"]
},
"view": {
"entry": "./src/views/bigScreen/screen.js",
"emplate": "public/index.html",
"filename": "view.html",
"title": "可视化平台",
"favicon": "public/favicon_view.ico",
"iconfont":" <link rel='stylesheet' href='//at.alicdn.com/t/font_1668594_l9pybqe35u.css'>",
"widgets":" <link rel='stylesheet'' href='libs//Cesium/Widgets/widgets.css'>",
"cesium":" <script type='text/javascript'' src='libs/Cesium/Cesium.js'></script>",
"chunks": ["chunk-vendors", "chunk-common", "view"]
}
}

2、multiPageConfig.js

const fs = require("fs");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i; const isProduction = process.env.NODE_ENV === 'production'; // 生成HtmlWebpackPlugin
let extraHtmlWebpackPlugins = [];
// 复制静态资源
extraHtmlWebpackPlugins.push(
new CopyWebpackPlugin([
{
from: './src/assets/libs',
to: 'libs',
ignore: ['.*']
}
])
)
if(isProduction){
extraHtmlWebpackPlugins.push(
new UglifyJsPlugin({
uglifyOptions: {
compress: {
drop_console: true,
drop_debugger: false,
pure_funcs: ['console.log']//移除console
}
},
sourceMap: false,
parallel: true
}),
new CompressionWebpackPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: productionGzipExtensions,
threshold: 10240,
minRatio: 0.8
})
)
} // 通过页面配置文件过去页面json
function generateByConfig() {
return JSON.parse(fs.readFileSync("./src/page.json"));
} // 生成extraEntry
const entryPages = generateByConfig(); exports.extraEntry = entryPages; exports.extraHtmlWebpackPlugins = extraHtmlWebpackPlugins

3、index.js

const path = require("path");
const multiBuilder = require("./multiPageConfig");
const { extraEntry, extraHtmlWebpackPlugins } = multiBuilder; const isProduction = process.env.NODE_ENV === 'production';
function assetsPath (_path) {
const assetsSubDirectory = isProduction ? './': '/';
return path.posix.join(assetsSubDirectory, _path)
} module.exports = {
pages:extraEntry,
configureWebpack: {
output: {
sourcePrefix: ' '
},
amd: {
toUrlUndefined: true
},
resolve: {
// alias: {
// 'cesium': path.resolve(__dirname, '../',cesiumSource)
// }
},
plugins: extraHtmlWebpackPlugins,
module: {
rules: [
{
test: /\.(cur)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: assetsPath('cur/[name].[hash:7].[ext]')
}
},
],
unknownContextCritical: /^.\/.*$/,
unknownContextCritical: false }
},
css: {
loaderOptions: {
postcss: {
plugins: [
require("postcss-px-to-viewport")({
unitToConvert: "px",
viewportWidth: 1920,
viewportHeight: 960,
unitPrecision: 3,
propList: ["*"],
viewportUnit: "vw",
selectorBlackList: ['.ignore', 'calc'],
minPixelValue: 1,
mediaQuery: false,
exclude: /((\/|\\)(node_modules|src)(\/|\\))/,
})
]
}
}
}
}

4、vue.config.js


const extraConfig = require('./configHelper/index.js')
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
devServer: {
port: 8081,
disableHostCheck: true,
},
pages: extraConfig.pages,
productionSourceMap: false,
configureWebpack: extraConfig.configureWebpack,
css: extraConfig.css
}

七、配置SuperMap全局构造

上面说到的将SuperMap重新过的Cesium.js整合到了项目中,也解决了页面刷新异步加载外部js 的问题,但是在全局使用SuperMap构造函数时还是会提示undefined,因为这里还需要将从SuperMap官网下载的

中的

这些扩展文件夹加入到vue的项目中去

1、首先将其拷贝到libs 文件夹下
2、在page.json中新增"superMap":"<script type='text/javascript' src='libs/SuperMap.Include.js'></script>",

如:

3、在index.html中新增<%= htmlWebpackPlugin.options.superMap %>

如:

4、现在就可以在项目中使用了



OK 到此问题总算解决了,也对js 异步加载和vue多入口配置有了进一步了解,特此记录希望对小伙伴有帮助,感谢你的阅读,如觉得ok请点赞或分享,赠人玫瑰手有余香,你会快乐开心每一天的。

Vue cli3 整合SuperMap巧遇js异步加载的坑的更多相关文章

  1. JS异步加载的三种方案

    js加载的缺点:加载工具方法没必要阻塞文档,个别js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载. 一.def ...

  2. Vue(基础七)_webpack(webpack异步加载原理)

    ---恢复内容开始--- 一.前言 1.webpack异步加载原理’                                           2.webpack.ensure原理     ...

  3. 点评js异步加载的4种方式

    主要介绍了点评js异步加载的4种方式,帮助大家更全面的了解js异步加载方式,感兴趣的小伙伴们可以参考一下 js异步加载的4种方式,点评开始. <!DOCTYPE html> <htm ...

  4. JS异步加载的三种方式

    js加载的缺点:加载工具方法没必要阻塞文档,过得js加载会影响页面效率,一旦网速不好,那么整个网站将等待js加载而不进行后续渲染等工作. 有些工具方法需要按需加载,用到再加载,不用不加载,. 默认正常 ...

  5. 关于JS异步加载方案

    javascript延迟加载的解决方案: 1.使用defer标签 <span style="font-size: small;"><script type=&qu ...

  6. 转:web前端面试题合集 (Javascript相关)(js异步加载详解)

    1. HTTP协议的状态消息都有哪些? 1**:请求收到,继续处理2**:操作成功收到,分析.接受3**:完成此请求必须进一步处理4**:请求包含一个错误语法或不能完成5**:服务器执行一个完全有效请 ...

  7. 关于使用Iscroll.js异步加载数据后不能滑动到最底端的问题解决方案

    关于使用Iscroll.js异步加载数据后不能滑动到最底端,拉到最下边又弹回去的问题困扰了我老半天,相信很多朋友都遇到了.我刚好不小心解决了,和大家分享一下.由于各种忙,下边就直接上代码吧. (前提是 ...

  8. js 异步加载的方式

    js 异步加载的方式 渲染引擎遇到 script 标签会停下来,等到执行完脚本,继续向下渲染 defer 是“渲染完再执行”,async 是“下载完就执行”,defer 如果有多个脚本,会按照在页面中 ...

  9. js延迟加载、js异步加载

    1.js延迟加载 (1)js延迟加载是js性能优化的一种方式 (2)作用:为了提高网页的加载速度 (3)原理:等网页加载完成之后再加载js文件 ··需要优化的原因:HTML元素是按照其在页面中出现的次 ...

  10. JS -- 异步加载进度条

    今天在博客园问答里面看到博友问道怎么实现Ajax异步加载产生进度条. 很好奇就自己写了一个. 展现效果: 1) 当点击Load的时候,模拟执行异步加载. 浏览器被遮挡. 进度条出现. 实现思路: 1. ...

随机推荐

  1. 使用 SpeechT5 进行语音合成、识别和更多功能

    我们很高兴地宣布,SpeechT5 现在可用于 Transformers (一个开源库,提供最前沿的机器学习模型实现的开源库). SpeechT5 最初见于微软亚洲研究院的这篇论文 SpeechT5: ...

  2. .Net 6.0全局异常捕获

    背景: 全局异常捕获是我们开发当中不可获取的一个环节,顾名思义就是全局的捕获异常,并响应出去,今天就带着各位童鞋们在.Net 6.0当中如何做到全局异常捕获. 思路: 我们可以通过请求管道达到我们全局 ...

  3. 如何使用 vue + intro 实现后台管理系统的引导

    引言 为了让用户更好的适应新版,或更方便使用公司内部系统,可以加入新手指引功能.如果你也想在自己的网页加入用户指引,那就试试在 vue 中使用 Intro.js 吧,它能够很轻松的制作出新手指引的效果 ...

  4. 正则表达式(cases)

    匹配不含'aaa'和'bbb'的字符串: ^(?!.*aaa)(?!.*bbb).*$ To be continue...

  5. C#中的命名空间和程序集

    前言 今天这篇文章和大家一起学习下C#语言下的命名空间和程序集. 在日常的编码工作中,我们对命名空间和程序集都不会很陌生.在创建项目文件时,IDE自动会为我们创建好一个大的命名空间和程序集.大多数业务 ...

  6. Vue2模版编译(AST、Optimize 、Render)

    在Vue $mount过程中,我们需要把模版编译成render函数,整体实现可以分为三部分: parse:解析模版 template生成 AST语法树 optimize: 优化 AST语法树,标记静态 ...

  7. SHA-256 简介及 C# 和 js 实现【加密知多少系列】

    〇.简介 SHA-256 是 SHA-2 下细分出的一种算法.截止目前(2023-03)未出现"碰撞"案例,被视为是绝对安全的加密算法之一. SHA-2(安全散列算法 2:Secu ...

  8. call、apply 及 bind 函数

    首先从以下几点来考虑如何实现这几个函数 不传入第一个参数,那么上下文默认为 window: 改变了 this 指向,让新的对象可以执行该函数,并能接受参数. 实现call 首先 context 为可选 ...

  9. 浅谈$\mathcal{LCT}$初步使用及具体操作

    \(0x01\) 闲话 · \(LCT\)的用途以及具体思路 \(LCT\)是啥?百度一下的话--貌似是一种检查妇科病的东西?Oier的口味可是真不一般啊 咳,其实在我最近只是浅浅地学了一部分的基础上 ...

  10. PyCharm在Linux安装出现报错-Java Runtime (class file version 55.0)

    在Linux桌面下安装PyCharm的时候出现如下报错 root@ubuntu:~# cd pycharm-community-2021.1.1 root@ubuntu:~/pycharm-commu ...