oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.2k stars 2.77k forks source link

Unable to build NestJS based project #4803

Open kpostekk opened 1 year ago

kpostekk commented 1 year ago

What version of Bun is running?

1.0.0+822a00c4d508b54f650933a73ca5f4a3af9a7983

What platform is your computer?

Linux 6.4.13-200.fc38.x86_64 x86_64 unknown

What steps can reproduce the bug?

Create a hello world app in NestJS then try to compile it?

bun build --compile src/main.ts --outfile=nest-main

What is the expected behavior?

Application compiles.

What do you see instead?

warn: wildcard sideEffects are not supported yet, which means this package will be deoptimized

    "umd/*"
    ^
/home/ads/ad-streamer/node_modules/graphql-ws/package.json:83:5 2189

error: Could not resolve: "@nestjs/microservices". Maybe you need to "bun install"?

        const { NestMicroservice } = (0, load_package_util_1.loadPackage)('@nestjs/microservices', 'NestFactory', () => require('@nestjs/microservices'));

                                        ^
/home/ads/ad-streamer/node_modules/@nestjs/core/nest-factory.js:57:129 2923

error: Could not resolve: "@nestjs/platform-express". Maybe you need to "bun install"?

        const { ExpressAdapter } = (0, load_adapter_1.loadAdapter)('@nestjs/platform-express', 'HTTP', () => require('@nestjs/platform-express'));

                             ^
/home/ads/ad-streamer/node_modules/@nestjs/core/nest-factory.js:164:118 7713

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));

                           ^
/home/ads/ad-streamer/node_modules/@nestjs/core/nest-application.js:19:116 1093

error: Could not resolve: "@nestjs/microservices/microservices-module". Maybe you need to "bun install"?

const { MicroservicesModule } = (0, optional_require_1.optionalRequire)('@nestjs/microservices/microservices-module', () => require('@nestjs/microservices/microservices-module'));

                                            ^
/home/ads/ad-streamer/node_modules/@nestjs/core/nest-application.js:20:133 1263

error: Could not resolve: "@nestjs/microservices". Maybe you need to "bun install"?

        const { NestMicroservice } = (0, load_package_util_1.loadPackage)('@nestjs/microservices', 'NestFactory', () => require('@nestjs/microservices'));

                                        ^
/home/ads/ad-streamer/node_modules/@nestjs/core/nest-application.js:123:129 5792

error: Could not resolve: "class-validator". Maybe you need to "bun install"?

            (0, load_package_util_1.loadPackage)('class-validator', 'ValidationPipe', () => require('class-validator')));

            ^
/home/ads/ad-streamer/node_modules/@nestjs/common/pipes/validation.pipe.js:39:101 1987

error: Could not resolve: "class-transformer". Maybe you need to "bun install"?

            (0, load_package_util_1.loadPackage)('class-transformer', 'ValidationPipe', () => require('class-transformer')));

              ^
/home/ads/ad-streamer/node_modules/@nestjs/common/pipes/validation.pipe.js:43:103 2197

error: Could not resolve: "class-transformer". Maybe you need to "bun install"?

                (0, load_package_util_1.loadPackage)('class-transformer', 'ClassSerializerInterceptor', () => require('class-transformer'));

                              ^
/home/ads/ad-streamer/node_modules/@nestjs/common/serializer/class-serializer.interceptor.js:25:119 1134

error: Could not resolve: "class-transformer". Maybe you need to "bun install"?

            require('class-transformer');
                    ^
/home/ads/ad-streamer/node_modules/@nestjs/common/serializer/class-serializer.interceptor.js:27:21 1228

error: Could not resolve: "@fastify/view". Maybe you need to "bun install"?

        return this.register((0, load_package_util_1.loadPackage)('@fastify/view', 'FastifyAdapter.setViewEngine()', () => require('@fastify/view')), options);

                                           ^
/home/ads/ad-streamer/node_modules/@nestjs/platform-fastify/adapters/fastify-adapter.js:251:132 10144

error: Could not resolve: "ts-morph". Maybe you need to "bun install"?

        tsMorphLib = await Promise.resolve().then(() => require('ts-morph'));
                                                                ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/graphql-ast.explorer.js:17:65 659

error: Could not resolve: "@apollo/gateway". Maybe you need to "bun install"?

        const { ApolloGateway } = (0, load_package_util_1.loadPackage)('@apollo/gateway', 'ApolloGateway', () => require('@apollo/gateway'));

                                 ^
/home/ads/ad-streamer/node_modules/@nestjs/apollo/dist/drivers/apollo-gateway.driver.js:18:122 1084

error: Could not resolve: "@apollo/subgraph". Maybe you need to "bun install"?

            const { printSubgraphSchema } = (0, load_package_util_1.loadPackage)('@apollo/subgraph', 'ApolloFederation', () => require('@apollo/subgraph'));

                                               ^
