bennymeg / nx-electron

Electron schematics for nrwl nx platform
Apache License 2.0
328 stars 85 forks source link

generatePackageJson does not impact the packaged dependencies. #167

Closed paustint closed 2 years ago

paustint commented 2 years ago

Describe the bug Setting generatePackageJson to true only impacts the package.json that gets generated in the build process of electron, but the root level package.json is always used the the actual packaging process.

The issue appears to be that the files transferred over - there are two package.json entries, and the latter one that is coming from the project root ends up "winning" and is what is used.

builder-effective-config.yaml

...
  - from: /../my-app/..
    to: ''
    filter:
      - index.js
      - package.json
  - filter:
      - ./package.json
      - '!(**/*.+(js|css).map)'

(On a side note, the implicit dependencies are not calculated correctly - there is NO way that my main electron app uses classnames, react, soql-parser-js, or xlsx (nx-electron added these to the package.json) - as these are only used in the web-application, not the electron app and are already bundled with my source code.

To Reproduce

Set generatePackageJso: true, include a package.json for the project with different dependencies, then build the application. Unpack the built application, notice that the root level package.json file is always used no matter what.

I can see in my built electron app, has a package.json that was generated by generatePackageJson:

  "dependencies": {
    "rollbar": "^2.21.0",
    "jsforce": "^1.9.3",
    "classnames": "^2.2.6",
    "react": "18.0.0",
    "soql-parser-js": "^4.4.0",
    "xlsx": "^0.17.4"
  }

When I extract my packaged application asar, I have the package.json from the root of my entire workspace, not the one that was generated.

"dependencies": {
    "@ag-grid-community/client-side-row-model": "^27.2.1",
    "@ag-grid-community/core": "^27.2.1",
    "@ag-grid-community/infinite-row-model": "^27.2.1",
    "@ag-grid-community/react": "^27.2.1",
    "@ag-grid-enterprise/clipboard": "^27.2.1",
    "@ag-grid-enterprise/core": "^27.2.1",
    "@ag-grid-enterprise/filter-tool-panel": "^27.2.1",
    "@ag-grid-enterprise/menu": "^27.2.1",
    "@ag-grid-enterprise/multi-filter": "^27.2.1",
    "@ag-grid-enterprise/range-selection": "^27.2.1",
    "@ag-grid-enterprise/row-grouping": "^27.2.1",
    "@ag-grid-enterprise/set-filter": "^27.2.1",
    "@emotion/react": "11.9.0",
    "@emotion/styled": "11.8.1",
    "@fullhuman/postcss-purgecss": "^2.2.0",
    "@grpc/grpc-js": "^1.5.8",
    "@headlessui/react": "^1.4.1",
    "@heroicons/react": "^1.0.4",
    "@mdx-js/react": "^1.6.21",
    "@monaco-editor/react": "^4.2.2",
    "@nrwl/nx-cloud": "14.0.3",
    "@octokit/graphql": "^4.7.0",
    "@octokit/rest": "^18.9.1",
    "@opentelemetry/api": "^1.0.4",
    "@opentelemetry/auto-instrumentations-node": "^0.28.0",
    "@opentelemetry/exporter-trace-otlp-grpc": "^0.27.0",
    "@opentelemetry/sdk-node": "^0.27.0",
    "@popperjs/core": "^2.4.0",
    "@prisma/client": "^3.13.0",
    "@react-aria/dialog": "^3.1.4",
    "@react-aria/focus": "^3.5.0",
    "@react-aria/overlays": "^3.7.2",
    "@tippyjs/react": "^4.0.2",
... (and more) ....
paustint commented 2 years ago

I worked around this by creating a root level folder named app and placing my curated package.json file there, based on this comment: https://github.com/electron-userland/electron-builder/issues/379#issuecomment-218503881

But ideally I would be able to use the generate package.json file instead.

r-hannuschka commented 2 years ago

We have done exactly the same thing now, the problem here is we have a nestjs/app with serve static in productive mode which already generates us a package.json.

But here the option is missing currently please take this. The 2nd problem is that I don't know exactly currently if it is even possible to tell the electron this is your working directory, so it always started from the app root and pulled the package.json from the monorepo which ended up being a 2GB Electron app.

We have now built our own scripts to solve this which are simply called via node.

Translated with www.DeepL.com/Translator (free version) // keep this so everybody know my english sucks :D

3 Steps:

  1. copy the package.json from dist/server/package.json to dist/electron/package.json
  2. add the devDependency: electron (version i take from the root package.json)
  3. save and run, the important part is config.directorys here since i can say okay electron you work here and not in root
// final package.json i use for electron build which is generated through nestjs and added some packages here
{
  "name": "easy-bsb",
  "version": "0.0.0",
  "dependencies": {
    "@nestjs/common": "8.4.5",
    "class-validator": "0.13.2",
    "reflect-metadata": "0.1.13",
    "rxjs": "7.5.5",
    "@nestjs/config": "2.0.1",
    "@nestjs/typeorm": "9.0.0-next.2",
    "@nestjs/core": "8.4.5",
    "@nestjs/platform-express": "8.4.5",
    "@nestjs/websockets": "8.4.5",
    "@nestjs/platform-socket.io": "8.4.5",
    "typeorm": "0.3.6",
    "@nestjs/swagger": "5.2.1",
    "swagger-ui-express": "4.4.0",
    "@nestjs/serve-static": "2.2.2",
    "@nestjs/passport": "8.2.1",
    "passport": "0.6.0",
    "@nestjs/jwt": "8.0.1",
    "bcryptjs": "2.4.3",
    "passport-jwt": "4.0.0",
    "passport-local": "1.0.0",
    "socket.io": "4.5.1",
    "@casl/ability": "5.4.3",
    "sql.js": "1.6.2",
    "@oclif/core": "1.9.0"
  },
  "main": "main.js",
  "author": {
    "name": "easybsb"
  },
  "description": "easybsb app",
  "license": "MIT",
  "engines": {
    "node": "^16.13.0",
    "npm": "^8.1.0"
  },
  "overrides": {
    "@nestjs/passport": {
      "passport": "$passport"
    },
    "@nestjs/typeorm": {
      "typeorm": "$typeorm"
    },
    "@nestjs/config": {
      "@nestjs/common": "$@nestjs/common"
    }
  },
  "bin": {
    "easybsb": "./bin/easybsb.js"
  },
  "devDependencies": {
    "electron": "18.2.3"
  }
}
...
async function buildElectron() {
  await electronBuilder.build({
    config: {
      files: [
        {
          from: path.resolve(__dirname, "..", "dist/apps/server"),
          to: "easy-bsb",
          filter: ["!package.json"],
        },
        {
          from: path.resolve(__dirname, "..", "dist/apps/electron"),
          to: "",
          filter: [
            "!dist",
            "!node_modules",
            "**/*.js",
            "**/*.js.map",
            "package.json",
          ],
        },
        // splash screen
        {
          from: path.resolve(__dirname, "..", "dist/apps/electron/assets"),
          to: "assets",
        },
      ],
      directories: {
        output: path.resolve(__dirname, "../dist/electron"),
        // this one seems the option we can tell the builder where to search
        app: path.resolve(__dirname, "../dist/apps/electron"),
        buildResources: (__dirname, "../dist/tmp/electron"),
      },
    }
  });
}
...
bennymeg commented 2 years ago

@paustint I see what you mean. I will ascend the global filter role to the top of the array it will get overridden only if the generated package json exist.

paustint commented 2 years ago

@bennymeg - Sort of unrelated, but throwing it out there - in maker.options, I have only been able to get custom files entries to work if I use the full path

working Example

    {
      "from": "/Users/my-user/dev/node/my-app/dist/apps/electron/worker",
      "to": "electron/worker",
      "filter": ["main.js", "assets"]
    },

Ideally I should be able to do a relative path - which would require the plugin to convert this to the full path when generating the effective config

"from": "apps/electron/worker",

bennymeg commented 2 years ago

No problem, Please open a new feature request and I will take care of it.

bennymeg commented 2 years ago

Fixed in v13.2.1