Moves properties out of classes to prototypes, ensures not minified class name.
Works together with JavaScript AST processor hooks in requirejs-esm, requirejs-esm-preprocessor and backbone-class-syntax, for example.
Decorate a property to move it from the class instances to the class prototype:
class Class {
property1 = 42
@prototype
property2 = 42
}The result:
class Class {
property1 = 42
}
Object.assign(Class.prototype, {
property2 = 42
})Decorate a descendant of Backbone.Model to move the well-known properties from the class instances to the class prototype:
import { Model } from 'backbone'
@propertiesToPrototype('model')
class User extends Model {
defaults: {
name: 'unnamed'
}
}The result:
import { Model } from 'backbone'
class User extends Model {}
Object.assign(Class.prototype, {
defaults: {
name: 'unnamed'
}
})The class name will be preserved in the name of the constructor and survive the minification:
class Class {}The result:
class Class {}
Object.defineProperty(Class.prototype.constructor, 'name', {
value: 'Class'
})This module can be installed using a NPM package manager:
npm i properties-to-prototypeCall updateClassDeclarations to update an AST of a script:
import { readFile } from 'node:fs/promises'
import { parse } from 'meriyah'
import { generate } from 'astring'
import { updateClassDeclarations } from 'properties-to-prototype'
const input = await readFile('index.js', 'utf8')
const program = parse(input, { sourceType: 'module', next: true })
const { updated } = updateClassDeclarations(program)
if (updated) {
const output = generate(program)
}| Option | Default | Description |
|---|---|---|
| prototypeProperties | {} | Names of properties to move from the class body to a prototype assignment object by default according to the class type. |
| alternativePrototypeProperties | {} | Properties in this object will be merged to the prototypeProperties option, replacing the same class types. |
| additionalPrototypeProperties | {} | Properties in this object will be merged to the prototypeProperties option, appending to the same class types. |
| classDecorator | propertiesToPrototype |
Identifier of the decorator for marking a class for property processing. |
| removeClassDecorator | true |
Whether to remove the class decorator after processing. |
| prototypeDecorator | prototype |
Identifier of the decorator for marking a class field as a prototype property. |
| removePrototypeDecorator | true |
Whether to remove the prototype decorator after processing. |
| instanceDecorator | instance |
Identifier of the decorator for forcing a class field to remain as a class field. |
| removeInstanceDecorator | true |
Whether to remove the instance decorator after processing. |
| convertToPropertyGetters | false |
Whether to replace property values with property getters instead of moving the properties to a prototype object assignment statement. |
| classTypes | {} | Class names or regular expressions to infer the class type from. |
| classTypesByEnds | false |
Use the strings with class names as suffixes (endsWith) instead of full names (===). |
| alternativeClassTypes | {} | Properties in this object will be merged to the classTypes option, replacing the same class types. |
| additionalClassTypes | {} | Properties in this object will be merged to the classTypes option, appending to the same class types. |
| classifyClass | Function to compute the class type and optionally to customise the properties for moving from the class declaration to the prototype. | |
| shouldMoveProperty | Function to determine whether a property should be moved from the class body to the prototype assignment object. | |
| ensureConstructorNames | true |
Whether to set the name of the class constructor to the class name to preserve it after minification. |
| replaceConstructorName | false |
Whether to replace the constructor name even if it already exists but has a different value. |
Moves a class instance property to the class prototype.
class Class {
@prototype
property = 42
}Forces a class property, which would be otherwise moved to the class prototype, to stay in the class instances.
@propertiesToPrototype
class Class {
@instance
property = 42
}Moves well-known class instance properties of a particular class type to the class prototype.
@propertiesToPrototype('model')
class User extends Model {
defaults: {
name: 'unnamed'
}
}Specific class types can have their well-know properties moved to prototype object assignment statement by default. The structure is an object with class types as keys and arrays of property names as values. For example, for Backbone and Marionette:
{
model: [
'cidPrefix', 'defaults', 'idAttribute', 'url', 'urlRoot'
],
collection: [
'cidPrefix', 'model', 'comparator'
],
view: [
'cidPrefix', 'options', 'tagName', 'className', 'attributes', 'template',
'el', 'ui', 'regions', 'behaviors', 'templateContext', 'templateHelpers',
'events', 'modelEvents', 'collectionEvents', 'triggers',
'childViewContainer', 'childView', 'childViewOptions',
'childViewEventPrefix', 'childViewEvents', 'childViewTriggers',
'emptyView', 'emptyViewOptions',
'viewComparator', 'sortWithCollection', 'reorderOnSort', 'viewFilter'
],
behavior: [
'options', 'behaviors', 'ui', 'childViewEvents', 'childViewTriggers',
'events', 'modelEvents', 'collectionEvents', 'triggers'
],
router: [
'routes', 'appRoutes', 'controller'
],
controller: [
'cidPrefix', 'options', 'channelName', 'radioEvents', 'radioRequests'
],
application: [
'cidPrefix', 'region', 'regionClass'
]
}In lieu of a formal styleguide, take care to maintain the existing coding style. Lint and test your code.
Copyright (c) 2025 Ferdinand Prantl
Licensed under the MIT license.