问题描述
多个项目,为了开发方便,不同项目中的模块存在相互引用。开发工具初始用的是Visual Studio Code 1.39.2
版本,之前打包运行都是正常,但是当Visual Studio Code
从1.39.2
升级到1.52.1
,发现引用部分模块功能不可用,问题主要体现在axios
与vue
封装插件中,部分修改变量获取不到修改后的值。
问题原因
初步定位问题原因为,不同项目之间公共包作用域不同,npm
默认是查找规则为以当前package.json
为基准,从同目录下的node_modules
开始,如果没有找到依赖文件,逐步向上查找,直至查到至全局的node_modules
上。如果项目2引入项目1中api
,项目1中存在axios
,则查找的就是项目1中,项目1中没有,才会查找项目2中的axios
,两者都有,就各找各的。
V1.39.2
的版本为何能正常解析?
1.39.2
版本的Visual Studio Code
中,我们默认增加了"npm.enableScriptExplorer": true
配置,这个配置的主要功能为查找依赖包时,默认要查找至最顶层的package.json
中的依赖包 && 显示侧边栏npm scripts
,即在项目1中引用了项目2中的一个模块,项目2中引入了vue.js
,项目1中也引入了vue.js
,则顶层package.json
是在项目1中,最后查找到的package.json
也在项目1中,所以功能可正常使用,否则则不行。
1.52.1
中,npm
插件中废除了此项配置,NPM:auto Detect
可以控制侧边栏npm scripts
的显示。因此会导致打包结果依赖分离,APP
运行异常。
实际上,目前开发引用模块的方式本质就是错的,只是误打误撞,碰巧以为是对的。归根结底,还是npm引用包查询方式与ES6模块机制理解不够透彻!
解决办法
Webpack
中可以固定关键包的查找作用域,引用其他APP模块,对于公共依赖可以配置别名alias,指定查找路径,如下所示:
configureWebpack: {
resolve: {
alias: {
'axios': path.resolve(__dirname, './node_modules/axios/')
}
}
}
- 将公共模块封装成插件,需要依赖以参数的形式注入
export default function (Vue) {
// vue相关插件代码
// xxxx
}
建议不同模块间包的引用最好不要掺杂第三方依赖。
延伸阅读
ES6
模块(import/export
)机制原理是新导入的包,是对原有包模块的一种引用,原有包数据的改变,会反应到引用的包里。所以在相同项目中,不同地方都导入了axios
,有一个地方改变了axios.defaults.baseURL
,其他地方虽然导入的是axios
包,但是修改的默认地址仍然会获取到。CommonJS
模块(require/module.exports
)规范是导入的包,是对原有包的值的拷贝,原有包的模块内容改变,不会反应到导入的文件中。