7

EDIT: Repository where issue can be reproduced easily:

https://github.com/sebastiangug/turborepo-nestjs

I have a turborepo project with several nestjs applications that share various packages.

I've configured it to use webpack per the documentation and latest versions via the CLI. Unfortunately, it doesn't seem to compile the application as expected resoluting in the 'unexpected token 'export'' that is thrown from within a shared package inside /packages/.

My package manage is pnpm.

Error:

graphql-server:build: SyntaxError: Unexpected token 'export'
graphql-server:build:     at Object.compileFunction (node:vm:352:18)

versions/dependencies:

  "dependencies": {
    "@nestjs/common": "9.0.8",
    "@nestjs/core": "9.0.8",
    "@nestjs/platform-express": "9.0.8",
    "@nestjs/graphql": "10.0.21",
    "@nestjs/apollo": "10.0.19",
    "graphql": "16.5.0",
    "apollo-server-express": "3.6.7",
    "reflect-metadata": "0.1.13",
    "rimraf": "3.0.2",
    "rxjs": "7.5.5"
  },
  "devDependencies": {
    "@nestjs/cli": "8.2.8",
    "@nestjs/schematics": "8.0.11",
    "@nestjs/testing": "9.0.8",
    "@types/express": "4.17.13",
    "@types/jest": "28.1.2",
    "@types/node": "16.0.0",
    "@types/supertest": "2.0.12",
    "@typescript-eslint/eslint-plugin": "5.30.0",
    "@typescript-eslint/parser": "5.30.0",
    "eslint": "8.18.0",
    "eslint-config-prettier": "8.5.0",
    "eslint-config-custom-nest": "workspace:*",
    "eslint-plugin-prettier": "4.2.1",
    "eslint-plugin-import": "2.26.0",
    "eslint-plugin-unicorn": "43.0.1",
    "jest": "28.1.2",
    "prettier": "2.7.1",
    "source-map-support": "0.5.21",
    "supertest": "6.2.3",
    "ts-jest": "28.0.5",
    "ts-node": "10.8.1",
    "tsconfig-paths": "3.10.1",
    "typescript": "4.7.4",
    "webpack-node-externals": "3.0.0",
    "webpack": "5.74.0",
    "run-script-webpack-plugin": "0.1.1",
    "ts-loader": "9.3.1",
    "webpack-cli": "4.10.0",
    "@yeo/tsconfig": "workspace:*",
    "@yeo/nest-config": "workspace:*",
    "@yeo/tracer": "workspace:*",
    "@yeo/entities": "workspace:*"
  },

the production build throws the same error and just bundles everything into one server.js file. For HMR, this config right out of the docs is used:

const nodeExternals = require("webpack-node-externals");
const { RunScriptWebpackPlugin } = require("run-script-webpack-plugin");

module.exports = function (options, webpack) {
  return {
    ...options,
    entry: ["webpack/hot/poll?100", options.entry],
    externals: [
      nodeExternals({
        allowlist: ["webpack/hot/poll?100"],
      }),
    ],
    plugins: [
      ...options.plugins,
      new webpack.HotModuleReplacementPlugin(),
      new webpack.WatchIgnorePlugin({
        paths: [/\.js$/, /\.d\.ts$/],
      }),
      new RunScriptWebpackPlugin({ name: options.output.filename, autoRestart: false }),
    ],
  };
};

Application structure:

├── apps
│   ├── nest-app1
│   └── nest-app2
└── packages
    └── config
        └── src
            └── config.module.ts
SebastianG
  • 8,563
  • 8
  • 47
  • 111
  • Did you manage to resolve this? – Jacobdo Sep 18 '22 at 13:50
  • 1
    @Jacobdo I've wised up and used NX instead, I've had a smooth blast since then! Everything just works and it's so much faster. Sadly the turborepo maintainers do not consider this a turborepo related issue but I don't see this a webpack maintainers issue as this only occurs in the turborepo context, so I don't see any potential fix in sight. – SebastianG Sep 28 '22 at 17:30
  • facing similar issue – Daksh Dec 08 '22 at 11:16

1 Answers1

1

There are two ways I can think of to solve this.

Use NestJS monorepo mode. See docs here

OR

Add build and dev scripts to each packages Package.json using the Typescript compiler (or similar like tsup). Also add main and types fields to the Package.json and point to the compiled js files.

Here is a simple example of what a Package.json for a package called shared could look like. Note this assumes a tsconfig.json file exists (if not, create one or pass in config options to tsc)

{
  "name": "shared",
  "main": "dist/index.js",
  "types": "dist/index.js",
  "scripts": {
    "build": "tsc --build",
    "dev": "tsc --watch"
  },
  "dependencies": {
    "typescript": "^4.9.4"
  }
}

The latter approach maybe better if you need to share the packages with apps that are not using NestJs and/or share the packages outside the monorepo. The first approach maybe better in the case where NestJs is the only framework and a single Package.json meets your requirements.

Dustin Townsend
  • 161
  • 1
  • 5