Decorators do not work inside packages

After successfully using decorators for a while inside the /imports directory with the use of the Babel ‘transform-decorators-legacy’-plugin, I found that they don’t work inside packages when I started to split my project into smaller parts.

When I import the decorators inside a local package (which are exported from another package) they do not work on (React Component) classes written inside that package (they work on React Components inside the /imports directory).

The package loads the ecmascript-package, and I have also tried to use the babel-runtime and babel-compiler packages, but without any difference.

Does anybody know what I am doing wrong?
Thanks for helping out!

For example, I have the following decorator exported from the ‘test-decorator’ package:

export function exampleDecorator(variable1) {
  console.log(variable1);
  return function (target) {
    console.log(target);
  };
}

When I use the decorator on a class inside the /imports directory, the console.log’s are shown.
Decorated class:

import { exampleDecorator } from 'meteor/test-decorator';

@exampleDecorator('variable1')
class UiMain extends Component {
}

But when I try the same code from inside a package, nothing is shown - but the component still works as expected (however, without the ‘extra decorations’). The .onUse configuration from the ‘destination’ package:

Package.onUse(function(api) {
  api.versionsFrom('1.4.4.2');
  api.use('ecmascript');
  
  api.use('test-decorator');
  
  api.mainModule('test-decorated-class.js');
});

Also when I place the decorator in the same file (inside the package) as the Component, nothing happens: it’s like the decorator line above the class definition is not there.

Try placing your babel configuration within a .babelrc file in your project root directory, instead of placing it inside your package.json file.

I already have a .babelrc file inside the root of the Meteor project (there is no Babel config in the root package.json file), which contains:

{
  "plugins": [
    "transform-decorators-legacy"
  ],
  "presets": ["stage-1"]
}

Hey @triplon sorry I was away from the forums for a while.

And yes you are right because my reply was incomplete.

There’s an interesting “hack” you need to provide to your packages to align them with your top level babel configuration.

cd packages/packagename
ln -s ../../.babelrc .babelrc
ln -s ../../node_modules node_modules

I know this sounds weird (and also cumbersome if you have lots of packages) but the idea is, packages are theoretically independent pieces of software and syntactically, they need to be provided their own node modules and configurations.

You see, it is in fact very similar to how you need to declare

api.use('ecmascript');

Even though ecmascript may be in your top level dependencies. Similarly, you need to be explicit in your package dependencies.

As such, you can create a different .babelrc file and install some node moduless within your package root, or if you are using packages for packages based application structuring, you can just go ahead and symlink to your top level ones and enjoy the consistency (alas, at a cost of some symlinking hassle)