Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webpack + Typegoose and minification breaks functionality #157

Closed
sverraest opened this issue Dec 11, 2019 · 8 comments
Closed

Webpack + Typegoose and minification breaks functionality #157

sverraest opened this issue Dec 11, 2019 · 8 comments
Labels
bug Something isn't working duplicate This issue or pull request already exists | This Feature already exists not a typegoose issue This is not a typegoose issue / This pr addresses something that shouldnt be in typegoose wont fix This will likely never be worked on

Comments

@sverraest
Copy link

Versions

  • NodeJS: 8.10.0
  • Typegoose(NPM): 6.1.7
  • Typegoose(GIT): commithash
  • mongoose: 5.7.14
  • mongodb: 3.6.0

What is the Problem?

We are using webpack to build and serverless to deploy our application.
Using the minification optimisation on production it seems TypeGoose gets broken with the errors such as:

TypeError: Type does not have an valid "OptionsConstructor"!
  File "/var/task/functions/update.js", line 434, in Object.t.mapArrayOptions
    '{snip} 

We also noticed class names are duplicated so uniqueness is not preserved.
This causes some classes to fail because they get the wrong schema.

Code Example

export class Company {
  @arrayProp({ itemsRef: "Invitation", default: [], required: false })
  invitations: Ref<Invitation>[]
  @arrayProp({ itemsRef: "Registration", default: [], required: true })
  registrations: Ref<Registration>[]
}

later:

        this.RegistrationModel = getModelForClass(Registration, { schemaOptions: {autoCreate: true, timestamps: true, collection: 'registration_pending', toJSON: {virtuals: true}}})
        this.UserModel = getModelForClass(User)
        this.CompanyModel = getModelForClass(Company, { schemaOptions: {autoCreate: true, timestamps: true, collection: 'companies', toJSON: {virtuals: true}}})
        this.InvitationModel = getModelForClass(Invitation, { schemaOptions: {autoCreate: true, timestamps: true, collection: 'registration_invitations', toJSON: {virtuals: true}}})

Webpack:

const path = require('path')
const slsw = require('serverless-webpack')
const webpack = require('webpack')
var nodeExternals = require('webpack-node-externals')

module.exports = {
  entry: slsw.lib.entries,
  mode: 'production',
  resolve: {
    extensions: [
      '.js',
      '.jsx',
      '.json',
      '.ts',
      '.tsx'
    ]
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, '.webpack'),
    filename: '[name].js',
    pathinfo: false,
  },
  externals: [
    nodeExternals({
      modulesFromFile: true,
    }),
    'aws-sdk'
  ],
  target: 'node',
  module: {
    rules: [
      { test: /\.ts(x?)$/, use: [
        {
          loader: 'ts-loader',
          options: {
            transpileOnly: true,
            experimentalWatchApi: true,
          }
        }
      ]},
    ],
  },
  plugins: [
    new webpack.DefinePlugin({ "global.GENTLY": false })
  ]
}

When we also remove for example the quotes around our itemsRef this breaks the application, getting undefined as a ref then when we run the code.

Do you know why it happens?

no

@sverraest sverraest added the bug Something isn't working label Dec 11, 2019
@hasezoey
Copy link
Member

When we also remove for example the quotes around our itemsRef this breaks the application, getting undefined as a ref then when we run the code.

https://typegoose.github.io/typegoose/guides/advanced/reference-other-classes/#common-problems


Duplicate of szokodiakos/typegoose#242 (old repository)

TL;DR: minification(/webpack optimization of it) is not supported by typegoose (and "name mangling" will break typegoose because it relies on names, which is not used in this case)


because webpack is used, i need to mention: #33

TL;DR: typegoose dosnt support being on the client side


i will close this because of the "duplicate" on the old repo and running on the client side (and because of the specific optimization webpack does to minify it)

@hasezoey hasezoey added duplicate This issue or pull request already exists | This Feature already exists not a typegoose issue This is not a typegoose issue / This pr addresses something that shouldnt be in typegoose wont fix This will likely never be worked on labels Dec 11, 2019
@sverraest
Copy link
Author

Thank you for the quick response. Just a final note, if we preserve class names and function names would there be any conflict?

@hasezoey
Copy link
Member

Just a final note, if we preserve class names and function names would there be any conflict?

probably, because of the "optimizations" web pack does (like reordering statements (functions / classes / statements) / everything into one big file) otherwise it should work

PS: i never used webpack and minimization of it, so i dont know what it actually does or what would be affected

@Smidgens
Copy link

Smidgens commented Mar 13, 2020

Just to chime in. I ran into this just now when building for production with webpack. All the model names got mangled or merged into one (I couldn't tell exactly what was happening, everything looked like it was being saved using the same model).

The quick fix that worked for me was to add the following to the webpack config:

optimization:{
	minimize:false
}

As far as I can tell, typegoose works just fine with webpack if you simply disable mangling.
And maybe it's possible to whitelist modules for mangling somehow so you don't have to disable it in general. Webpack has a plethora of settings so it seems likely.

The webpack docs on minification.

@ludovit-ubrezi
Copy link

ludovit-ubrezi commented Oct 27, 2021

FYI this is still big problem because of randomness.
I converting our server to mongoose and first 3 repositories were ok but at 4th i got this problem.
2 different repositories used same table even with exact { schemaOptions: { collection: "my_collection" } } definition

Maybe it should be added to your official documentation. https://typegoose.github.io/typegoose/docs/guides/known-issues
@hasezoey

@hasezoey
Copy link
Member

a section for webpack was added in ad0b4ff, it will be up at Known-Issues: Webpack (in a few minutes, when deployed)

@singhsoldier13
Copy link

singhsoldier13 commented Jan 21, 2022

Fix:
It works with Terser Plugin for minification and keeping the class names.

 optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
        // sourceMap: true,
        terserOptions: {
          ecma: 8,
          keep_classnames: true,
          keep_fnames: true,
        },
      }),
    ],
  },

Referenced from: szokodiakos/typegoose#242 (comment)

@hasezoey
Copy link
Member

@singhsoldier13 next time please put your code in code blocks, see Mastering Markdown: Quoting Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working duplicate This issue or pull request already exists | This Feature already exists not a typegoose issue This is not a typegoose issue / This pr addresses something that shouldnt be in typegoose wont fix This will likely never be worked on
Projects
None yet
Development

No branches or pull requests

5 participants