tsyringe
tsyringe copied to clipboard
Webpack/Babel can't handle '@' in constructor
Describe the bug
Attempting to generate a react build via webpack and babel-loader fails when there's a parameter decorator in the constructor - even though I included the 'babel-plugin-transform-typescript-metadata' plugin. The workaround is obviously to not include the inject parameter decorator in the constructor and DI manually (which works so I'm unblocked), but this seems like a bug that should be tracked nonetheless?
I've originally referred to this closed issue: https://github.com/microsoft/tsyringe/issues/142 which still did not resolve my issue.
Generated output:
> [email protected] build
> react-scripts build
Creating an optimized production build...
Failed to compile.
Module parse failed: Unexpected character '@' (1:422)
File was processed with these loaders:
* ./node_modules/babel-loader/lib/index.js
* ./node_modules/source-map-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
> import _createClass from"D:/projects/app/node_modules/@babel/runtime/helpers/esm/createClass.js";
import _classCallCheck from"D:/projects/app/node_modules/@babel/runtime/helpers/esm/classCallCheck.js";
var _dec,_class;import"reflect-metadata";import{inject,singleton}from'tsyringe';
export var App=(_dec=singleton(),_dec(_class=
/*#__PURE__*/_createClass(function App(@inject("Store")storeService){_classCallCheck(this,App);this.storeService=void 0;}
To Reproduce
Generate a build by invoking react-scripts build
with the configured webpack.config.js and .babelrc
import "reflect-metadata";
import { container, inject, singleton } from 'tsyringe'
@singleton()
export class App {
storeService: typeof store
constructor(@inject("Store") storeService: typeof store) {}
}
webpack.config.js
const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
module.exports = ({ mode } = { mode: "production" }) => {
console.log(`mode is: ${mode}`);
return {
mode,
entry: "./src/index.tsx",
devtool: 'inline-source-map',
output: {
publicPath: "/",
path: path.resolve(__dirname, "dist"),
filename: "bundle.js"
},
devServer: {
static: [
{ directory: path.join(__dirname, 'public') },
{ directory: path.join(__dirname, 'src/common') }
],
compress: true,
hot: true,
watchFiles: {
paths: ['src/common/**/*.ts'],
options: {
usePolling: false
}
},
// open: true,
port: 3030
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
},
module: {
rules: [
{
test: /\.css$/i,
exclude: /node_modules/,
use: ["style-loader", "css-loader"],
},
{
test: /\.svg$/,
exclude: /node_modules/,
loader: "svg-url-loader",
},
{
test: /\.jpe?g|png|ico$/,
exclude: /node_modules/,
use: ["url-loader", "file-loader"]
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: "babel-loader",
options: {
plugins: ['react-refresh/babel'],
},
},
{
test: /\.(ts|tsx)$/,
use: [
{
loader: 'ts-loader',
options: {
transpileOnly: true
}
}
],
exclude: /node_modules/,
},
]
},
plugins: [
new HtmlWebpackPlugin({
template: "./public/index.html",
manifest: "./public/manifest.json",
favicon: "./public/favicon.ico"
}),
]
}
};
tsconfig.json
{
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "es5",
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": false,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false,
"jsx": "react-jsx",
"sourceMap": true,
"outDir": "./dist/"
},
}
.babelrc
{
"presets": [
"@babel/preset-react",
[
"@babel/preset-env",
{
"targets": {
"browsers": "last 2 versions"
},
"modules": false,
"loose": false
}
]
],
"plugins": [
"transform-class-properties",
"babel-plugin-transform-typescript-metadata",
],
"env": {
"test": {
"plugins": [
"transform-es2015-modules-commonjs"
]
}
}
}
Expected behavior
Be able to generate a webpack build using parameter decorators. Version: "tsyringe": "^4.7.0", "webpack": "^5.74.0", "@babel/core": "^7.19.3", "@babel/plugin-proposal-class-properties": "^7.18.6", "@babel/plugin-proposal-decorators": "^7.20.13", "@babel/plugin-proposal-object-rest-spread": "^7.20.7", "@babel/preset-env": "^7.20.2", "@babel/preset-react": "^7.18.6", "@babel/preset-typescript": "^7.18.6", "babel-loader": "^8.2.5", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "babel-plugin-transform-typescript-metadata": "^0.3.2",