UglifyJS generuje nieoczekiwany token: słowo kluczowe (const) z node_modules

90

Mały projekt, który zacząłem, wykorzystuje moduł węzła (zainstalowany przez npm ), który deklaruje constzmienne. Uruchamianie i testowanie tego projektu przebiega dobrze, ale browserify kończy się niepowodzeniem po uruchomieniu UglifyJS.

Nieoczekiwany token: słowo kluczowe (stała)

Oto ogólny plik Gulp, którego z powodzeniem używałem w kilku innych poprzednich projektach bez tego problemu (tj. Bez tego konkretnego modułu węzła).

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

Próbowałem to naprawić, zamieniając wszystko constna varw tym zainstalowanym module npm i wszystko jest w porządku. Więc nie rozumiem niepowodzenia.

Co jest nie tak const? O ile ktoś nie używa IE10, wszystkie główne przeglądarki obsługują tę składnię.

Czy istnieje sposób, aby to naprawić bez konieczności zmiany tego modułu węzła?

Aktualizacja

Tymczasowo (lub na stałe) zastąpiłem UglifyJS Butternut i wydaje się, że działa.

Yanick Rochon
źródło
Czy to nie problem z wersją węzła? Czy nie potrzebujesz takiego węzła 8+, aby był constdostępny? (nie jestem pewien, kiedy faktycznie został wprowadzony)
laurent
Używam constod wersji 4. Obecnie używam 8.9.1 LTS.
Yanick Rochon
Ok, to dziwne. Jaki jest komunikat o błędzie, który widzisz?
laurent
@ this.lau_ ten sam komunikat o błędzie jak w tytule, ale dodałem go również w pytaniu dla jasności.
Yanick Rochon
Nie musi to koniecznie dotyczyć „const”. Może to być jeden z wymaganych modułów.
James

Odpowiedzi:

92

Jak wspomniał ChrisR , UglifyJS w ogóle nie obsługuje ES6.

Musisz użyć wtyczki terser-webpack-plugin dla ES6 (webpack @ 5 użyje tej wtyczki do uglifikacji)

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

Następnie zdefiniuj w swojej pluginstablicy

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

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

Źródło

Ser
źródło
1
Może powinieneś zasugerować npm install --save-dev terser-webpack-plugin.
Rafa
2
Naprawdę doceniam tę odpowiedź, ponieważ przypomniała mi o terserlib terser-webpack-pluginużywanej pod spodem. Uwaga dla innych: tersermoże być używany samodzielnie jako cli, tak jak uglify-jsbył (tj. Webpack nie jest wymagany), co było dokładnie tym, czego potrzebowałem.
John Lee,
1
ale musimy użyć webpacka, aby skorzystać z tego rozwiązania?
Enrique
@enrique zależy od tego, co chcesz zrobić, aby zbudować stronę internetową odpowiadającą rzeczywistym potrzebom biznesowym, zdecydowanie powinieneś wypróbować pakiet webpack. Mieliśmy ten problem w społeczności webpack, więc moja odpowiedź jest dobrze oceniona, ale technicznie nie potrzebujesz pakietu webpacka do zbudowania kodu ES6
Ser
Terser został wybrany do webpack @ 4 na github.com/webpack/webpack/pull/8392
Trivikram,
39

UglifyJS nie obsługuje es6. constjest deklaracją es6, więc zgłasza błąd.

Dziwne jest to, że pakiet, którego używasz, nie transponuje swoich plików do es5 w celu użycia w dowolnym miejscu.

Jeśli chcesz nadal używać UglifyJS (na przykład w celu ponownego wykorzystania konfiguracji), użyj wersji zgodnej z ES6 +, uglify-es . ( Ostrzeżenie : uglify-esjest teraz opuszczony .)

I jak wspomniał Ser , powinieneś teraz użyć terser-webpack-plugin.

ChrisR
źródło
3
Możesz również zamienić gulp-uglifyna gulp-uglify-es: npmjs.com/package/gulp-uglify-es
ChrisR
3
UglifyJS does not support es6 . Dziękuję Ci! Nigdzie nie mogłem znaleźć tej informacji.
Karl Pokus
użyj, gulp-terserjeśli migracja do WebPacka przekracza Twój budżet.
Riki137
7

Miałem ten sam problem i gulp plugin gulp-uglify-es rozwiązała problem.

Myślę, że to najprostsza decyzja.

Wystarczy zainstalować:

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

po tym w swoim kodzie zmień tylko tę linię

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

do tego:

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

Właściwość NB .default jest kluczowa, w przeciwnym razie wystąpi błąd, że uglify nie jest funkcją.

Jak wspomniano powyżej i jako część operatora const ES6 może być przetwarzane tylko przez nowocześniejszą wtyczkę es6 gulp „gulp-uglify-es”

Reszta kodu nie musi być zmieniana.

Z poważaniem!

Christiyan
źródło
przetestowane i współpracujące z „node: v12.14”, „gulp cli v2.2.1”, „gulp local v4.0.2”.
ioojimooi
2

Właśnie miałem ten problem z projektem Gulp, który refaktoryzowałem iz jakiegoś powodu miałem problem z oficjalną wtyczką Terser Gulp. Ten (łyk-terser) działał bez problemów.

NetOperator Wibby
źródło
0

Użyj wtyczki uglify-es-webpack-plugin

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



    module.exports = {
    plugins: [
            new UglifyEsPlugin({
                compress:{
                    drop_console: true
                }
            }),
    ] 
    }
NEO ViSiON
źródło
7
To jest opinia, proszę wyjaśnić, dlaczego jest lepiej.
ChrisR
0

Wymieniłem UglifyJSz YUI Compressor JSwewnątrz GUI PHPStorm .. To działa teraz.

Sjoerd
źródło
0

Nie wydaje mi się, żeby to podejście było dobre, ale w moim przypadku musiałem to zrobić raz i zapomnieć o tym, więc po prostu wszedłem na stronę babel , transpile es6 do es5 online i zastąpiłem wyjście!

Gh111
źródło