Inversifyjs: bundle using webpack mode "production" and inversify-express-utils

Created on 8 Aug 2018  路  7Comments  路  Source: inversify/InversifyJS

Expected Behavior

should be able to generate a minimized bundle using webpack.

Current Behavior

when using webpack configuration option mode: "production" which generates a minimized app bundle, there are conflicts when using the @controller(..) decorator available in the inversify-express-utils package.

Steps to Reproduce

test repo:
https://github.com/jwldnr/inversify-webpack

steps to reproduce (also included in the readme):

  • install dependencies using yarn
    -> cd inversify-webpack && yarn
  • bundle using webpack
    -> yarn build

  • run app
    -> yarn serve

Context

we're unable to bundle our app in production using webpack together with inversify-express-utils.

Your Environment (versions)

inversify: 4.13.0
inversify-express-utils: 6.1.0
webpack: 4.16.5

Stack trace

/Users/m41n/source/repos/inversify-webpack/node_modules/inversify-express-utils/lib/server.js:132
                throw new Error(constants_1.DUPLICATED_CONTROLLER_NAME(name));
                ^

Error: Two controllers cannot have the same name: e
    at /Users/m41n/source/repos/inversify-webpack/node_modules/inversify-express-utils/lib/server.js:132:23
    at Array.forEach (<anonymous>)
    at InversifyExpressServer.registerControllers (/Users/m41n/source/repos/inversify-webpack/node_modules/inversify-express-utils/lib/server.js:129:22)
    at InversifyExpressServer.build (/Users/m41n/source/repos/inversify-webpack/node_modules/inversify-express-utils/lib/server.js:117:14)
    at Object.<anonymous> (/Users/m41n/source/repos/inversify-webpack/dist/server.js:1:1196)
    at n (/Users/m41n/source/repos/inversify-webpack/dist/server.js:1:172)
    at /Users/m41n/source/repos/inversify-webpack/dist/server.js:1:965
    at Object.<anonymous> (/Users/m41n/source/repos/inversify-webpack/dist/server.js:1:974)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)

Most helpful comment

When we initialize the decorator @controller('/sample-path').

If webpack minimize=false he will generate the function name correctly.
example:
{
middleware: [],
path: '/sample-path',
target: [Function: SamplePathController]
}

if webpack minimize=true he will change function name to 't', and not using the classname as function name.
example:
{
middleware: [],
path: '/sample-path',
target: [Function: t]
}

When inversify will registerControllers he will use the function name to verify if alrealdy was initialize, so occors DUPLICATED_CONTROLLER_NAME.

Inversify need store the name in decorator @controller.

All 7 comments

Having the same issue. @jwldnr Please share if you are able to fix it

Out of curiosity, what is your intention behind wanting to create your production bundle using webpack?

I am fairly new to TypeScript, but wouldn't it be more traditional to use something like ts-node + nodemon to run your application in development, and then create a production build using tsc (typescript compiler)?

Am I misunderstanding, and you are creating a client-side application with inversify vs a server-side application?

@viglucci I'm using inversify on a server-side application. Webpack provides optimized builds that minimize as well as provides other features. I understand your point of using tsc, but I would like to understand why this does not work?

When we initialize the decorator @controller('/sample-path').

If webpack minimize=false he will generate the function name correctly.
example:
{
middleware: [],
path: '/sample-path',
target: [Function: SamplePathController]
}

if webpack minimize=true he will change function name to 't', and not using the classname as function name.
example:
{
middleware: [],
path: '/sample-path',
target: [Function: t]
}

When inversify will registerControllers he will use the function name to verify if alrealdy was initialize, so occors DUPLICATED_CONTROLLER_NAME.

Inversify need store the name in decorator @controller.

Any update on this?

To all, I've worked around this by using the exclude property in TerserPlugin to exclude controllers:

 optimization: {
    minimizer: [
      new TerserPlugin({
        include: /\.ts($|\?)/i,
        exclude: /\.controller\.ts/i,
        parallel: true,
        sourceMap: true
      })
    ]
  }

My regex kung-fu let me down but I found an easier option if you don't mind all class names to be un-obfuscated:

optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          keep_classnames: true,
        },
        parallel: true,
        sourceMap: true
      })
    ]
  },
Was this page helpful?
0 / 5 - 0 ratings