Use babel to remove ES6 Class no-use properties when bundle your code
frustigor
Posted on December 6, 2019
In some situation, when we bundle our code, we find some properties of a class are not needed in our project. For example, we wrote a class:
export default class A {
a = 1
static b = 2
c() {}
static d() {}
e() {
return false
}
}
And we use it in our project like:
import A from './a'
const a = new A()
a.e()
We did not invoke a
b
c
d
of class A
, but now, we have no idea to shake this methods/properties away from our code. Even through we have tree shaking, the tool like webpack has no idea to shake this no-use properties, it does not know which properties are used, and which are not.
After searching for ways to remove no-use properties, I did not find any good plugins or tools, so I have to write one, and published it as name babel-plugin-shake-class-properties
and you can use it very easy.
npm i -D babel-plugin-shake-class-properties
And then modify your babel.config.js. (We only support babel.config.js because we need to point out the file's absolute path.)
// babel.config.js
const path = require('path')
module.exports = {
...
plugins: [
['babel-plugin-shake-class-properties', {
// the only properties we want to keep, other properties will be removed (except constructor)
retain: [
{
file: path.resolve(__dirname, 'node_modules/tyshemo/src/store.js'), // the file's absolute path to match
class: 'Store', // the class name from which properties will be removed
properties: ['update', 'set'], // the properties which will be kept
},
],
// the properties we want to remove, properties even in `retain` will be removed
remove: [
{
file: path.resolve(__dirname, 'node_modules/tyshemo/src/store.js'),
class: 'Store',
properties: ['update', 'set'], // the properties which will be removed
},
],
}],
...
],
}
In a item string of properties, you can use static async get set * keywords to match certain properties, for example:
class A {
static a = 1
get name() {}
set name() {}
* f() {}
async fetch() {}
async * r() {}
static async * p() {}
static get e() {}
}
If you want to remove all properties, aha?? you should use retain
with properties: ['']
, however, to match strict, you could do like:
remove: {
...
properties: [
'static a',
'get name',
'set name',
'* f',
'async fetch',
'async * r',
'static async * p',
'static get e',
],
}
Notice here, there should must be a space ' ' between *
and the name of property.
Only ES6+ source class properties will be matched. The following situation will not work with this plugin. Computed properties will not work as possible:
class A {
// will never be remove
constructor() {
// will not be realized
this.a = '1'
}
// will not be realized
[`some${a}`]() {}
// will not be realized
[Symbol('xxx')]() {}
// will be treated as dd
'dd'() {}
// will be treated as ["dd"]
['dd']() {}
// will be treated as [dd]
[dd]() {}
// will be treated as [dd]
[dd] = 1
// will be treated as ["dd"]
['dd'] = 1
}
function B() {}
// will not be realized
B.prototype.a = function() {}
// will not be realized
// you can use https://github.com/tangshuang/babel-plugin-transform-class-remove-static-properties to remove this
B.b = 'xxx'
If you are interested in this project, follow it on github https://github.com/tangshuang/babel-plugin-shake-class-properties and give a star.
Posted on December 6, 2019
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.