使用Webpack集成mapbox-gl与@mapbox/mapbox-gl-draw遇生产构建报错求助
解决Webpack打包mapbox-gl和mapbox-gl-draw生产构建后
e is not defined错误 我之前也碰到过一模一样的问题!这种生产环境才出现的未定义错误,本质是因为你引入的dist版本已经是经过压缩混淆的bundle,而Webpack生产模式下的压缩工具(比如Terser)会再次对它进行变量混淆,导致原本的变量引用被破坏,就出现了e is not defined这类报错。下面给你几个可行的解决方案:
方案1:改用CDN + Webpack Externals(最推荐)
这种方式既可以避免二次压缩的冲突,还能减小你的打包体积,把加载mapbox库的压力交给CDN。
步骤1:配置Webpack的externals
在你的Webpack生产配置文件中添加externals字段,告诉Webpack不要把这两个库打包进去,而是从全局变量中获取:
module.exports = { // ...其他Webpack配置 externals: { 'mapbox-gl': 'mapboxgl', '@mapbox/mapbox-gl-draw': 'MapboxDraw' } };
步骤2:在HTML中引入CDN资源
在项目的入口HTML文件里添加mapbox和draw的CDN脚本与样式:
<!-- 替换成你需要的版本号 --> <script src="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.js"></script> <link href="https://api.mapbox.com/mapbox-gl-js/v2.15.0/mapbox-gl.css" rel="stylesheet"> <script src="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.js"></script> <link href="https://api.mapbox.com/mapbox-gl-js/plugins/mapbox-gl-draw/v1.4.3/mapbox-gl-draw.css" rel="stylesheet">
步骤3:正常引入使用
在你的业务代码里直接import即可,不需要再引用dist版本:
import mapboxgl from 'mapbox-gl'; import MapboxDraw from '@mapbox/mapbox-gl-draw'; // 正常初始化地图和绘制工具 const map = new mapboxgl.Map({ container: 'map', style: 'mapbox://styles/mapbox/streets-v12', accessToken: '你的Mapbox Token' }); const draw = new MapboxDraw({ displayControlsDefault: false, controls: { polygon: true, trash: true } }); map.addControl(draw);
方案2:禁止Webpack压缩mapbox的dist文件
如果你一定要坚持引入dist版本,可以配置Terser插件,让它跳过对mapbox相关dist文件的压缩:
步骤1:安装Terser插件(如果没装的话)
npm install terser-webpack-plugin --save-dev
步骤2:修改Webpack配置
在生产配置的optimization.minimizer中添加排除规则:
const TerserPlugin = require('terser-webpack-plugin'); module.exports = { // ...其他配置 optimization: { minimizer: [ new TerserPlugin({ // 排除mapbox的dist文件,避免二次压缩 exclude: /mapbox-gl\.js$|mapbox-gl-draw\.js$/ }) ] }, // 可选:让Webpack不解析这些dist文件的内部依赖,提升构建速度 module: { noParse: /mapbox-gl\.js$|mapbox-gl-draw\.js$/ } };
步骤3:保持你的引入方式
继续使用dist版本的引入,但别忘了同时引入样式文件:
import mapboxgl from 'mapbox-gl/dist/mapbox-gl.js'; import MapboxDraw from '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.js'; // 引入样式 import 'mapbox-gl/dist/mapbox-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
方案3:直接引入库源码(避免dist版本)
如果之前你选择dist版本是因为源码引入有问题,其实可以尝试直接引入库的入口文件,同时确保Webpack能正确处理它的依赖:
import mapboxgl from 'mapbox-gl'; import MapboxDraw from '@mapbox/mapbox-gl-draw'; import 'mapbox-gl/dist/mapbox-gl.css'; import '@mapbox/mapbox-gl-draw/dist/mapbox-gl-draw.css';
这种方式下,Webpack会正常处理库的源码和依赖,只要你的Webpack配置支持处理CSS(比如用css-loader和style-loader/mini-css-extract-plugin),一般不会出现生产构建的错误。
内容的提问来源于stack exchange,提问作者PhilippeAuriach
相关产品推荐
相关产品推荐

