在开发若干个有相互依赖关系的库的时候,通常都会采用 symlink 的方式互相引用,比较典型的一种场景就是使用 lerna 开发多个 package 。

lerna 简介

lerna 是用于管理拥有多个 package 的 JavaScript 项目,其典型目录结构为

lerna-repo/packages/package1/package.jsonpackage2/package.jsonpackage.jsonlerna.json

packages 目录下面就是各个 package 了。

lerna 有两个比较常用的命令:

lerna clean
lerna bootstrap

lerna clean 用于清理 packages ,会删掉各个 package 下面的 node_modules 目录。

lerna bootstrap 用于处理各个 package 的依赖,处理步骤为:

  1. 在每个 package 下面执行 npm install

  2. 根据各个 package 下 package.json 里面的 dependencies 和 devDependencies 配置,使用 symlink 在各个 package 的 node_modules 下面建立引用关系。

  3. 在每个 package 下执行 npm run prepublish

  4. 在每个 package 下执行 npm run prepare

symlink 的问题

假设 package 下面有一个包 pkg1 ,依赖 package 下面的另一个包 pkg2

运行 lerna bootstrap 之后, pkg1/node_modules 下就会出现 pkg2 的 symlink 。

如果使用 webpack 系列工具来编译运行 pkg1 ,由于 webpack loader 判断路径默认是按照真实路径来的,所以 pkg2 对应到的路径是 [project root]/package/pkg2 ,而不是 [project root]/package/pkg1/node_modules/pkg2

这样一来,如果需要 pkg2 中的源码过 pkg1 的 loader (比如 pkg2 中的 ES6 代码过 pkg1babel-loader),就需要在 webpack 相应 loader 配置中加上这个特殊的路径匹配,这和不涉及 symlink真实场景存在较大差异。

同时,很多配置(比如 postcssrcbabelrceslintrc 等)是以 resolve 到的文件去解析的,比如要用 babel 编译 pkg2 下面的 [project root]/package/pkg2/src/Dialog.es6 源码,会按照如下目录顺序查找 babelrc 配置:

[project root]/package/pkg2/src/
[project root]/package/pkg2/
[project root]/package/
[project root]/
...

而此时很可能希望能在 [project root]/package/pkg1/ 目录下寻找 babelrc 配置。

所以此时其实很希望 webpack loader 基于 symlink 的路径去解析判断 include / exclude 等配置,而不是按照真实文件的路径。

resolve.symlinks

webpack 提供了 resolve.symlinks 来解决这个问题,具体参见官方文档。

新的问题

虽然使用 symlink 解决了基准路径的问题,但是还存在另外的问题。

如果 pkg2 依赖了 babel-runtime ,那么在 pkg1 的配置中就要注意不要让 babel-runtimebabel-loader 了,不然 babel 可能会在 babel-runtime 的源码里面插入一些 ES6 的代码。

如果 pkg1pkg2 同时依赖了第三方模块 externalPkg3 ,那么在 lerna bootstrap 之后,会存在两个 externalPkg3

[project root]/package/pkg1/node_modules/externalPkg3
[project root]/package/pkg1/node_modules/pkg2/node_modules/externalPkg3 -> [project root]/package/pkg2/node_modules/externalPkg3

externalPkg3 里面有个 module 提供了全局的 object :

const obj = {};export function register(name, value) {obj[name] = value;
}export function getValue(name) {return obj[name];
}

此时 pkg1pkg2 会用各自的 obj 对象,如果 pkg1 中想用 pkg2 注册进去的 value ,就会拿不到。

可以考虑在 lerna.json 中配置 commands.bootstrap.ignore["pkg2"] ,在 lerna bootstrap 的时候不安装 pkg2 的依赖,使得最终只会有一个 externalPkg3

[project root]/package/pkg1/node_modules/externalPkg3

这种方式肯定不会是万能的,具体怎么做还要看真正的场景,可能还得各种配置互相配合才能解决问题。

