vercel / ncc

Compile a Node.js project into a single file. Supports TypeScript, binary addons, dynamic requires.
https://npmjs.com/@vercel/ncc
MIT License
9.27k stars 292 forks source link

[TypeScript] Does not work with project references #320

Open screendriver opened 5 years ago

screendriver commented 5 years ago

I try to deploy one of my TypeScript projects to ZEIT Now and get a lot of Module build failed (from (webpack)/ncc/loaders/ts-loader.js): errors.

Could it be that I'm getting these errors because I'm using project references? Or is this somehow related to #291?

My tsconfig.json file looks like this:

{
  "files": [],
  "references": [
    { "path": "./src/one" },
    { "path": "./src/two" },
    { "path": "./test/unit/one" },
    { "path": "./test/unit/two" }
  ]
}

(every of these directories contain a separate tsconfig.json with composite set to true).

I'm not sure if this is related to zeit/now-builders or to ncc 🤔

styfle commented 5 years ago

@screendriver Can you try to reproduce this bug with the latest ncc?

npm install -g @zeit/ncc
ncc build src/one/index.js # assuming this is the entry point
node dist/index.js
screendriver commented 5 years ago

I'm not using ncc directly. I'm using it indirectly via the ZEIT Now builder @now/node

Or does @now/node just use this under the hood and this call is almost the same that the builder would do?

styfle commented 5 years ago

Since I don't have your source code, I can't reproduce the bug.

So that's why I'm asking you to run ncc in your project and see if you get an error.

Or does @now/node just use this under the hood and this call is almost the same that the builder would do?

Basically yes and many sources of errors in @now/node is caused by ncc or an improper now.json configuration.

screendriver commented 5 years ago

@screendriver Can you try to reproduce this bug with the latest ncc?

ncc version 0.16.1 produces

ncc: Using typescript@3.3.4000 (local user-provided)
Error: Hash: 12a2a6b144c58b5cdcbb
Version: webpack 5.0.0-alpha.9
Time: 1608ms
Built at: 03/21/2019 9:38:02 PM
           Asset       Size  Chunks  Chunk Names
        index.js   1.71 KiB   {404}  main
    mongodb.d.ts  190 bytes
mongodb.d.ts.map  308 bytes
Entrypoint main = index.js
[823] ./src/one/index.ts 380 bytes {404} [built] [failed] [2 errors]

ERROR in ./src/one/index.ts
Module build failed (from ./node_modules/@zeit/ncc/dist/ncc/loaders/ts-loader.js):
Error: TypeScript emitted no output for /Users/me/project/src/one/index.ts.
    at makeSourceMapAndFinish (evalmachine.<anonymous>:1:2894210)
    at successLoader (evalmachine.<anonymous>:1:2893770)
    at Object.loader (evalmachine.<anonymous>:1:2892441)

ERROR in /Users/me/project/src/one/index.ts
./src/one/index.ts
[tsl] ERROR in /Users/me/project/src/one/index.ts(7,28)
      TS6305: Output file '../two/foo' has not been built from source file '/Users/me/project/src/two/foo.ts'.

    at compiler.close.n (evalmachine.<anonymous>:3:1349875)
    at _promise0.then._result0 (eval at create (evalmachine.<anonymous>:1:349386), <anonymous>:13:1)
    at processTicksAndRejections (internal/process/next_tick.js:81:5)
error Command failed with exit code 1.

Should I create a test repository for you?

By the way: I saw in the output that you are using ts-loader internally. As far as I know ts-loader doesn't support project references completely. At the moment my workaround is to build my project "manually" with tsc --build and let the Zeit builder run against my output dist directory.

styfle commented 5 years ago

@screendriver Yes, an example repository (preferably the smallest possible) would be of great help!

At the moment my workaround is to build my project "manually" with tsc --build and let the Zeit builder run against my output dist directory.

That sounds painful.

One solution you might try is change your now.json to something like the following:

{
  "builds": [
    { "src": "src/one/index.ts", "use": "@now/node-server", "config": { "bundle": false } }
  ]
}

You would also have to add the listen(3000) in your index.ts file to use this builder but it would circumvent ncc bundling.

screendriver commented 5 years ago

@styfle I created a very very small repository where you can reproduce it easily 😉

styfle commented 5 years ago

@screendriver Thank you!

So this issue is currently blocked on the upstream ts-loader (as you mentioned earlier). And ts-loader is blocked on typescript because the builder API is not exposed yet 😮

Related Issues

screendriver commented 5 years ago

:scream:

Oh, that's sad... Project references are really great and I don't understand why they are not so much used out there. But ok, so we have to wait. Should we keep this issue open until it's fixed?

styfle commented 5 years ago

It looks like ts just added support for tsc --build and --incremental

Now we need this to land it ts-loader

cc @guybedford

anthonyshort commented 5 years ago

@styfle Any update on this? Looks like ts-loader v6.1.0 landed and supports project references: https://github.com/TypeStrong/ts-loader/pull/935

Happy to help out with this if no one is looking at it.

styfle commented 5 years ago

@anthonyshort Feel free to submit a PR with implementation and tests 👍

I should also point out that ZEIT Now is no longer using ncc for tree-shaking user code and instead uses node-file-trace.