Issue 1:
Hi,

i am new to node packages and i am trying to build the packages and i spent my whole day to find out what might be the issue but i am unable to sort it out. below is my package.json file

{
"private": true,
"scripts": {
"dev": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"watch": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --watch --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
"production-noprogress": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},
"dependencies": {
"@babel/core": "^7.12.10",
"@ungap/url-search-params": "^0.1.2",
"@vimeo/player": "^2.0.1",
"axios": "^0.21.1",
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-polyfill": "^6.26.0",

"babel-preset-es2015": "^6.24.1",
"bootstrap": "^4.1.1",
"bootstrap-daterangepicker": "2.1.27",
"bootstrap-sass": "^3.3.7",
"bootstrap-select": "^1.13.8",
"bugsnag-sourcemap-webpack-plugin": "^0.9.7",
"countup.js": "^1.9.3",
"cross-env": "^3.2.3",
"css-loader": "^0.28.11",
"dotenv": "^5.0.1",
"eonasdan-bootstrap-datetimepicker": "^4.17.47",
"font-awesome": "^4.7.0",
"img-loader": "^2.0.0",
"intl-tel-input": "^12.1.10",
"jquery": "^3.3.1",
"jquery-toast-plugin": "^1.3.2",
"js-cookie": "^2.1.0",
"laravel-mix": "2.1.14",
"metismenu": "^2.7.8",
"modernizr": "^3.6.0",
"moment": "^2.17.1",
"moment-timezone": "^0.4.0",
"normalize.css": "^8.0.1",
"nouislider": "^10.0.0",
"numeral": "^2.0.6",
"object.entries": "^1.0.4",
"outdated-browser-rework": "^2.9.0",
"pace-progress": "^1.0.2",
"perfect-scrollbar": "0.8.1",
"popper.js": "^1.14.3",
"promise": "^7.1.1",
"scrollreveal": "3.4.0",
"slick-carousel": "1.6.0",
"sweetalert2": "^7.24.4",
"trix": "^1.0.0",
"ua-parser-js": "^0.7.20",
"underscore": "^1.8.3",
"urijs": "^1.17.0",
"v-img": "^0.2.0",
"vee-validate": "^2.1.0-beta.2",
"vue": "^2.2.4",
"vue-flatpickr-component": "^8.0.0",
"vue-infinite-scroll": "^2.0.0",
"vue-l-carousel": "^1.0.1",
"vue-loader": "^11.1.4",
"vue-multiselect": "^2.1.0",
"vue-template-compiler": "^2.2.4",
"vuex": "^3.0.1",
"weakmap-polyfill": "^2.0.0"
},
"devDependencies": {
"@babel/preset-env": "^7.12.11",
"babel-core": "^6.26.3",
"babel-loader": "^8.2.2",
"less": "^3.0.1",
"less-loader": "^4.1.0"
}
}

Issue 2:
💻

Would you like to work on a fix?

How are you using Babel?

Programmatic API (babel.transform, babel.parse)

Input code

fn(class WorkerClient {
static #worker_threads() {
return WorkerClient;
}
});

REPL

Configuration file name

No response

Configuration

{
"plugins": [
"@babel/plugin-proposal-private-methods",
"@babel/plugin-proposal-class-properties"
]
}

Current and expected behavior

It is compiled to this:

var _class;

fn(_class = class WorkerClient {});

function _worker_threads() {
return WorkerClient;
}

As you can see, WorkerClient is not reachable. It should be compiled to something like this:

var _class;

fn(_class = class WorkerClient {});

function _worker_threads() {
return _class;
}

Environment

Babel 7.14.4

Possible solution

In the replaceThisContext function that we use to replace this usage in class fields and private methods:

babel/packages/babel-helper-create-class-features-plugin/src/fields.ts

Line 672
in
813f2a3

function replaceThisContext(

we should add a new path.traverse call to replace references to the inner binding, with a visitor similar to this one:

const innerReferencesVisitor = {
ReferencedIdentifier(path, state) {
const { name } = path.node;
if (path.scope.bindingIdentifierEquals(name, state.innerBinding)) {
state.needsClassRef = true;
path.replaceWith(t.cloneNode(state.classRef));
}
},
};

where state is the one used by thisContextVisitor with the addition of state.innerBinding, which is the node representing the id of the class expression.

Note that we don't need to merge this visitor with environmentVisitor: environmentVisitor is only needed to avoid replacing nested thises that don't refer to the class, while for normal bindings we use path.scope.bindingIdentifierEquals.

We can get innerBinding from right before extracting the class reference at

babel/packages/babel-helper-create-class-features-plugin/src/index.ts

Lines 173 to 178
in
813f2a3

if (path.isClassExpression() || !path.node.id) {

nameFunction(path);

ref = path.scope.generateUidIdentifier("class");

} else {

ref = t.cloneNode(path.node.id);

}

We only need to get it if we have a ClassExpression and path.node.id is set, otherwise we can leave innerBinding as undefined and use it as a "signal" to skip the new path.traverse call.

After working on the fix itself, we'll need a bunch of tests:

A simple input.js/output.js test, for example my original example

An exec.js test, to check that the binding is the correct one. For example:

let x = class Test {
static #getTest() { return Test }
static getTest() { return this.getTest() }
};

expect(x.getTest()).toBe(x);

An input/output test to verify that it works when the binding is used in nested scopes, for example:

let x = class Test {
static #method() {
return function inner() {
return Test;
};
}
}

An input/output test to verify that it doesn't rewrite shadowed bindings:

let x = class Test {
static #method() {
new Test();

return function inner() {
let Test = 2;
return Test;
};
}
}

Additional context

The same bug happens with static class fields (both public and private) and instance private methods:

fn(class WorkerClient {
static #x = WorkerClient;
static y = WorkerClient;
});

we should duplicate the tests for those cases.