I am trying to use gulp in order to minify a folder containing JS files. However, one of the files has the above error, preventing it from being minified.
I managed to catch and print the error, which I've partially printed here:
JS_Parse_Error {
message: 'SyntaxError: Unexpected token: punc ())',
filename: 'ex.js',
line: 189,
col: 25,
pos: 6482,
stack: Error\n at new JS_Parse_Error (eval at <anonymous> ... )
plugin: 'gulp-uglify',
fileName: '.../js/ex.js',
showStack: false
}
The file in question contains the following, shortened:
function() {
...
$.confirm({
buttons: {
confirm: function() {
$.post('/ajax-handler', {
...
})
.done( function(response) {
var data = filterResponse(response);
if (data['status'] == 'success') {
sleep(1000).then(() => {
* ...
});
sleep(5000).then(() => {
...
});
} else {
console.log('Oops!');
}
})
.fail( function(err, status, response) {
...
});
},
cancel: function() {}
}
});
...
}
I added the "*" above in order to indicate the exact position listed by JS_Parse_Error.
// Update
From the comments ~ #imolit
v2.0.0 (2018-09-14) - BREAKING CHANGES (link)
Switch back to uglify-js (uglify-es is abandoned, if you need uglify ES6 code please use terser-webpack-plugin).
Original answer before the update...
I hope you can get inspired by this solution which works with webpack. (link below)
Simply teach UglifyJS ES6
There are two versions of UglifyJS - ES5 and ES6 (Harmony), see on git
ES5 version comes by default with all the plugins, but if you install a Harmony version explicitly, those plugins will use it instead.
package.json
"uglify-js": "git+https://github.com/mishoo/UglifyJS2.git#harmony"
or
npm install --save uglify-js#github:mishoo/UglifyJS2#harmony
yarn add git://github.com/mishoo/UglifyJS2#harmony --dev
Webpack
To use it with webpack install also the webpack plugin
npm install uglifyjs-webpack-plugin --save-dev
yarn add uglifyjs-webpack-plugin --dev
then import the manually installed plugin
var UglifyJSPlugin = require('uglifyjs-webpack-plugin');
and replace it in code
- new webpack.optimize.UglifyJsPlugin({ ... })
+ new UglifyJSPlugin({ ... })
For more webpack info (Installation/Usage) see https://github.com/webpack-contrib/uglifyjs-webpack-plugin#install
npm install uglifyjs-webpack-plugin --save-dev is not enough
The main problem is "uglifyjs-webpack-plugin": "^0.4.6" in webpack's package.json
According to semver, ^0.4.6 := >=0.4.6 <0.5.0. Because of the leading zero, webpack will never use the 1.0.0-beta.2.
So after running npm i -D uglifyjs-webpack-plugin#beta, you need to do one more step which is rm -rf node_modules/webpack/node_modules/uglifyjs-webpack-plugin. Then webpack will pick up the version from node_modules/uglifyjs-webpack-plugin instead of node_modules/webpack/node_modules/uglifyjs-webpack-plugin
Update on 2018-04-18: webpack v4 does not have this issue
Add the babel-preset-es2015 dependency to fix this.
And also add 'es2015' in .babelrc file.
json
{
"presets": ["es2015"]
}
I am having the same issue, i found a great answers here that helped me to reach the the file that was causing the error.
Go to Rails Console and Paste:
JS_PATH = "app/assets/javascripts/**/*.js";
Dir[JS_PATH].each do |file_name|
puts "\n#{file_name}"
puts Uglifier.compile(File.read(file_name))
end
Hope it helps someone!
If you got this error using Grunt (grunt-contrib-uglify) the solution is to install ES6 version of the plugin:
npm install grunt-contrib-uglify-es --save-dev
For me it had nothing to do with Uglify not working correctly, but rather a dependency (in this case empty-promise) that has not been compiled to ES5 yet. As we just imported the raw source file, but babel is only transpiling files outside of node_modules, uglify got confused by the ES6 syntax.
Simply check if any dependency you've recently added might not have a "dist" build.
Add stage-3 to presets in .babelrc file.
{
"presets": [
"stage-3"
]
}
Related
Error: Unable to resolve module navigation/stack-routes from /Users/jacksaunders/gymzoo/src/navigation/tabs/MainTabs.tsx: navigation/stack-routes could not be found within the project or in these directories:
node_modules
Hello there! I have just tried to set up absolute imports (using navigation/stack instead of ../../../navigation/stack)
I am not sure what is happening because it looks to be okay in my IDE but my metro is flagging the following error.
Here is my tsconfig for context:
I have tried deleting my node modules, npm i and pod install but theres no luck.
Please throw your suggestions at me! Or advise me on how to solve this.
All the best,
Jack :)
You need to update your babel.config.js to understand the root imports you're using here, because your .tsconfig only takes care about the code before it's transcompiled.
You can use the babel-plugin-root-import to achieve this.
npm package: https://www.npmjs.com/package/babel-plugin-root-import
Example babel.config.js could look like this:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'babel-plugin-root-import',
{
paths: [
{
rootPathSuffix: './src',
rootPathPrefix: 'src',
},
{
rootPathSuffix: './src/navigation',
rootPathPrefix: 'navigation',
},
]
},
],
],
};
It's not an only option though, you can also use babel-plugin-module-resolver, which is more popular (https://www.npmjs.com/package/babel-plugin-module-resolver).
For some reason, my jest configuration doesn't work with the latest version of d3-path#3.0.1. It worked fine with version 2.0.0. I guess it has something to do with d3-path switching to ESM, but I was already using ES6 in my own code, so I don't get why it suddenly doesn't work anymore. I have the following packages installed:
"dependencies": {
"d3-path": "^3.0.1"
},
"devDependencies": {
"#babel/core": "^7.15.8",
"#babel/preset-env": "^7.15.8",
"babel-jest": "^27.3.1",
"jest": "^27.3.1"
}
My babel.config.js:
module.exports = {
presets: [['#babel/preset-env', {targets: {node: 'current'}}]],
};
My index.js:
import { path } from 'd3-path'
export default () => path()
The test file:
import fn from '../src/index.js'
describe('test', () => {
it('works', () => {
fn()
expect(2 + 2).toBe(4)
})
})
The error message:
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export {default as path} from "./path.js";
^^^^^^
SyntaxError: Unexpected token 'export'
> 1 | import { path } from 'd3-path'
To reproduce:
git clone https://github.com/luucvanderzee/jest-problem.git
cd jest-problem
npm i
npm run test
// The test runs without failure- this is because we're currently still using d3-path#2.0.0
npm uninstall d3-path && npm install d3-path // (upgrade to d3-path#3.0.1)
npm run test
// Now the test fails.
How should I configure jest and/or babel to solve this issue?
EDIT:
I already tried the following (from this page of the jest docs):
Creating a jest.config.js file with the following:
module.exports = {
transform: {}
}
Changing my "test" command from "jest" to "node --experimental-vm-modules node_modules/jest/bin/jest.js"
This gives me another error:
/home/luuc/Projects/javascript/jest-problem/test/test.test.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import fn from '../src/index.js'
^^^^^^
SyntaxError: Cannot use import statement outside a module
I also don't get what is meant by
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
Isn't the problem that the module is not transformed? Would adding an ignore pattern not just lead to the module not getting transformed?
Problem
The error happens because jest does not send the content of node_modules to be transformed by babel by default.
The following output line of npm run test indicates one way to solve the problem:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
Solution
The configuration of jest should be updated in order to instruct it to transform the ESM code present in d3-path dependency.
To do so, add the following to a jest.config.js file in the root directory of the project:
module.exports = {
transformIgnorePatterns: ['node_modules/(?!(d3-path)/)']
}
npm run test runs fine after that.
The transformIgnorePatterns option is documented here.
Edit - including more modules
In order to include all modules starting with d3, the following syntax may be used:
transformIgnorePatterns: ['/node_modules/(?!(d3.*)/)']
TLDR;
transformIgnorePatterns: [
"/node_modules/(?!d3|d3-array|d3-axis|d3-brush|d3-chord|d3-color|d3-contour|d3-delaunay|d3-dispatch|d3-drag|d3-dsv|d3-ease|d3-fetch|d3-force|d3-format|d3-geo|d3-hierarchy|d3-interpolate|d3-path|d3-polygon|d3-quadtree|d3-random|d3-scale|d3-scale-chromatic|d3-selection|d3-shape|d3-time|d3-time-format|d3-timer|d3-transition|d3-zoom}|internmap|d3-delaunay|delaunator|robust-predicates)"
]
For the ones reaching this page after updating recharts dependency, here I found the solution, provided by them.
I am refactoring am existing project with TypeScript and React. I have introduced ESLint and there are over 300 errors reported across the code.
This is quite a large task as these cannot be fixed automatically with ESLint itself.
Is there a way to get the distinct error from the ESLint CLI output then use that rule to get the files that throw the rule error so I can fix it rule-by-rule rather than file-by-file?
Eslint supports custom formatters. So you can do something along the lines:
Add file lint-formatter.js
module.exports = results => {
const byRuleId = results.reduce(
(map, current) => {
current.messages.forEach(({ ruleId, line, column }) => {
if (!map[ruleId]) {
map[ruleId] = [];
}
const occurrence = `${current.filePath}:${line}:${column}`;
map[ruleId].push(occurrence);
});
return map;
}, {}
);
return Object.entries(byRuleId)
.map(([ruleId, occurrences]) => `${ruleId} (total: ${occurrences.length})\n${occurrences.join('\n')}`)
.join('\n########################\n');
};
The above example groups errors/warnings by rule id, but of course everything in your hands.
Then run linter with your custom formatter:
eslint -f ./lint-formatter.js
Sample output:
object-curly-spacing (total: 2)
foo/bar.js:2:8
foo/bar.js:3:13
########################
no-trailing-spaces (total: 1)
foo/bar.js:7:11
########################
object-curly-newline (total: 2)
foo/bar.js:14:8
foo/bar.js:15:31
########################
space-infix-ops (total: 1)
foo/bar.js:18:29
I had 100s of eslint errors from a open source project.
Spent 2 hours in trying to fix them.
Below worked:
Install eslint-nibble along with any dependencies, I have installed as below:
npm i -g eslint
npm i -g eslint-config-standard
npm i -g eslint-plugin-import
npm i -g eslint-plugin-markdown
npm i -g eslint-plugin-n
npm i -g eslint-plugin-promise
npm i -g eslint-nibble
Now see by running eslint & eslint-nibble:
Normal eslint produces 100s of mixed warning & errors
eslint --fix **/*.js
eslint-nibble will show all errors group by rule.
Also asks which ones we type of eslint errors we want to see:
eslint-nibble **/*.js
I'm getting below error running this command
gulp.task('minify', function () {
return gulp
.src('public/app/js/myapp.bundle.js')
.pipe(uglify())
.pipe(gulp.dest('public/app/js/myapp.bundle.min.js'));
});
GulpUglifyError: unable to minify JavaScript Caused by: SyntaxError: Unexpected token: name (MenuItem) (line: 1628, col: 18, pos: 53569)
Code on that location is this
setters: [],
execute: function () {
class MenuItem { // <-- line 1628
What's wrong?
UglifyJS does not currently support EcmaScript 6 structures like classes.
You'll probably need to run your JavaScript through a transpiler step first, or find a minifier that knows what to do with ES6 code.
Update 2017-06-17
The branch of UglifyJS that is designed to work with ES6 is now published as uglify-es on npm.
Update 2018-09-10
terser is the new uglify-es, uglify-es is no longer maintained.
If using gulp both npmjs gulp-uglify-es and npmjs gulp-terser packages support terser.
npm install gulp-terser --save-dev
const gulp = require('gulp');
const terser = require('gulp-terser');
function es(){
return gulp.src('./src/index.js')
.pipe(terser())
.pipe(gulp.dest('./build'))
}
gulp.task('default', es);
If you run into this problem and you have in fact a transpiler step like Babel, make sure that you include the proper Babel preset in you .babelrc file. Otherwise Babel will simply leave your code as is.
E.g.
{
"presets": ["es2015"]
}
I have a piece of code:
'use strict';
class ArticleModel {
constructor(options = {}) {
this.options = options
}
}
module.exports = ArticleModel
which results in the error Unexpected token = - I don't believe Babel is parsing this. Which babel 6 plugin is needed to parse default parameters in a function?
Edit 1 - this is my .babelrc file
{
"presets": [
"es2015",
"stage-0"
]
}
Edit 2 - I am not running babel from the same directory as .babelrc. I'm running babel from inside test/ where the structure looks like this:
/app
/test
/test/runner.js < -- this is what calls babel-core/register
.babelrc
Do I need to explicitly tell babel-core/register where .babelrc is? I assumed it rolled up a directory for it.
Edit 3 - changed babel/register to babel-core/register. Still get the same issue.
npm install babel-preset-es2015 --save-dev
Add the following line to your .babelrc file:
{
"presets": ["es2015"]
}
Did you try this?
How are you importing the module into the test? I had a similar problem when my tests started to break after upgrading from Babel 5 to 6. In my case it turned out that the problem was because the import has to referenced the default property in the imported lib.
The initiator of this Babel issue gives a good example: https://github.com/babel/babel/issues/2679