UglifyJS lança token inesperado: palavra-chave (const) com node_modules

90

Um pequeno projeto que comecei faz uso de um módulo de nó (instalado via npm ) que declara constvariáveis. Executar e testar este projeto está bem, mas o browserify falha quando o UglifyJS é executado.

Token inesperado: palavra-chave (const)

Aqui está um arquivo Gulp genérico que tenho usado com sucesso em alguns outros projetos anteriores sem esse problema (ou seja, sem aquele módulo de nó específico).

gulpfile.js

'use strict';

const browserify = require('browserify');
const gulp = require('gulp');
const source = require('vinyl-source-stream');
const derequire = require('gulp-derequire');
const buffer = require('vinyl-buffer');
const uglify = require('gulp-uglify');
const sourcemaps = require('gulp-sourcemaps');
const gutil = require('gulp-util');
const path = require('path');
const pkg = require('./package');
const upperCamelCase = require('uppercamelcase');

const SRC_PATH = path.dirname(pkg.main);
const DIST_PATH = path.dirname(pkg.browser);

const INPUT_FILE = path.basename(pkg.main);
const OUTPUT_FILE = path.basename(pkg.browser);

const MODULE_NAME = upperCamelCase(pkg.name);


gulp.task('default', () => {
  // set up the browserify instance on a task basis
  var b = browserify({
    entries: INPUT_FILE,
    basedir: SRC_PATH,
    transform: ['babelify'],
    standalone: MODULE_NAME,
    debug: true
  });

  return b.bundle()
    .pipe(source(OUTPUT_FILE))
    .pipe(buffer())
    .pipe(derequire())
    .pipe(sourcemaps.init({loadMaps: true}))
    .pipe(uglify())
    .on('error', gutil.log)
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(DIST_PATH))
  ;
});

Eu tentei corrigir isso por substituir toda consta varem que o módulo instalado de NPM, e está tudo bem. Então, eu não entendo o fracasso.

O que há de errado const? A menos que alguém use o IE10, todos os principais navegadores suportam essa sintaxe.

Existe uma maneira de corrigir isso sem exigir uma alteração nesse módulo de nó?

Atualizar

Substituí temporariamente (ou permanentemente) o UglifyJS pelo Butternut e pareço funcionar.

Yanick Rochon
fonte
Não é um problema com a versão do nó? Você não precisa gostar do nó 8+ para ter constdisponível? (não tenho certeza de quando foi realmente introduzido)
laurent
Tenho usado constdesde a v4. E atualmente estou usando 8.9.1 LTS.
Yanick Rochon
Ok, isso é estranho então. Qual é a mensagem de erro que você está vendo?
Laurent
@ this.lau_ a mesma mensagem de erro do título, mas também a adicionei à pergunta para maior clareza.
Yanick Rochon de
Não precisa necessariamente ser sobre o 'const'. Pode ser um dos módulos que você precisa.
James

Respostas:

92

Como ChrisR mencionou , o UglifyJS não oferece suporte a ES6.

Você precisa usar o plugin terser-webpack para ES6 (webpack @ 5 usará este plugin para uglificação)

npm install terser-webpack-plugin --save-dev

Em seguida, defina em sua pluginsmatriz

const TerserPlugin = require('terser-webpack-plugin')

  new TerserPlugin({
    parallel: true,
    terserOptions: {
      ecma: 6,
    },
  }),

Fonte

Ser
fonte
1
Talvez você deva sugerir npm install --save-dev terser-webpack-plugin.
Rafa
2
Agradeço muito essa resposta porque me lembrou da terserbiblioteca que terser-webpack-pluginusa por baixo. Nota para os outros: terserpode ser usado autônomo como cli exatamente como uglify-jsestava (ou seja, o webpack não é um requisito) que era exatamente o que eu precisava.
John Lee de
1
mas precisamos usar o webpack para usar essa solução?
Enrique
@enrique depende do que você quer fazer, para construir um site que corresponda às necessidades reais de negócios, você deve definitivamente experimentar o webpack. Tivemos esse problema na comunidade do webpack, então minha resposta foi bem avaliada, mas tecnicamente você não precisa do webpack para construir o código ES6
Ser
Terser foi escolhido a dedo para webpack @ 4 em github.com/webpack/webpack/pull/8392
Trivikram
39

O UglifyJS não oferece suporte a es6. consté uma declaração es6, portanto, gera um erro.

O que é estranho é que o pacote que você usa não transpila seus arquivos para es5 para serem usados ​​em qualquer lugar.

Se você ainda quiser usar o UglifyJS (para reutilizar a configuração, por exemplo), use a versão compatível com ES6 +, uglify-es . ( Aviso : agorauglify-es está abandonado .)

E como Ser mencionou , agora você deve usar terser-webpack-plugin.

ChrisR
fonte
3
Você também pode substituir gulp-uglifypor gulp-uglify-es: npmjs.com/package/gulp-uglify-es
ChrisR
3
UglifyJS does not support es6 . Obrigado! Não consegui encontrar essa informação em lugar nenhum.
Karl Pokus de
use gulp-terserse a migração para o webpack estiver fora do seu orçamento.
Riki137
7

Eu tive o mesmo problema e o plugin gulp gulp-uglify-es resolveu o problema.

Acho que é a decisão mais simples.

Basta instalar:

npm i gulp-uglify-es --save-dev

depois disso, no seu código, altere apenas esta linha

const uglify = require('gulp-uglify');

para isso:

const uglify = require('gulp-uglify-es').default;

NB propriedade .default é crucial, caso contrário você terá um erro de que o uglify não é uma função.

Como mencionado acima e como parte do operador const ES6 , só pode ser processado por um plugin es6 gulp mais moderno "gulp-uglify-es"

O resto do seu código não precisa ser alterado.

Cumprimentos!

Christiyan
fonte
testado e trabalhando com "node: v12.14", "gulp cli v2.2.1", "gulp local v4.0.2".
ioojimooi
2

Acabei de ter esse problema com um projeto Gulp que refatorou e, por algum motivo, estava tendo problemas com o plugin oficial do Terser Gulp. Este (gulp-terser) funcionou sem problemas.

NetOperator Wibby
fonte
0

Usar o plugin uglify-es-webpack é melhor

    const UglifyEsPlugin = require('uglify-es-webpack-plugin')



    module.exports = {
    plugins: [
            new UglifyEsPlugin({
                compress:{
                    drop_console: true
                }
            }),
    ] 
    }
NEO ViSiON
fonte
7
Esta é uma opinião, explique por que é melhor.
ChrisR
0

Eu substituí UglifyJScom YUI Compressor JSdentro da GUI do PHPStorm .. Funciona agora.

Sjoerd
fonte
0

Eu realmente não acho que essa abordagem seja boa, mas no meu caso eu precisava fazer isso uma vez e esquecer aquilo, então eu apenas fui ao site da babel , transpilei es6 para es5 online e substituí a saída!

Gh111
fonte