/home/ads/ad-streamer/node_modules/@nestjs/apollo/dist/drivers/apollo-federation.driver.js:20:136 1251

error: Could not resolve: "@apollo/subgraph". Maybe you need to "bun install"?

        const { buildSubgraphSchema } = (0, load_package_util_1.loadPackage)('@apollo/subgraph', 'ApolloFederation', () => require('@apollo/subgraph'));

                                           ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation-definitions.factory.js:13:132 932

error: Could not resolve: "@apollo/subgraph". Maybe you need to "bun install"?

        const { printSubgraphSchema } = (0, load_package_util_1.loadPackage)('@apollo/subgraph', 'ApolloFederation', () => require('@apollo/subgraph'));

                                           ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation-definitions.factory.js:14:132 1085

error: Could not resolve: "@apollo/subgraph". Maybe you need to "bun install"?

        const { buildSubgraphSchema } = (0, load_package_util_1.loadPackage)('@apollo/subgraph', 'ApolloFederation', () => require('@apollo/subgraph'));

                                           ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation.factory.js:41:132 2089

error: Could not resolve: "@apollo/subgraph". Maybe you need to "bun install"?

        const apolloSubgraph = (0, load_package_util_1.loadPackage)('@apollo/subgraph', 'ApolloFederation', () => require('@apollo/subgraph'));

                                  ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation.factory.js:52:123 2545

error: Could not resolve: "@apollo/subgraph/package.json". Maybe you need to "bun install"?

        const apolloSubgraphVersion = (await Promise.resolve().then(() => require('@apollo/subgraph/package.json'))).version;
                                                                                  ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation.factory.js:53:83 2649

error: Could not resolve: "@apollo/subgraph/dist/directives". Maybe you need to "bun install"?

        const { federationDirectives, directivesWithNoDefinitionNeeded } = (0, load_package_util_1.loadPackage)('@apollo/subgraph/dist/directives', 'SchemaBuilder', () => require('@apollo/subgraph/dist/directives'));

   ^
/home/ads/ad-streamer/node_modules/@nestjs/graphql/dist/federation/graphql-federation.factory.js:238:180 11801

error: Could not resolve: "class-validator". Maybe you need to "bun install"?

    const classValidator = require('class-validator');
                                   ^
/home/ads/ad-streamer/node_modules/@nestjs/mapped-types/dist/type-helpers.utils.js:10:36 488

error: Could not resolve: "class-transformer/storage". Maybe you need to "bun install"?

Additional information

It's still possible to run it using bun run (however, start time is quite long). Related to #1641

posabsolute commented 1 year ago

I have a similar issue, when running packages using require-optional it's failing to load the dependency

Cannot find package "mongodb-extjson" from "/node_modules/mongodb/lib/core/utils.js"

function retrieveEJSON() {
  let EJSON = requireOptional('mongodb-extjson');
  if (!EJSON) {
    EJSON = {
      parse: noEJSONError,
      deserialize: noEJSONError,
      serialize: noEJSONError,
      stringify: noEJSONError,
      setBSONModule: noEJSONError,
      BSON: noEJSONError
    };
  }

  return EJSON;
}
kazak1377 commented 1 year ago

Same. Trying to migrate existent project to use bun as runtime. As i understand running bunx nest start --watch will still be using nodejs same for build. So, tried to use bun as dev server or bundler:

For dev server tried:

bun ./src/main.ts

it failed with such error:

I noticed that it is cuz of prom-client. Related to #4708

bun ./src/main.ts

 8 | }, $;
 9 | 
