库模式下,dependencies、devDependencie

2023-02-08  本文已影响0人  科科Cole

首先是结论。devDependencies会使包被编译。比如你import something from 'something',如果somethingdevDependencies中,最终build出的产物是不会出现import something from 'something'的,something中用到的内容会被编译。而externaldependencies都会使包被保留,意思是如果你import something from 'something',那么最终build出的产物中import something from 'something'会被原样保留。externaldependencies的不同之处是,dependencies中的依赖会在你的包被安装的时候自动安装,而external中的包不会被自动安装,需要用户手动安装。

external只作用于打包阶段,使你在external中的包在最终生成的产物中不被编译;由于你发布npm包的时候package.json会被一起打包进去,所以dependencies会作用于以你的包为依赖的包。如果你使用的依赖既在external中,又没在dependencies中,最终用你包的人需要自己安装补全依赖。

至于什么时候会用到external,我想应该可以externaldevDependenciespeerDependencies一起使用。

以下是我的实验过程:


在这个示例中我创建了三个项目,一个是upstream-dependency(以下简称upstream),作为最顶层的依赖包;一个以upstream-dependency作为依赖的testing-dependency(以下简称testing);还有一个是依赖testing-dependencyclient-dependency(以下简称client),用来模拟最终使用的用户环境。都使用unbuild进行构建。

upstream中有一个dependencies依赖:
package.json

{
  ...
  "dependencies": {
    "vue": "^3.2.47"
  },
  ...
}

upstream有一个简单的导出:

import { createSSRApp, h } from "vue";
import { renderToString } from "vue/server-renderer";

export default renderToString(createSSRApp(h("div", "Hello World")));

最终build后的产物,以mjs为例,是这样的:

import { createSSRApp, h } from 'vue';
import { renderToString } from 'vue/server-renderer';

const index = renderToString(createSSRApp(h("div", "Hello World")));

export { index as default };

testing中只有简单的两行导出:

import appString from "upstream";

export default `${appString}test`;

首先我将upstream作为devDependencies安装,然后build,此时就有warning了。因为我的upstream实际上是在production环境中用到了,但是我放到了devDependencies中。而devDependencies中的依赖会被全部编译。可以通过设置{rollup:{inlineDependencies: true}}解决这个warning。此时再打包,可以发现打包的产物有8000多行,因为vue中与createSSRApphrenderToString相关的代码也被全部编译了。

8000多行的打包产物

如果在上一步,不设置{rollup:{inlineDependencies: true}},而是设置{external: ["upstream"]},再进行打包,最终产物是这样:

import appString from 'upstream';

const index = `${appString}test`;

export { index as default };

我们发布这个testing包,再在client中引入。然后去执行的时候发现报错了。因为upstream这个包没有在testingdependencies中出现,并且我们还将其作为external没打包进最终产物里,所以我们在client中引入的时候,是找不到upstream的,此时我们需要手动安装upstream包。我们在client中手动安装upstream,此时再去执行,可以发现执行成功了。


如果在上述步骤中,我们不添加external,再把upstream挪到dependencies中,再build,产物是这样:

import appString from 'upstream';

const index = `${appString}test`;

export { index as default };

可以发现,{external: ["upstream"]}{"dependencies": {"upstream": "^0.0.0"}}对最终打包产物的效果是一样的,都是使upstream作为外部依赖引入。此时我们再发布这个包,再在client中引入。这时我们可以成功运行,因为upstreamtesting作为dependencies引入了:

pnpm仓库
上一篇下一篇

猜你喜欢

热点阅读