Reputation: 100200
So I have the standard folder structure
dist/
src/
where src
has my .ts files and dist
has my .js files.
(I have "outDir":"dist"
in my tsconfig.json file, and "includes"
set to 'src'
).
Note that 'dist' is in my gitignore
file, so it is not in version control, and so when it goes to Travis or CircleCI
, nothing is in the dist
folder until I run tsc
.
Here is the problem - if I run npm install
first - it will fail because I have this in my package.json:
"bin":{
"foo" :"dist/cli.js" // dist/cli.js does not exist yet
}
but if I run tsc
first - tsc will then be missing dependencies that it needs for compilation, which arrive if I run npm install
.
The only thing I can think of to solve this, is to install all the necessary tsc
dependencies first, then run tsc, then run npm install --production
.
However that is not the most convenient thing to do.
Has anyone run into this problem and found a good solution?
Upvotes: 14
Views: 1087
Reputation: 2856
The answer from @wkrueger is close.
The goal here is to just allows a cheesy step to work without actually making it do anything useful. That cheesy step is making the file references by bin
executable, during the install step, which for a local module only makes sense for non-transpiled JavaScript, as for transpiled code the file won't exist yet. Luckily, this cheesy step doesn't actually care if the file is usable or not, it just needs it to exist so it can chmod
it without failure.
My work-around for this problem is to simply checkin an empty dist/index.js
file:
touch dist/index.js
Then add dist
back to .gitignore
as you don't want to checkin real builds of the file.
In NPM 6 I would have used a preinstall
script in package.json
but this has broken in NPM 7, which I happen to be using and I'm not super interested in converting to hooks just to work around this issue. If you are using NPM 6 or earlier the preinstall
script would look like this:
...
"scripts": {
"preinstall": "mkdir -p dist/ && touch dist/index.js"
}
...
Upvotes: 1
Reputation: 1373
Absolutely not your answer, but I usually just prefer to commit the javascript.
Downside: Tons of additional git history/bloat.
My points:
.d.ts
;Upvotes: 0
Reputation: 9509
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.
Upvotes: 4
Reputation: 1610
It looks like preinstall
script is what you need
Add in your package.json
file as
{
"scripts": {
"preinstall" : "tsc ..." // < build stuff
}
}
Reference https://docs.npmjs.com/misc/scripts
Upvotes: 2
Reputation: 4802
I don't remember having this problem but in at least one case I did something that will work around the issue.
I put an index.js in the root folder that runs the actual dependency in dist. Then the bin that npm looks for is a file that's present, and it shouldn't freak out.
It won't work until tsc is run, of course. But it should resolve your chicken and egg problem.
Upvotes: 4