10 | class NotImplementedError extends Error {
11 |   code;
12 | 
13 |   constructor(feature, issue) {
                             ^
NotImplementedError: PerformanceObserver is not yet implemented in Bun.
 code: "ERR_NOT_IMPLEMENTED"

trying to build app also provides lots of errors:

bun build ./src/main.ts --target=bun                                                                                                                                       ─╯

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
                                                                                                                   ^
/Users/${projectDir}/node_modules/@nestjs/core/nest-application.js:19:116 1093

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
                                                                                                                   ^
/Users/${projectDir}/node_modules/@nestjs/microservices/nest-microservice.js:12:116 769

error: Could not resolve: "@grpc/grpc-js". Maybe you need to "bun install"?

        grpcPackage = (0, load_package_util_1.loadPackage)('@grpc/grpc-js', ClientGrpcProxy.name, () => require('@grpc/grpc-js'));
                                                                                                                ^
/Users/${projectDir}/node_modules/@nestjs/microservices/client/client-grpc.js:28:113 1471

error: Could not resolve: "@grpc/proto-loader". Maybe you need to "bun install"?

            ? require('@grpc/proto-loader')
                      ^
/Users/${projectDir}/@nestjs/microservices/client/client-grpc.js:30:23 1677
ArtemKurtiakWork commented 1 year ago

+1 for this issue

keinsell commented 1 year ago

Same. Trying to migrate existent project to use bun as runtime. As i understand running bunx nest start --watch will still be using nodejs same for build. So, tried to use bun as dev server or bundler:

For dev server tried:

bun ./src/main.ts

it failed with such error:

I noticed that it is cuz of prom-client. Related to #4708

bun ./src/main.ts

 8 | }, $;
 9 | 
10 | class NotImplementedError extends Error {
11 |   code;
12 | 
13 |   constructor(feature, issue) {
                             ^
NotImplementedError: PerformanceObserver is not yet implemented in Bun.
 code: "ERR_NOT_IMPLEMENTED"

trying to build app also provides lots of errors:

bun build ./src/main.ts --target=bun                                                                                                                                       ─╯

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
                                                                                                                   ^
/Users/${projectDir}/node_modules/@nestjs/core/nest-application.js:19:116 1093

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
                                                                                                                   ^
/Users/${projectDir}/node_modules/@nestjs/microservices/nest-microservice.js:12:116 769

error: Could not resolve: "@grpc/grpc-js". Maybe you need to "bun install"?

        grpcPackage = (0, load_package_util_1.loadPackage)('@grpc/grpc-js', ClientGrpcProxy.name, () => require('@grpc/grpc-js'));
                                                                                                                ^
/Users/${projectDir}/node_modules/@nestjs/microservices/client/client-grpc.js:28:113 1471

error: Could not resolve: "@grpc/proto-loader". Maybe you need to "bun install"?

            ? require('@grpc/proto-loader')
                      ^
/Users/${projectDir}/@nestjs/microservices/client/client-grpc.js:30:23 1677

Literally same thing on my side, same issues which ncc had when it comes down to compilation of much older Node.js modules (or ones that use Native Bindings), genuinely I do not think this will be fixed the issue was persisting through a lot of compilers and none of them have solved a problem.

tungv commented 1 year ago

optional-require package has a check to see if an error throw while requireing and that check assume there is a "${packageName}" in the error. However, the equivalent error thrown from bun uses single quote '${packageName}'.

I made a PR to optional-require but I don't think it will be merged into and we also need all the transitive dependencies to upgrade as well (which is not feasible in a short time).

Solution: we may need to ask bun to change the error message to match the one from node. I searched through bun source code and I think this is the one: https://github.com/oven-sh/bun/blob/35109160ca5d439116bedeb3302ec3745e2895d5/src/bun.js/ResolveMessage.zig#L55.

AnsgarLichter commented 1 year ago

Same Problem on my side. When trying to build this repo with the following command I have the same errors.

bun build --target bun --outdir ./out src/main.ts

This are the errors shown in the console:

error: Could not resolve: "@nestjs/microservices". Maybe you need to "bun install"?

        const { NestMicroservice } = (0, load_package_util_1.loadPackage)('@nestjs/microservices', 'NestFactory', () => require('@nestjs/microservices'));
                                                                                                                                ^
/home/ansgar/repositories/nestjs-api/node_modules/@nestjs/core/nest-factory.js:57:129 2923

error: Could not resolve: "@nestjs/websockets/socket-module". Maybe you need to "bun install"?

const { SocketModule } = (0, optional_require_1.optionalRequire)('@nestjs/websockets/socket-module', () => require('@nestjs/websockets/socket-module'));
                                                                                                                   ^
/home/ansgar/repositories/nestjs-api/node_modules/@nestjs/core/nest-application.js:19:116 1093

error: Could not resolve: "@nestjs/microservices/microservices-module". Maybe you need to "bun install"?

const { MicroservicesModule } = (0, optional_require_1.optionalRequire)('@nestjs/microservices/microservices-module', () => require('@nestjs/microservices/microservices-module'));
                                                                                                                                    ^
/home/ansgar/repositories/nestjs-api/node_modules/@nestjs/core/nest-application.js:20:133 1263

error: Could not resolve: "@nestjs/microservices". Maybe you need to "bun install"?

        const { NestMicroservice } = (0, load_package_util_1.loadPackage)('@nestjs/microservices', 'NestFactory', () => require('@nestjs/microservices'));
                                                                                                                                ^
/home/ansgar/repositories/nestjs-api/node_modules/@nestjs/core/nest-application.js:123:129 5792

error: Could not resolve: "mock-aws-s3". Maybe you need to "bun install"?

    const AWSMock = require('mock-aws-s3');
                            ^
/home/ansgar/repositories/nestjs-api/node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:43:29 1141

error: Could not resolve: "aws-sdk". Maybe you need to "bun install"?

  const AWS = require('aws-sdk');
                      ^
/home/ansgar/repositories/nestjs-api/node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:76:23 2020

error: Could not resolve: "nock". Maybe you need to "bun install"?

  const nock = require('nock');
                       ^
/home/ansgar/repositories/nestjs-api/node_modules/@mapbox/node-pre-gyp/lib/util/s3_setup.js:112:24 2898

error: Could not resolve: "class-transformer/storage". Maybe you need to "bun install"?

        classTransformer = require('class-transformer/storage');
                                   ^
/home/ansgar/repositories/nestjs-api/node_modules/@nestjs/mapped-types/dist/type-helpers.utils.js:71:36 3118
andreasvh-conceto commented 10 months ago

same here: with bun build there are still issues. I have still to use nest build and node. So +1 for fixing this issue

jlucaso1 commented 8 months ago

Still occurs in the latest version of bun v1.0.29. The only blocker for using bun runtime entirely in our project (still using tsc with node)

ericrange commented 8 months ago

works for me if i install the deps with npm.

npm install
bun index.js
jlucaso1 commented 8 months ago

What's up guys. I managed to make it work with some flags. We must add "-e" for each library that gives an error in the log. Example for a simple nest project:

bun build --target=bun -e @nestjs/websockets/socket-module -e ts-morph -e amqplib -e amqp-connection-manager -e nats -e @apollo/subgraph -e mqtt -e @nestjs/sequelize -e @mikro-orm/core -e @nestjs/typeorm -e @nestjs/mongoose -e class-transformer/storage -e kafkajs -e @nestjs/microservices -e class-transformer -e class-validator --minify src/main.ts --outdir out

I still can't use it in a large project as it depends on the sharp library which bun build doesn't handle well

https://github.com/oven-sh/bun/issues/158#issuecomment-1927764821

alextbok commented 7 months ago

As a guess this behavior may have to do with how bun build treats dependencies' peer dependencies marked as optional in peerDependenciesMeta. I'm not sure what the exact "expected" behavior is, but I wrote a small script as a workaround for now until the bun team supports expected behavior, whether by default or via bundler configuration.

The script uses a simple heuristic to determine whether to mark a dependency as external: if dependency A is marked as optional in peerDependenciesMeta and A is not installed (i.e. the file node_modules/A/package.json does not exist), then mark it as external.

The script assumes node_modules have been installed to {cwd}/node_modules and the entrypoint is {cwd}/main.ts.

import Bun from 'bun';

const entrypoint = 'main.ts';

type PackageJson = {
  readonly peerDependencies?: Record<string, unknown>;
  readonly peerDependenciesMeta?: Record<string, { readonly optional?: boolean }>;
};

const externals: string[] = [];

for await (const path of new Bun.Glob('./node_modules/**/package.json').scan('.')) {
  const { peerDependencies, peerDependenciesMeta } = (await Bun.file(path).json()) as PackageJson;
  if (peerDependencies && peerDependenciesMeta) {
    for (const dependency of Object.keys(peerDependencies)) {
      if (peerDependenciesMeta[dependency]?.optional) {
        const exists = await Bun.file(`node_modules/${dependency}/package.json`).exists();
        if (!exists) {
          externals.push(dependency);
        }
      }
    }
  }
}

await Bun.$`bun build --target=bun -e ${{ raw: externals.join(' -e ') }} --compile ${entrypoint}`;

(caveat emptor) This will obviously lead to a runtime error if the dependency is supposed to be there and isn't either shipped with the build artifact or provided at runtime so please vet the result and use with caution!

I don't know if this fix is comprehensive for the class of issues, but fwiw I tried on a medium sized project that had ~8 dependencies that blew up the build and all met the criteria above (it obv will not help with sharp or other libs that depend on node apis bun doesn't yet support).

jlucaso1 commented 7 months ago

About the sharp support in build it can be achieved if using wasm version, but for now bun not support specify the cpu architecture in the install. https://github.com/oven-sh/bun/issues/9636

yharaskrik commented 5 months ago

@Jarred-Sumner similar to my previous comment tonight about production usage, this is also blocking (for full bun switchover that is). I have our servers running in docker using dependencies installed by bun but the main.js is run with node. As soon as I switch over to doing bun run main.js instead, I get these types of errors (mine is specifically mongodb-extjson but the specific package likely doesn't matter).

Fine with running it with Node and installing with Bun for the time being though, thats already much faster than before.

shadowqcom commented 4 months ago

A successful solution for packaging Nestjs https://github.com/oven-sh/bun/discussions/12253

Niewdanka commented 3 months ago

any updates?

Jarred-Sumner commented 3 weeks ago

@tungv we will update the error message in Bun to use single quotes instead of double quotes