背景

在《前端多个vue项目公共组件的三种方法(推荐npm file引入)》这一篇里讲了npm通过file方式引入公共包的方法,但在实际运用中,会遇到不少坑,这里就讲述笔者遇到的2个问题并给出解决方案。

问题一

通过file方式引入的包,npm不会自动安装该包的依赖。
例:项目A通过file方式引入了包B,如下所示。在
项目A的package.json:

{"name": "A","version": "0.1.0","dependencies": {"B": "file:../B"}//...
}

项目B的package.json:

{"name": "B","version": "0.1.0","dependencies": {"axios": "^0.19.2"}//...
}

如此在项目A中执行npm install时,不会安装axios包,node_modules中只有一个通过软链接引入的B。

解决方案

主要思路:

  • 增加一个webpack插件,DepPlugin,在entryOption hook,也就是webpack刚处理完配置项之后,执行插件。
  • 读取主项目package.json中dependencies中所有依赖,读取所有file引入npm包中dependencies中的依赖和版本号,两者取差集,也就是在file引入npm包中依赖的但主项目中没有的。
  • 一次性安装上述所得的所有依赖,执行npm install a@1.0 b@2.1 c@3.2 --no-save(a b c为依赖包名)。

以下是代码:
vue.config.js

chainWebpack: config => {const depPlugin = require('./plugin/DepPlugin')config.plugin('DepPlugin').use(depPlugin).tap(args => args)
}

DepPlugin.js

