UglifyJS arroja un token inesperado: palabra clave (const) con node_modules

90

Un pequeño proyecto que comencé hace uso de un módulo de nodo (instalado a través de npm ) que declara constvariables. Ejecutar y probar este proyecto está bien, pero browserify falla cuando se ejecuta UglifyJS.

Token inesperado: palabra clave (const)

Aquí hay un archivo Gulp genérico que he estado usando con éxito para algunos otros proyectos anteriores sin este problema (es decir, sin ese módulo de nodo en particular).

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))
  ;
});

He intentado solucionar este substituyen todo el constque varen ese módulo NPM-instalado, y todo está bien. Entonces no entiendo el fracaso.

¿Qué pasa con const? A menos que alguien use IE10, todos los navegadores principales admiten esta sintaxis.

¿Hay alguna manera de solucionar este problema sin requerir un cambio en ese módulo de nodo?

Actualizar

He reemplazado temporalmente (o permanentemente) UglifyJS con Butternut y parece que funciona.

Yanick Rochon
fuente
¿No es un problema con la versión del nodo? ¿No necesitas como nodo 8+ para tener constdisponible? (no estoy seguro de cuándo se presentó)
laurent
Lo he estado usando constdesde v4. Y actualmente estoy usando 8.9.1 LTS.
Yanick Rochon
Ok, eso es extraño entonces. ¿Cuál es el mensaje de error que está viendo?
Laurent
@ this.lau_ el mismo mensaje de error que en el título, pero también lo agregué en la pregunta para mayor claridad.
Yanick Rochon
No tiene que tratarse necesariamente de la 'constante'. Podría ser uno de los módulos que necesita.
James

Respuestas:

92

Como mencionó ChrisR , UglifyJS no es compatible con ES6 en absoluto.

Necesita usar terser-webpack-plugin para ES6 (webpack @ 5 usará este complemento para uglification)

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

Luego defina en su pluginsmatriz

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

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

Fuente

Ser
fuente
1
Quizás deberías sugerir npm install --save-dev terser-webpack-plugin.
Rafa
2
Realmente aprecio esta respuesta porque me recordó la terserlib que se terser-webpack-pluginusa debajo. Nota para otros: terserse puede usar de forma independiente como cli tal como uglify-jsestaba (es decir, el paquete web no es un requisito), que era exactamente lo que necesitaba.
John Lee
1
pero necesitamos usar webpack para usar esta solución?
Enrique
@enrique depende de lo que quieras hacer, para crear un sitio web que se adapte a las necesidades comerciales reales, definitivamente debes probar el paquete web. Tuvimos ese problema en la comunidad de paquetes web, por lo que mi respuesta está bien calificada, pero técnicamente no necesita el paquete web para compilar el código ES6
Ser
Terser fue elegido para webpack @ 4 en github.com/webpack/webpack/pull/8392
Trivikram
39

UglifyJS no es compatible con es6. constes una declaración es6, por lo que arroja un error.

Lo extraño es que el paquete que usa no transpila sus archivos a es5 para usarlos en cualquier lugar.

Si aún desea usar UglifyJS (para reutilizar la configuración, por ejemplo) use la versión compatible con ES6 +, uglify-es . ( Advertencia : ahorauglify-es está abandonado ).

Y como mencionó Ser , ahora debería usar terser-webpack-plugin.

ChrisR
fuente
3
También puede reemplazar gulp-uglifypor gulp-uglify-es: npmjs.com/package/gulp-uglify-es
ChrisR
3
UglifyJS does not support es6 . ¡Gracias! No pude encontrar esa información en ningún lado.
Karl Pokus
utilícelo gulp-tersersi la migración a paquete web está fuera de su presupuesto.
Riki137
7

Tuve el mismo problema y el complemento gulp gulp-uglify-es resolvió el problema.

Creo que es la decisión más sencilla.

Simplemente instale:

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

después de eso en su código, cambie solo esta línea

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

a esto:

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

NB property .default es crucial, de lo contrario, tendrá un error de que uglify no es una función.

Como se mencionó anteriormente y como parte del operador const de ES6 , solo puede ser procesado por el plugin gulp "gulp-uglify-es" más moderno

No es necesario modificar el resto de su código.

¡Atentamente!

Christiyan
fuente
probado y trabajando con "nodo: v12.14", "gulp cli v2.2.1", "gulp local v4.0.2".
ioojimooi
2

Acabo de tener este problema con un proyecto de Gulp que refactoricé y, por alguna razón, estaba teniendo problemas con el complemento oficial de Terser Gulp. Este (gulp-terser) funcionó sin problemas.

NetOperator Wibby
fuente
0

Usar uglify-es-webpack-plugin es mejor

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



    module.exports = {
    plugins: [
            new UglifyEsPlugin({
                compress:{
                    drop_console: true
                }
            }),
    ] 
    }
NEO VISIÓN
fuente
7
Esta es una opinión, por favor explique por qué es mejor.
ChrisR
0

He reemplazado UglifyJScon YUI Compressor JSdentro de la GUI de PHPStorm .. Funciona ahora.

Sjoerd
fuente
0

Realmente no creo que este enfoque sea bueno, pero en mi caso necesitaba hacer esto una vez y olvidarme de eso, así que simplemente fui al sitio web de babel , transpile es6 a es5 en línea y reemplacé la salida.

Gh111
fuente