Decoradores Webpack babel 6 ES6

101

Eu tenho um projeto escrito em ES6 com webpack como meu bundler. A maior parte da tradução funciona bem, mas quando tento incluir decoradores em qualquer lugar, recebo este erro:

Decorators are not supported yet in 6.x pending proposal update.

Eu olhei o rastreador de problemas do babel e não consegui encontrar nada nele, então presumo que esteja usando errado. Minha configuração do webpack (os bits relevantes):

loaders: [
  {
    loader: 'babel',
    exclude: /node_modules/,
    include: path.join(__dirname, 'src'),
    test: /\.jsx?$/,
    query: {
      plugins: ['transform-runtime'],
      presets: ['es2015', 'stage-0', 'react']
    }
  }
]

Não tenho problemas com mais nada, funções de seta, desestruturação tudo funciona bem, isso é a única coisa que não funciona.

Sei que sempre posso fazer o downgrade para o babel 5.8, onde estava funcionando há um tempo, mas se houver alguma maneira de fazer isso funcionar na versão atual (v6.2.0), isso ajudaria.

Pavlin
fonte
Achei que, desde que incluí a predefinição do estágio 0, eles seriam transformados de maneira adequada. Os decoradores fazem parte da predefinição do estágio 1 que deve incluir os decoradores de transformação. Conforme escrito no site da babel.
Pavlin de
@Pavlin Estou pensando se isso poderia ser um problema com o pedido de presets.
Sulthan de
Achei que pudesse ser isso, mas testei novamente. De qualquer forma, recebo um erro. Aparentemente, a ordem importa, mas não acho que seja esse o problema aqui.
Pavlin de

Respostas:

170

Este plugin do Babel funcionou para mim:

https://github.com/loganfsmyth/babel-plugin-transform-decorators-legacy

npm i --save-dev babel-plugin-transform-decorators-legacy

.babelrc

{
  "presets": ["es2015", "stage-0", "react"],
  "plugins": [
    ["transform-decorators-legacy"],
    // ...
  ]
}

ou

Webpack

{
  test: /\.jsx?$/,
  loader: 'babel',
  query: {
    cacheDirectory: true,
    plugins: ['transform-decorators-legacy' ],
    presets: ['es2015', 'stage-0', 'react']
  }
}

React Native

Com react-nativevocê deve usar o babel-preset-react-native-stage-0plugin.

npm i --save babel-preset-react-native-stage-0

.babelrc

{
  "presets": ["react-native-stage-0/decorator-support"]
}

Por favor, veja esta pergunta e resposta para uma explicação completa.

Kyle Finley
fonte
Você provavelmente não gostaria que o plugin fosse habilitado apenas para development.
loganfsmyth
Obrigado @loganfsmyth. Eu atualizei a resposta para incluir productiontambém
Kyle Finley
1
Quero dizer, por que colocá-lo em um envbloco afinal? Você pode ter pluginscomo irmão depresets
loganfsmyth
1
@ am5255, ainda parece estar funcionando para mim. Você se importaria de enviar um problema com o autor? github.com/loganfsmyth/babel-plugin-transform-decorators-legacy/…
Kyle Finley
1
Finalmente consegui fazer isso funcionar. Acontece que eu tive que instalar transform-class-propertiestambém babeljs.io/docs/plugins/transform-class-properties e também certificar-se de que o plug-in legado está antes do plug-in de classe de transformação conforme os documentos em github.com/loganfsmyth/babel-plugin- transform-decorators-legacy
reectrix
41

Depois de passar 5 minutos no webchat do slack do babeljs, descobri que os decoradores estão corrompidos na versão atual do babel (v6.2). A única solução parece ser fazer o downgrade para 5.8 neste momento.

Também parece que eles moveram o rastreador de problemas do github para https://phabricator.babeljs.io

Escrevo tudo isso, pois depois de horas de pesquisa, descobri que a documentação atual é muito pobre e insuficiente.

Pavlin
fonte
6
A partir desse problema, um plug-in legado de "melhor esforço com limitações" foi feito. Consulte o leia-me para limitações: npmjs.com/package/babel-plugin-transform-decorators-legacy
Jason
Posso confirmar que o legado dos decoradores de transformação está funcionando para mim como uma solução provisória.
dvlsg
@Pavlin, embora sua resposta possa estar correta, o plugin listado abaixo deve ser a resposta aceita por enquanto.
Ajax
8

Instalar apenas babel-plugin-transform-decorators-legacynão funcionou para mim (eu tenho uma configuração usando enzima junto com karma). Acontece que a instalação de transform-class-properties: transform-class-properties e também certificando-se de que o plug-in legado está antes do plug-in de classe transform de acordo com os documentos em transform-decorators-legacy finalmente fez com que funcionasse para mim.

Também não estou usando um .babelrcarquivo, mas adicionar isso ao meu karma.conf.jsarquivo funcionou para mim:

babelPreprocessor: {
  options: {
    presets: ['airbnb', 'es2015', 'stage-0', 'react'],
    plugins: ["transform-decorators-legacy", "transform-class-properties"]
  }
}

Eu também adicionei aos meus carregadores:

loaders: [
  {
    test: /\.js$/,
    loader: 'babel',
    exclude: path.resolve(__dirname, 'node_modules'),
    query: {
      presets: ['airbnb', 'es2015', 'stage-0', 'react'],
      plugins: ["transform-decorators-legacy", "transform-class-properties"]
    }
  },
reectrix
fonte
1
Passei uma hora aqui e ali e essas coisas funcionaram para mim. Muito obrigado
cjmling de
3

Você só precisa de um plugin de decoradores de transformação: http://babeljs.io/docs/plugins/transform-decorators/

ainda um
fonte
1
Ainda falhou para mim com isso.
amcdnl
3
@amcdnl minha impressão é que o plug-in de decoradores de transformação é o oficial, mas não foi implementado devido às restrições TC39, enquanto isso há isso - github.com/loganfsmyth/babel-plugin-transform-decorators-legacy
Qiming
@Qiming yup isso é o que eu acabei usando e o oficial do babel até diz que se você cavar longe o suficiente .. ideia terrível da parte deles imo
amcdnl
1

Se você atualizou seu projeto do Babel 6 para o Babel 7, você deseja instalar @babel/plugin-proposal-decorators.

Se você deseja oferecer suporte a decoradores legados como usados ​​no Babel 5, você precisa configurar seu da .babelrcseguinte forma:

plugins: [
      ['@babel/plugin-proposal-decorators', { legacy: true }],
      ['@babel/plugin-proposal-class-properties', { loose: true }],
]

Certifique-se de @babel/plugin-proposal-decoratorsvir antes, se @babel/plugin-proposal-class-propertiesvocê estiver usando o último.

codejockie
fonte