How to get webpack and babel to handle private typescript keyword?

Viewed 787

I have webpack and babel compiling typescript but they don't seem to know how to handle the private keyword in Typescript. They don't seem to have a problem with Typescript in general, I'm able to compile files. So I'm wondering if I need to do some config changes but googling is not helping.

How do you get webpack and babel to play nice with Typescript's private keyword?

.babelrc:

{
    "presets": [
        "@babel/preset-env",
        "@babel/preset-typescript",
        "@babel/preset-react"
    ],
    "plugins": [
        "@babel/plugin-transform-typescript",
        "@babel/proposal-class-properties",
        "@babel/proposal-object-rest-spread"
    ]
}

webpack.config.js: ...

{
            test: /\.(ts|js)x?$/,
            exclude: /node_modules/,
            use: {
                loader: 'babel-loader',
            },
        },

EDIT: There has been a request for reproduction details, I think this one is pretty easy to reproduce with what I've provided. I've seen it in the past and it has to do with babel-loader's quasi support of typescript. Create a class and add a private field to it. private whatever: string. That should be enough to make the unrecognized token error appear with the config I've provided.

EDIT 2: package.json as requested:

{
  "name": "blah",
  "version": "1.0.0",
  "description": "blah config",
  "main": "index.js",
  "scripts": {
    "bundle": "webpack",
    "start": "webpack-dev-server --config ./webpack.config.js --mode development",
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production",
    "check-types": "tsc"
  },
  "devDependencies": {
    "@babel/core": "^7.11.1",
    "@babel/plugin-proposal-class-properties": "^7.10.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.11.0",
    "@babel/preset-env": "^7.11.0",
    "@babel/preset-react": "^7.10.4",
    "@babel/preset-typescript": "^7.10.4",
    "babel-loader": "^8.1.0",
    "css-loader": "^4.2.1",
    "html-webpack-plugin": "^4.3.0",
    "style-loader": "^1.2.1",
    "tslint": "^6.1.3",
    "tslint-immutable": "^6.0.1",
    "typescript": "^3.9.7",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  },
  "dependencies": {
    "@types/react": "^16.9.46",
    "@types/react-dom": "^16.9.8",
    "react": "^16.13.1",
    "react-dom": "^16.13.1"
  }
}

Example of failure:

class Example {
 private anyField = 'danger';
}

Example of error message:

SyntaxError [path] Unexpected token (2:12)
  1 | class Example {
> 2 |     private anyField = 'danger';
    |             ^
1 Answers

Changing the directory that the file was in had some impact in how it was compiled. I'm not entirely sure how or why that had an impact. The file that had trouble with was on a directory branch two levels lower than the base webpack config that pointed to it. While files that were above the webpack.config allowed for private typescript keywords, the file below that directory level did not allow for a private keyword.

Perhaps the lower directory levels were being read as classic javascript despite the file extension for some reason?

By default the latest versions of the babel/webpack setup should allow Typescript compilation with both the private and readonly keywords. Though there was a time when babel had trouble with those keywords. If you're running into trouble consider experimenting with the directory structure. I'm guessing someone with more expertise might be able to tell me why the directory level matters even if the compilation starts where the configuration files are located.

Related