webpack配置別名alias出現的錯誤匹配

jopen 8年前發布 | 17K 次閱讀 前端技術 webpack

<p>@(webpack)</p>

webpack是一款功能強大的前端構建工具,不僅僅是針對js,它也可通過各種loader來構建相關的less,html,image等各種資源,將webpack配合流程制定工具gulp結合起來,則更為方便的自定義工作流程。

[TOC]

webpack的alias匹配問題初現

在webpack.config.js中,通過設置resolve屬性可以配置查找“commonJS/AMD模塊”的基路徑,也可以設置搜索的模塊后綴名,當然,最后一個就是我們要講的別名alias設置。

跟蹤問題

在模塊開發過程中,我們可能會對可以復用的組件封裝成一個可被git管控的模塊,并在引用的過程中采用 帶版本號的方式引用 ,這就要求我們在webpack.config.js中添加相關alias配置,如

...
module.exports = {
    entry: {
        main: 'index.js'
    },
    output: {
        path: 'build'
        filename: '[name].js'
    },
    resolve: {
        root: 'modules'
        alias: {
            'mod/slider': '/path/mods/mod/slider/0.0.5',
            'mod/footer': '/path/mods/mod/footer/0.0.2',
            'mod/slider/0.0.3': '/path/mods/mod/slider/0.0.3',
            'mod/header': '/path/mods/mod/header/0.0.1',
            'mod/slider/0.0.1': '/path/mods/mod/slider/0.0.1'
        }   
    }
}

有一個簡單的需求,即在index.js中,可這樣引用:

var slider = require('mod/slider');
var sliderV3 = require('mod/slider/0.0.3');
var sliderV1 = require('mod/slider/0.0.1');

結果和我們預想的會有不同,webpack的別名處理邏輯會使這三個變量的引用都為 slider 這個變量所對應的模塊,要想解決這種情況,只能深入源碼。

深入源碼之ModuleAliasPlugin

先貼上部分源碼:

    var aliasMap = this.aliasMap;
    resolver.plugin("module", function(request, callback) {
        var fs = this.fileSystem;
        var keys = Object.keys(aliasMap);
        var i = 0;
        (function next() {
            for(;i < keys.length; i++) {
                var aliasName = keys[i];
                var onlyModule = /\$$/.test(aliasName);
                if(onlyModule) aliasName = aliasName.substr(0, aliasName.length-1);
                if((!onlyModule && request.request.indexOf(aliasName + "/") === 0) || request.request === aliasName) {
                    var aliasValue = aliasMap[keys[i]];
                    if(request.request.indexOf(aliasValue + "/") !== 0 && request.request != aliasValue) {
                        var newRequestStr = aliasValue + request.request.substr(aliasName.length);
                        var newRequest = this.parse(newRequestStr);
                        var obj = {
                            path: request.path,
                            request: newRequest.path,
                            query: newRequest.query,
                            directory: newRequest.directory
                        };
                        var newCallback = createInnerCallback(callback, callback, "aliased with mapping " + JSON.stringify(aliasName) + ": " + JSON.stringify(aliasValue) + " to " + newRequestStr);
                        if(newRequest.module) return this.doResolve("module", obj, newCallback);
                        if(newRequest.directory) return this.doResolve("directory", obj, newCallback);
                        return this.doResolve(["file", "directory"], obj, newCallback);
                    }
                }
            }
            return callback();
        }.call(this));

這段簡單的代碼所做的就是針對別名做映射,獲取到對應的模塊。之所以出現上節的問題,就是因為這句判斷

if(request.request.indexOf(aliasValue + "/") !== 0 && request.request != aliasValue)

webpack的作者貌似有些多此一舉了,或者說是在我們的應用場景中并沒有考慮到,所以僅僅針對這個判斷進行修改就可以滿足需求。修改非常簡單,進行嚴格相等的判斷:

if(request.request != aliasValue)

來自: http://www.cnblogs.com/accordion/p/5104426.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!