如何使用`tsc`和`npm install`解决Chicken / Egg情况?

时间:2018-05-31 03:36:23

标签: node.js typescript npm npm-install tsc

所以我有标准的文件夹结构

dist/
src/

其中src包含我的.ts文件,dist包含我的.js文件。 (我的tsconfig.json文件中有"outDir":"dist",而"includes"设置为'src')。

注意,' dist'在我的gitignore文件中,因此它不在版本控制中,所以当它转到Travis或CircleCI时,dist文件夹中没有任何内容,直到我运行tsc

以下是问题 - 如果我先运行npm install - 它会失败,因为我在package.json中有这个:

"bin":{
  "foo" :"dist/cli.js"   // dist/cli.js does not exist yet
}

但是如果我首先运行tsc - 那么tsc将缺少编译所需的依赖项,如果我运行npm install则会到达。

我能想到的唯一的事情是先安装所有必需的tsc依赖项,然后运行tsc,然后运行npm install --production

然而,这不是最方便的事情。

是否有人遇到此问题并找到了一个很好的解决方案?

5 个答案:

答案 0 :(得分:4)

我不记得遇到这个问题,但至少在一个案例中,我做了一些可以解决这个问题的事情。

我将index.js放在根文件夹中,该文件夹运行dist中的实际依赖项。然后npm寻找的bin是一个存在的文件,它不应该被吓坏。

当然,直到tsc运行它才会工作。但它应该解决你的鸡和鸡蛋问题。

答案 1 :(得分:3)

看起来preinstall脚本就是您需要的

package.json文件添加为

{
  "scripts": {
    "preinstall" : "tsc ..." // < build stuff
  }
}

参考https://docs.npmjs.com/misc/scripts

答案 2 :(得分:3)

I would check-in a file ./lib/cli the file contents are

#!/usr/bin/env node
require('../dist/cli.js')

and just run npm normally followed by tsc.

答案 3 :(得分:0)

绝对不是你的答案,但我通常只是喜欢提交javascript。

下行:额外的git历史/膨胀。

我的观点:

  • 最后,您正在制作一个javascript项目。所以应该测试javascript运行时,如果该项目也应该从typescript中使用,那么测试生成的.d.ts;
  • 生成代码的TSC版本不应该是测试和消费者的另一个移动部分。您将测试生成的输出,而不是许多TSC版本的源。
  • 通过包含.js和.d.ts减少“活动部分”边界,你获得的收益(=可预测性)远远超过你失去的(git history膨胀)。

答案 4 :(得分:0)

@wkrueger 的答案很接近。

这里的目标是只允许一个俗气的步骤工作,而不实际让它做任何有用的事情。这个俗气的步骤是在安装步骤中通过 bin 可执行文件引用,这对于本地模块仅对非转译的 JavaScript 有意义,而对于转译的代码,该文件尚不存在。幸运的是,这个简单的步骤实际上并不关心文件是否可用,它只需要它存在,这样它就可以chmod它而不会失败。

我解决这个问题的方法是简单地检入一个空的 dist/index.js 文件:

touch dist/index.js

然后将 dist 添加回 .gitignore,因为您不想签入文件的真实版本。

在 NPM 6 中,我会在 preinstall 中使用 package.json 脚本,但这在 NPM 7 中被破坏了,我碰巧正在使用它,我对转换为钩子不太感兴趣,只是为了解决这个问题。如果您使用的是 NPM 6 或更早版本,preinstall 脚本将如下所示:

  ...
  "scripts": {
    "preinstall": "mkdir -p dist/ && touch dist/index.js"
  }
  ...