'use strict'
const path = require('path')
const sep = path.sep
let cwd = process.cwd()
const execSync = require('child_process').execSyncfunction DepPlugin (options) {this.options = options || {}this.done = false
}
DepPlugin.prototype.apply = function (compiler) {const that = thiscompiler.hooks.entryOption.tap('DepPlugin', compiler => {if(that.done) returnconst mainDependency = getDependency('.' + sep + 'package.json')// 假设有file引入了2个项目,baqi和baqi-chatlet subDependency = {...getSubDependency('baqi'),...getSubDependency('baqi-chat')}const subDependencyKey = Object.keys(subDependency)const mainDependencyKey = Object.keys(mainDependency)// 获取当前包中的依赖// 查找baqi,baqi-chat包中有的依赖,但主包中没有的for (let i = 0; i < subDependencyKey.length; i++) {if (mainDependencyKey.includes(subDependencyKey[i])) {delete subDependency[subDependencyKey[i]]}}// 安装这些依赖execCmdSync('cd ' + cwd)let str = ''for (let dep in subDependency) {// node_modules中没有这些包就安装if (fs.existsSync(path.join(cwd, 'node_modules' + sep + dep)) === false) {str += dep + '@' + subDependency[dep].replace(/\"|\^|\~/g, '') + ' '}}if (str) {execCmdSync('npm install ' + str + '--no-save')}})
}function getSubDependency (moduleName) {const filePath = path.join(cwd, '..' + sep + moduleName + sep + 'package.json')const dependencies = getDependency(filePath)return dependencies
}
function getDependency (packageJsonPath) {const fileObj = JSON.parse(readPackageJson(packageJsonPath))const dependency = fileObj.dependenciesreturn dependency
}
function readPackageJson (packageJsonPath) {const fileStr = fs.readFileSync(packageJsonPath, 'utf8')return fileStr
}
function execCmdSync (cmdStr) {console.log('执行:' + cmdStr)const out = execSync(cmdStr, { encoding: 'utf8' })return out
}

问题二

babel不会自动转义file引入的包,也就是子包中若有ES6写法,在低版本的浏览器中运行时会报错。

解决方案

vue官网这么描述的

所以,可以在vue.config.js中添加

transpileDependencies: [ /[/\\]node_modules[/\\]baqi[/\\]/,/[/\\]node_modules[/\\]baqi-chat[/\\]/
]

此问题同样适用与npm link

npm file方式引入公共包遇到的几个坑相关推荐

  1. maven引用公共包_maven怎么 引入(或引用/使用) 自定义(或本地/第三方) jar的三种方式 图文教程-Fun言...

    准备工作: jar包里的源码是: public class RegexUtils { /** * 验证Email * @param email email地址,格式:zhangsan@zuidaima ...

  2. Android Studio4.0引入arr包和jar包方式

    Android Studio升级到 4.0 并且gradle_plugin 也更新到4.0.0,之后引入jar包和arr包的方式有所变更. 一.第一种引入方式如下: 1.File -> New ...

  3. Thymeleaf引入公共片段方式

    引入公共片段 引入公共片段的th属性,包括三种方式 th:insert 将公共片段,整个插入到声明引入的元素中 th:replace 将声明引入的元素,替换为公共片段 th:include 将被引入的 ...

  4. Andriod开发中正确引入jar包的方式

    andriod中如果引入jar包的方式不对就会出现一些奇怪的错误. 工作的时候恰好有一个jar包需要调用,结果用了很长时间才解决出现的bug. 刚开始是这样引用的(eclipse): 右键工程,Bui ...

  5. Maven仓库理解、如何引入本地包、Maven多种方式打可执行jar包

    转载博客:http://quicker.iteye.com/blog/2319947 有关MAVEN仓库的理解参见:http://blog.csdn.net/wanghantong/article/d ...

  6. 基于 cz88 纯真IP数据库开发的 IP 解析服务 - 支持 http 协议请求或 rpc 协议请求,也支持第三方包的方式引入直接使用

    cz88 基于 cz88 纯真IP数据库开发的 IP 解析服务 - 支持 http 协议请求或 rpc 协议请求,也支持第三方包的方式引入直接使用 Go 语言编写 进程内缓存结果,重复的 ip 查询响 ...

  7. IDEA手动引入jar包方式

    IDEA手动引入jar包 第一种方式,使用idea自带的功能引入.注意本地开发可以,但项目打成jar包时因未添加进去导致打包报错或打包成功启动失败 最后一次性选择(选中第一个,按住shift键,点击最 ...

  8. Rust引入外部包,VsCode引入失败,Blocking waiting for file lock on package cache lock

    引入外部包出错的解决方法 VsCode导入包后一直转圈 首先要停掉Rust server Ctrl + Shift + P 快捷键,输入Stop那个,停掉服务 改用命令行,像这样 可以看到它说 Blo ...

  9. golang 引入外部包的三种方式:go get, go module, vendor目录

    import "github.com/astaxie/beego" 编译出错解决方案: go get:确保你的GOPATH是工程目录,代码在src目录下,然后在命令提示符中输入:g ...

最新文章

  1. SQL Date 函数
  2. Asp.Net.Core 系列-中间件和依赖注入进阶篇
  3. 复制内存时检测到可能的io争用条件_这篇高并发服务模型大科普,内部分享时被老大表扬了...
  4. 八年技术加持,性能提升10倍,阿里云HBase 2.0首发商用
  5. 【学习笔记】SAP CO模块概念信息(上)
  6. 【线上直播】:5G时代VR+8K直播 刷新你的视界认知
  7. 如何修改浏览器服务器时间格式,浏览器模式怎么改模式
  8. Unity中的SystemInfo.deviceUniqueIdentifier 唯一ID
  9. python装饰器有几种_Python装饰器使用你可能不知道的几种姿势
  10. 基于双二阶广义积分器(DSOGI)的软件锁相环需求的根源及s域仿真
  11. 苏宁易购:苏宁小店将获4.5亿美元增资
  12. 符号_特殊符号大全狐狸符号加字和复制
  13. 数学分析-换底公式证明
  14. 5G网络身份识别---详解5G-GUTI
  15. 010-WebBuilder-编写可复用模块+阶段实战效果与代码
  16. ESP8266 上电 boot 模式
  17. python函数编写脚本
  18. 服务器系统壁纸,云服务器壁纸
  19. 【C++】利用Unicode控制字符-RLO构造欺骗性文件后缀
  20. Python学习初衷、心得

热门文章

  1. 部署ebe-shop商城系统(使用IDEA克隆Git项目)
  2. Android Notification详解
  3. SVN的服务器端与客户端的下载,安装以及在IDEA中的简单使用
  4. burpsuite小米手机抓包_burpsuite小米手机抓包_Fiddler抓包实用非常详细
  5. 图 最短路 Dijkstra 迪杰斯特拉算法
  6. Javascript函数节流 —— How To Use Throttle
  7. java自学:MySQL
  8. coreldraw矫正两张图_利用CorelDRAW矫正图像
  9. 将小米平板2从低版本安卓适配到高版本的若干收获与思考
  10. word文档(office)打钩处无法打钩的两种解决办法