问题描述

最近一直再用leaflet在做地图相关的,leaflet是什么?leaflet是一个轻量级的地图客户端,本来以前用google的javascript库的,后来google被那啥了,才改用这个库的,感觉还蛮不错的。grunt是一个非常优秀的构建工具,组成有Yeoman一套工具及,酷爆了。
在项目中引用了很多的js文件。
下面的是grunt编译压缩js代码的标记,我只是照着人家的用而已。

<!--build:js xxxxxx-->
<!--endbuil-->

我引用的主要代码如下

  <!-- build:js scripts/components.min.js -->
    <!-- bower:js -->
    <script src="bower_components/jquery/dist/jquery.min.js"></script>
    <script src="bower_components/angular/angular.min.js"></script>
    <script src="bower_components/leaflet/dist/leaflet.js"></script>
    <script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
    <!-- endbower -->
  <!-- endbuild -->

    <!-- build:js scripts/lmap.plugin.min.js -->
    <script src="scripts/L.TileLayer.A.js"></script>
    <script src="scripts/Control.MiniMap.js"></script>
    <script src="scripts/Leaflet.draw.js"></script>
    <script src="scripts/leaflet.layerindex.js"></script>
    <script src="scripts/json2.js"></script>
    <script src="scripts/rtree.js"></script>
    <script src="scripts/leaflet.ajax.js"></script>
    <!-- endbuild -->

我在我自己机器上测试完全没问题,然后我由于当时需要急用,我草草的测试了一下,然后就

grunt build

把生成的那个dist文件夹发布出去了。。。。
第二天,我被上司批评了一大顿,因为我昨天发布出去的站点有问题,执行到某个功能的时候就出错了。我一看 出错了都吓傻了,各种猜测问题从哪里出来的。

查错

问题出来了我这是肯定跑不掉的。firebug看一下错出来哪里,发现是adfsafa.components.min.js这个脚本抛出异常了Couldn't autodetect L.Icon.Default.imagePath, set it manually.我就想为啥我在开发的时候毛线问题没有,这压缩打包发布之后就给我出了这么大的问题了,既然冤有头,债有主,只能去找问题了。
看了一下leaflet的源代码,
抛出异常的代码段

function(name) {
            var key = name + 'Url';
            if (this.options[key]) {
                return this.options[key];
            }
            if (L.Browser.retina && name === 'icon') {
                name += '-2x';
            }
            var path = L.Icon.Default.imagePath;
            if (!path) {
                throw new Error('Couldn\'t autodetect L.Icon.Default.imagePath, set it manually.');
            }
            return path + '/marker-' + name + '.png';
        }

很明显是path为null才抛出异常,继续找到L.Icon.Default.imagePath

L.Icon.Default.imagePath = (function() {
        var scripts = document.getElementsByTagName('script'),
            leafletRe = /[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;
        var i, len, src, matches, path;
        for (i = 0, len = scripts.length; i < len; i++) {
            src = scripts[i].src;
            matches = src.match(leafletRe);
            if (matches) {
                path = src.split(leafletRe)[0];
                return (path ? path + '/' : '') + 'images';
            }
        }
    }());

看了半天,发现这货居然是靠正则匹配名字包含leaflet***.js去获得一个文件路径,从而给我返回一个path保守估计这个返回的是个空才引发异常抛出。当然也通过断点调试的方法确认了问题就是这个就是因为没匹配到东西才引发的血案。

grunt打包的时候,会把<!-- build:js scripts/lmap.plugin.min.js --><!--endbuild-->
代码段合并在一起并重命名一下。
问题就出在我压缩后发布后,script标签匹配不到leaflet***.js,才引发了这个抛出异常导致我的代码无法继续正常工作的血案。

应急解决

也没时间去思考该怎么彻底解决这个问题,临时解决一下了。我把leaflet的代码加了一句

 if (matches) {
                path = src.split(leafletRe)[0];
                return (path ? path + '/' : '') + 'images';
            }
    return '我该给他的路径';

教训

首先,解决这样的问题的时候,原则上不应该去修改这个库,而是先试着在我的代码中去修正这个问题的影响,因为我项目依赖管理是依靠bower来做的,我这里只是应急一下。
然后,我发布代码之后测试不够充分,很明显的问题因为仓促发布而没发现,这当然是我的失职。(其实这问题是我现在遭遇的最大的问题,这个项目现在由我开发测试发布,而且没有文档和明确的需求,又扯到伪需求的问题上去了)。
这个问题倒是让我重视到了测试的重要性了,grunt完全是正常使用,leaflet也是正常的使用,我也是按照套路在做开发,但是遇到一起了就是给我出这个问题了。写代码的时候遇到坑其实不是我们不小心引入的,而是上游之间可能出现冲突。


MingjunYang
290 声望5 粉丝

一切从〇开始……


引用和评论

0 条评论