最近在给隔壁组做项目拆分,将几个项目的通用部分拆出来成为独立的资源项目
原理是通过npm install 的时候 ,允许设置为本地文件
npm i dep@file:../dep
这样就能在项目中引用一个本地的类库--公司的版本库还是老掉牙的svn
这样就能通过公共的资源项目来管理公共模块,其他业务性的项目就能简单的引用了一下,当公共资源项目修改了之后,业务项目只需要简单的update
一下就好了
理想很丰满,现实比较残酷
首先确实以前几乎没怎么用过webpack,都是什么vue-cli之类的直接初始化好,直接用,也没管过这东西具体是怎么配置的
更别提写一个library了
首先我们的项目是被拆成三部分:业务项目,公共代码部分,公共UI组件部分
公共代码起个名字:ts-dep
公共代码部分会同时被UI和业务项目引用
公共代码部分比较简单,一个中规中矩的npm package
项目,当然我们的项目用的ts,也让我折腾了一下,这一块就不说了
最后得到这样一个项目结构
package.json文件内容
{
"name": "ts-dep",
"version": "1.0.0",
"description": "",
"main": "./lib/index.js",
"typings": "./lib/index.d.ts",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC"
}
UI组件起个名字: v-com-dep
在index.js
中有如下代码
import tsDep from 'ts-dep';
在UI组件中,首先遇到的问题是:
这个项目ts依赖不能被打包进来
这个查一查,都是说用 externals 配置一下就好了
官网文档也没写清楚,就说配置一下这个
结果我按照官网的实例配好之后,得到一个
module.exports = undefined
运行的时候一直报错
最后发现这东西得跟 output
选项配合好
如下代码:libraryTarget 设置成什么,底下的externals就会取对应的选项来进行require
output: {
path: resolve('./dist'),
filename: 'index.js',
libraryTarget: 'commonjs2',
globalObject: 'this',
// libraryExport: 'default',
library: 'v-com-dep'
},
//.....
externals: {
'ts-dep': {
commonjs: 'ts-dep',
commonjs2: 'ts-dep'
},
lodash: {
commonjs: 'lodash',
commonjs2: 'lodash'
}
},
这样配置之后,就能在编译出来的代码中看到对应的模块由
module.exports = undefined
变成了
/* 6 */
/***/ (function(module, exports) {
module.exports = require("ts-dep");
/***/ }),
//....... 和
/* 8 */
/***/ (function(module, exports) {
module.exports = require("lodash");
/***/ })
第一步搞定了
现在开始搞第二步:在业务项目中调用这两个模块
业务项目也起个名字: deps
那么deps/package.json
中就有两个依赖
{
"dependencies":{
"ts-dep": "file:../ts-dep",
"v-com-dep": "file:../v-com-dep",
}
}
在index.js中有以下代码
import tsDep from 'ts-dep';
import vComDep from 'v-com-dep';
结果这个配置,打包出来之后
ts-dep被引入了两次!!!
查看打包出来的文件
很明确,同一个包引入了两次,分别给的ID是'WQi9'和'/wiT1'(这个反正不固定,是这个意思就行)
我当场就哭了,尼玛折腾了这么久,给我两份算怎么回事?
代码体积都是小事,问题是两边的状态不统一!这个很坑啊
我项目里需要设置状态的,不互通的话我怎么设置?
在通用项目里头有一个上传图片的公共组件,允许设置上传图片是否开启压缩,但是对应的界面组件又在UI组件里头
我现在引用资源项目设置了不允许压缩,结果UI项目读不到,我还要这个有啥用??
恨死了。。。。。
但是自己挖的坑,怎么着也得走出来不是?
继续吧,从网上的一些现有的类库入手,比如element-ui
,这里面有个peerDependency:vue
看看这个会不会打包两次。。。当然不会啦
所以看看这个破玩意儿跟我的配置有啥区别?结论是没有。。。
我再哭会去。。。
再去研究一下webpack官方提供的library demo,是不是我漏掉了什么东西?
研究了几个小时,结论是没有,我直接把官网的例子clone下来到本地,一样会在最终打包文件中出现两个lodash
难不成天要亡我???
朕的天下保不住了?
仔细看看这两份打包出来的内容吧,貌似是一毛一样的。。。
稍等,这个是lodash的源码,前面的说明里头有一行(我把压缩关了,可以直接看打包出来的源码,webpack@4配置mode:'none',webpack@3将uglifyplugin那一段关掉就好了)
/*
* Lodash
*/
但是两份差一个字母,另外一份长这个样子
/*
* lodash
*/
一个是大写的L,一个是小写的l
如果是同一份代码出来的,怎么会差一个字母呢??
所以只能说明这里是两份代码!!
为什么会有两份代码呢?
看看代码好了,结果,我发现:在deps的node_modules下有一个lodash,在node_modules/v-com-dep/node_modules下还有一个lodash,且两个lodash刚好就是差一个字母!
deps
node_modules
lodash * Lodash
v-com-dep
node_modules
lodash * lodash
至此,此案告破,就是因为本地安装的时候,yarn直接将整个目录拷进去了(npm 会做一个类似快捷方式的东西放进去,结果是一样的)
把 v-com-dep/node_modules
目录删掉(我这里没有其他依赖,可以删掉)就好了(至于为什么我就不解释了,之前确实没想到会是这里的问题)
看来在开发本地程序的时候,还得像个办法来解决一下这个安装问题。
这个就是小问题了,问题原因找到了~~~~