当 webpack 遇上 symlink相关推荐

  1. 推荐系统遇上深度学习,9篇阿里推荐论文汇总!

    作者 | 石晓文 转载自小小挖掘机(ID: wAIsjwj) 业界常用的推荐系统主要分为两个阶段,召回阶段和精排阶段,当然有时候在最后还会接一些打散或者探索的规则,这点咱们就不考虑了. 前面九篇文章中 ...

  2. 华为平板电脑_当5G遇上平板电脑,华为MatePad Pro 5G带来了什么?

    5G已经来临,科技产品向5G升级已是大势所趋,这更是检验实力的探索之路. 2月24日,华为在巴塞罗那在线发布了一系列新品,其中,华为面向全球推出的5G高端旗舰平板,同时也是全球首款公开发布的5G平板华 ...

  3. 404未找到是什么意思_为什么老遇上404 not found?你懂的

    文章转载自公众号:一只学霸(bajie203) 昨天晚上 大毛火急火燎地打开了电脑 戴上了耳机 不到两分钟 -- 我们往前一凑 登等 果然是大家最害怕的一幕出现了 学霸在网上冲浪多年 留下的都是美好的 ...

  4. 《当用户体验设计遇上敏捷》一3.5 小结

    本节书摘来自异步社区<当用户体验设计遇上敏捷>一书中的第3章,第3.5节,作者[英]Lindsay Ratcliffe , Marc McNeill,更多章节内容可以访问云栖社区" ...

  5. 当网络安全遇上大数据分析(9)

    2012年3月份,Gartner发表过一篇报告--Information Security Is Becoming a Big Data Analytics Problem .里面主要就讲到了针对大规 ...

  6. html实体编码遇上js代码

    单双引号 在js代码中 在js中单.双引号引起来的是字符串,如果我们要在字符串中使用单.双引号,需要反斜杠进行转义 let str='user\'s name'; // or let str=&quo ...

  7. SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败解决方案

    SQL SERVER 2008 R2 SP1更新时,遇上共享功能更新失败的问题,可作如下尝试: 更新失败后,在windows的[事件查看器→应用程序]中找到来源为MsiInstaller,事件ID为1 ...

  8. 当微信小程序遇上TensorFlow:Server端实现补充

    在前面一篇文章<当微信小程序遇上TensorFlow:Server端实现>中,我们探讨了微信小程序server端的实现.今天在调试微信小程序时才发现一个问题,那就是:微信小程序要求HTTP ...

  9. webpack项目上传云服务器,webpack项目上传云服务器

    webpack项目上传云服务器 内容精选 换一换 为了避免不必要的费用产生,完成本示例体验后,可释放以下资源.资源释放后无法恢复,请谨慎操作.项目是使用DevCloud各服务的基础,删除项目可将该项目 ...

最新文章

  1. 测量接线导通问题解决方案
  2. MINIGUI 开发指南---GDI
  3. 软件测试框架课程考试_那考试准备课程值得吗?
  4. Android系统的开机画面显示过程分析
  5. Intel MKL 多线程设置
  6. socket异步处理问题
  7. atexit()函数(进程退出函数,类似析构)
  8. MySQL数据的重复处理
  9. python 主线程_Python threading多线程模块
  10. Tomcat6.0连接器源码分析3
  11. OMS智能订单管理系统
  12. dolphinscheduler 2.0.4 PIGEON任务使用的一次尝试
  13. 已知从1970年1月1日0分0秒到目前的总秒数计算当前时间
  14. 机器人搬运码垛工作站
  15. 每日分享,三款纯jquery移动端日期时间选择插件
  16. 《持续集成实践指南》第1章 DevOps实践简介
  17. Auto.JS简介与教程
  18. 我们能从后验分布中学到什么?贝叶斯后验的频率解释
  19. linux能运行安卓模拟器吗,Android模拟器的使用方法(Linux)
  20. c语言 ll1文法实验报告,C语言文法 LL(1)文法

热门文章

  1. mysql 改列定义_如何更改MySQL列定义?
  2. react开发公众号踩坑日志
  3. jenkins自动打包报错:cannot find symbol
  4. C_sharp-gives-OJ-background-test-data
  5. R语言|导入excel数据
  6. ZYNQ学习笔记PS部分【基本介绍】
  7. 使用tvp.player_v2_zepto.js播放腾讯视频
  8. 安卓玩机搞机-----没有第三方包 刷写第三方各种GSI系统 体验非官方系统
  9. 【webrtc0419 点对点视频聊天功能】
  10. 学习方法推荐——时间管理