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

autoInjectable not working in Chrome Extension using Webpack #142

Closed
qwykx opened this issue Nov 27, 2020 · 12 comments
Closed

autoInjectable not working in Chrome Extension using Webpack #142

qwykx opened this issue Nov 27, 2020 · 12 comments
Assignees

Comments

@qwykx
Copy link

qwykx commented Nov 27, 2020

Describe the bug
TSyringe seems not to be working when used in a Chrome Extension using Webpack and ts-loader.

To Reproduce

// Database.ts
class Database {
    constructor() {}
}

export default Database;
// ConfigService.ts
import "reflect-metadata";
import { autoInjectable } from "tsyringe";
import Database from "../Database";

@autoInjectable()
class ConfigService {
    constructor(private db?: Database) {}
}

export default ConfigService;
// Background.ts
import "reflect-metadata";
import { container } from "tsyringe";
import Database from "../db/Database";
import ConfigService from "../db/services/ConfigService";

container.register<Database>(Database, { useClass: Database });

const service = new ConfigService();

Expected behavior
Expected new ConfigService() to return a ConfigService instance with dependencies resolved automatically.

Actual behavior
new ConfigService() throws an uncaught TypeError Class constructor ConfigService cannot be invoked without 'new'

Version: 4.4.0

@MeltingMosaic
Copy link
Collaborator

Can you share your config files (`webpack.*.config, tsconfig.json, .babelrc, etc.)?

@qwykx
Copy link
Author

qwykx commented Dec 2, 2020

Hello @MeltingMosaic

I am not using babel but here are the other requested files :)

// webpack.common.js
const path = require('path');
const src = '../src/';
const assets = '../assets'
const dist = '../dist/'

module.exports = {
    entry: {
        background: path.join(__dirname, src + '/background/background.ts')
    },
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /(node_modules|test)/,
            },
        ]
    },
    resolve: {
        extensions: ['.ts', '.tsx', '.js']
    },
    output: {
        path: path.join(__dirname, dist + '/js'),
        filename: '[name].js'
    },
};
 // webpack.prod.js
const { merge } = require('webpack-merge');
const common = require('./webpack.common.js');

module.exports = merge(common, {
    mode: 'production'
});
// tsconfig.json
{
  "compilerOptions": {
    "outDir": "./dist/",
    "module": "commonjs",
    "target": "ES6",
    "sourceMap": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true
  }

@manhnd98
Copy link

manhnd98 commented Dec 4, 2020

same issue

@MeltingMosaic
Copy link
Collaborator

Interesting. Do you have a repo I could fork? I've never written a chrome extension before, so I don't quite know how to set this up for repro.

@qwykx
Copy link
Author

qwykx commented Dec 8, 2020

Sure, I'll setup a minimal example repo tomorrow and link it here.

@qwykx
Copy link
Author

qwykx commented Dec 9, 2020

@MeltingMosaic

Here is your requested repo :) Just follow the install instructions in the Readme.

https://github.com/qwykx/Sample-Extension

@MeltingMosaic
Copy link
Collaborator

Thanks. I'll try to find some time to investigate it.

@MeltingMosaic
Copy link
Collaborator

@Xapphire13 if you get a chance, could you take a look at this? I can repro it, but I don't understand what's going on.

@ffortier
Copy link

ffortier commented May 4, 2021

It looks like webpack is prefering the "module": "./dist/esm5/index.js" config in the tsyringe/package.json over the better option "es2015": "./dist/esm2015/index.js". The esm5 does not use the class keyword and that's why you're getting this error. To fix it, I added the following config in my webpack.config.js file:

{
    resolve: {
        extensions: ['.ts', '.js'],
        alias: {
            tsyringe: require.resolve('tsyringe/dist/esm2015/index.js'),
        },
    },
}

@thiagoolsilva
Copy link

Thanks @ffortier . Your solution solves my problem.

@ckifer
Copy link

ckifer commented Nov 2, 2022

Not to resurrect this, but is there any way that this could be solved by the repository rather than by each user? Same issue today when running webpack but packing files for a Node runtime and using esbuild-loader. Why does it resolve to esm5 when our targets are higher?

@risen228
Copy link

I was unable to resolve this issue in Bun environment. There are no aliases and the only option is paths in tsconfig.json, but this causes types to break. So I made a fork: tsyringe-neo. The es2015 option does not work with modern tools and should not be used in 2024, it's not surprising that the package breaks with almost anything. In my fork, I adapted tsyringe to modern realities and now everything should work. The bundle size has also decreased, but I'm afraid that something might have broken on the ancient platforms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants