vue cli3 整合Cesium,处理build 时内存溢出问题
一直使用cesium,但是都是使用script直接引入的,但是在将其放置在增加路由的子页面中中时会出现一个问题,刷新后提示cesium is undefined
看直接引入cesium.js
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="stylesheet" href="libs/Cesium/Widgets/widgets.css"> <link rel="stylesheet" href="//at.alicdn.com/t/font_1668594_l9pybqe35u.css"> <title><%= htmlWebpackPlugin.options.title %></title> </head> <body> <noscript> <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> <div id="screen"></div> <!-- built files will be auto injected --> <script type="text/javascript" src="libs/Cesium/Cesium.js"></script> </body> </html>
刷新后提示错误
。。。。。。。。
后来决定根据cesium官网来改进配置
一、安装ceium
npm install --save-dev cesium
二、配置vue.config.js
1、在vue.config.js增加cesium目录映射
// The path to the CesiumJS source code const cesiumSource = 'node_modules/cesium/Source'; const cesiumWorkers = '../Build/Cesium/Workers';
2、配置别名
chainWebpack: config => { config.resolve.alias .set("cesium", resolve(cesiumSource)) },
3、使用WebpackPlugin拷贝cesium资源到dist
configureWebpack: config => { const plugins = []; plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]) ); plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]) ); plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ]) ); plugins.push( new webpack.DefinePlugin({ CESIUM_BASE_URL: JSON.stringify('./') }) ); config.plugins = [...config.plugins, ...plugins]; },
4、main.js引用
将Home.vue修改用于测试
最后vue.config.js配置是这样的
const path = require("path"); const webpack = require('webpack'); const CopyWebpackPlugin = require('copy-webpack-plugin') // The path to the CesiumJS source code const cesiumSource = 'node_modules/cesium/Source'; const cesiumWorkers = '../Build/Cesium/Workers'; function resolve(dir) { return path.join(__dirname, dir) } module.exports = { publicPath: process.env.NODE_ENV === 'production' ? './' : '/', devServer: { port: 8099, disableHostCheck: true, }, chainWebpack: config => { config.resolve.alias .set("cesium", resolve(cesiumSource)) }, configureWebpack: config => { const plugins = []; plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' } ]) ); plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets' } ]) ); plugins.push( new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' } ]) ); plugins.push( new webpack.DefinePlugin({ CESIUM_BASE_URL: JSON.stringify('./') }) ); config.plugins = [...config.plugins, ...plugins]; }, }
5、 运行测试
npm run serve
提示了几个错误
WARNING Compiled with 3 warnings 09:14:40
warning in ./src/main.js
"export 'default' (imported as 'Cesium') was not found in 'cesium/Cesium'
warning in ./node_modules/cesium/Source/Core/buildModuleUrl.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
warning in ./node_modules/cesium/Source/Core/buildModuleUrl.js
Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
看第一个错误相信熟悉过node 或者commonJS都知道其实,Cesium.js没有 export default默认导出
三、错误处理
那么就将
import Cesium from 'cesium/Cesium'
修改为
// const Cesium = require('cesium/Cesium') ; // 也可以改成require引入 import * as Cesium from 'cesium/Cesium'
好了目前只有两个错误了
看地图也加载出来了
但是还是有两个【错误】…
看到有朋友说要增加unknownContextCritical配置,如:
于是我试着这样去修改配置
chainWebpack: config => { config.module .unknownContextCritical(false) .end() config.resolve.alias .set("cesium", resolve(cesiumSource)) },
但是运行是报错的
ERROR TypeError: config.module.unknownContextCritical is not a function
看了半天vue 配置文档,最后将回调函数换成对象就OK了
这里就不啰嗦了,直接看最终的vue.config.js配置吧
const path = require("path"); const webpack = require('webpack'); const CopyWebpackPlugin = require('copy-webpack-plugin') // The path to the CesiumJS source code const cesiumSource = 'node_modules/cesium/Source'; const cesiumWorkers = '../Build/Cesium/Workers'; function resolve(dir) { return path.join(__dirname, dir) } module.exports = { publicPath: process.env.NODE_ENV === 'production' ? './' : '/', devServer: { port: 8099, disableHostCheck: true, }, configureWebpack: { output: { sourcePrefix: ' ' }, amd: { toUrlUndefined: true }, resolve: { alias: { 'vue$': 'vue/dist/vue.esm.js', '@': path.resolve('src'), 'cesium': path.resolve(__dirname, cesiumSource) } }, plugins: [ new CopyWebpackPlugin([ { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers'}]), new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Assets'), to: 'Assets'}]), new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets'}]), new CopyWebpackPlugin([ { from: path.join(cesiumSource, 'ThirdParty/Workers'), to: 'ThirdParty/Workers'}]), new webpack.DefinePlugin({ CESIUM_BASE_URL: JSON.stringify('./') }) ], module: { unknownContextCritical: /^.\/.*$/, unknownContextCritical: false } } }
四、deal with ‘JavaScript heap out of memory’ in vue build
> tf-pipe-gallery@0.1.0 build D:\YLKJPro\tf-pipe-gallery
> vue-cli-service build
\ Building for production...
<--- Last few GCs --->
[10780:000001C5544A9790] 232452 ms: Mark-sweep 1383.4 (1420.6) -> 1383.0 (1420.6) MB, 1387.6 / 0.0 ms (average mu = 0.105, current mu = 0.017) allocation failure scavenge might not succeed
[10780:000001C5544A9790] 233690 ms: Mark-sweep 1383.7 (1420.6) -> 1383.3 (1421.1) MB, 1234.4 / 0.0 ms (average mu = 0.057, current mu = 0.003) allocation failure scavenge might not succeed
<--- JS stacktrace --->
==== JS stack trace =========================================
0: ExitFrame [pc: 0000026F403D0461]
Security context: 0x01f699a9d971 <JSObject>
1: /* anonymous */(aka /* anonymous */) [000002EFA8A9A541] [D:\YLKJPro\tf-pipe-gallery\node_modules\webpack-sources\lib\applySourceMap.js:~58] [pc=0000026F4126674D](this=0x03d26f9825b1 <undefined>,0x02080a98c961 <String[6]: Array(>,0x01b0a61506b9 <Object map = 000000E391A70FC1>)
2: SourceNode_walk [0000036225A356F9] [D:\YLKJPro\tf-pipe-gallery\node...
FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Writing Node.js report to file: report.20200402.161224.10780.001.json
Node.js report completed
1: 00007FF6B7CCCC3A public: __cdecl v8::internal::GCIdleTimeHandler::GCIdleTimeHandler(void) __ptr64+4618
2: 00007FF6B7C798B6 uv_loop_fork+80934
3: 00007FF6B7C7A411 uv_loop_fork+83841
4: 00007FF6B8070F1E void __cdecl v8::internal::FatalProcessOutOfMemory(class v8::internal::Isolate * __ptr64,char const * __ptr64)+798
5: 00007FF6B8070E57 void __cdecl v8::internal::FatalProcessOutOfMemory(class v8::internal::Isolate * __ptr64,char const * __ptr64)+599
6: 00007FF6B8120E74 public: static bool __cdecl v8::internal::Heap::RootIsImmortalImmovable(int)+14900
7: 00007FF6B8116994 public: bool __cdecl v8::internal::Heap::CollectGarbage(enum v8::internal::AllocationSpace,enum v8::internal::GarbageCollectionReason,enum v8::GCCallbackFlags) __ptr64+7556
8: 00007FF6B8115068 public: bool __cdecl v8::internal::Heap::CollectGarbage(enum v8::internal::AllocationSpace,enum v8::internal::GarbageCollectionReason,enum v8::GCCallbackFlags) __ptr64+1112
9: 00007FF6B811EAB7 public: static bool __cdecl v8::internal::Heap::RootIsImmortalImmovable(int)+5751
10: 00007FF6B811EB36 public: static bool __cdecl v8::internal::Heap::RootIsImmortalImmovable(int)+5878
11: 00007FF6B82A78E1 public: class v8::internal::Handle<class v8::internal::HeapObject> __cdecl v8::internal::Factory::NewFillerObject(int,bool,enum v8::internal::AllocationSpace) __ptr64+49
12: 00007FF6B8360CEA public: static int __cdecl v8::internal::StoreBuffer::StoreBufferOverflow(class v8::internal::Isolate * __ptr64)+27082
13: 0000026F403D0461
看到这一片错误的确叫人头疼。。。
最后在vue 官网Issues终于找到了解决方法
直接修改package.json中的script
"build": "node --max_old_space_size=4096 node_modules/@vue/cli-service/bin/vue-cli-service.js build --open"
再次npm run build
看见buil 成功了
ok到此总算完美解决了所有问题。
感谢阅读,希望对于刚入门的cesium 开发者一些帮助,谢谢