zoukankan      html  css  js  c++  java
  • webpack配置别名alias出现的错误匹配

    @(webpack)

    webpack是一款功能强大的前端构建工具,不仅仅是针对js,它也可通过各种loader来构建相关的less,html,image等各种资源,将webpack配合流程制定工具gulp结合起来,则更为方便的自定义工作流程。


    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)
    
  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    阿里巴巴的零知识证明
    DPOS委托权益证明 vs POW工作量证明
    DPOS共识算法 -- 缺失的白皮书
    信息图:股份授权证明机制(DPOS)
    DPOS——回归中本聪
    深度解析POS和POW的区别
  • 原文地址:https://www.cnblogs.com/accordion/p/5104426.html
Copyright © 2011-2022 走看看