"ESLint": ... is not defined - Knockoutjs and google maps - google-maps

I am using ESLint to lint my JavaScript. I am also using Knockout.js and Google Maps. The problem I ran into is ESLint doesn't recognize the google and ko variables.
My first attempt was to specify environments but I realized (after reading the documentation and crashing eslint) that the list provided by the documentation is exclusive.
Then I tried specifying globals but no luck there as well.
So my question is, how can I make it so ESLint recognizes my Google Maps library and Knockout.js?

Defining globals in .eslintrc.js should work. The following is an example that supports jQuery $, Google (google, custom site search in our case), and Knockout.js (ko).
module.exports = {
root: true,
extends: [
'eslint:recommended'
],
env: {
"browser": true,
"commonjs": true,
"jquery": true
},
globals: {
"google": true,
"ko": true
}
};

Related

Karma runner with Coverage - preprocessor not working on Javascript ES6 code

I just recently started working with Karma runner in our UI5 app. Wrote some unit tests, ran them... all worked fine so far.
However, now I´ve decided to track the code coverage. To measure it, I need to run preprocessor on my source code. And this is where I stumbled upon a problems - I am currently trying to make it work and both have some kind of problems
npm package karma-coverage as a preprocessor - after installing it, I set it up in karma.conf.js like this
preprocessors: {
"webapp/helpers/**/*.js": ['coverage'],
"webapp/controller/**/*.js": ['coverage'],
},
This works fine on helpers folder since it contains only one file with simple javascript. However, when it tries to process controller folder which has files with some ES6 code, each file fails with errors such as these
Unexpected token function
Unexpected token ...
As a second option, I tried to use karma-babel-preprocessor which should be able to handle also ES6 code. This is how my karma.conf.js file looks like
preprocessors: {
"webapp/helpers//.js": ['babel'],
"webapp/controller//.js": ['babel'],
},
babelPreprocessor: {
options: {
presets: ['#babel/preset-env'],
sourceMap: 'inline'
} ,
filename: function (file) {
return file.originalPath.replace(/\.js$/, '.es5.js');
},
sourceFileName: function (file) {
return file.originalPath;
}
},
However, this one is not even able to find the js file (even though the address is the same as in the case of coverage preprocesor) and returns this error.
Error: failed to load 'sbn/portal/helpers/formatter.js' from .webapp/helpers/formatter.js: 404 - Not Found
at https://openui5.hana.ondemand.com/resources/sap-ui-core.js:86:37
Does someone have an idea how I can get the coverage data while using these packages or any other ones? There is a lots of conflicting info on the web, most of it several years old while various karma-related npm packages keep popping up each month so I am really not sure which one would be the best to use.
Thank a lot
We had the same problem and we managed to fix it integrating babel in a ui5-building-tool step.
This is how our package.json looks like:
{
"devDependencies": {
"babel-core": "6.26.3",
"babel-plugin-fast-async": "6.1.2",
"babel-preset-env": "1.7.0",
"karma": "^4.0.1",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.2",
"karma-ui5": "^1.0.0",
"karma-junit-reporter": "1.2.0",
"rimraf": "^2.6.2",
"start-server-and-test": "^1.4.1",
"#ui5/cli": "^1.5.5",
"#ui5/logger": "^1.0.0",
}
"scripts": {
"start": "ui5 serve -o index.html",
"lint": "eslint webapp",
"test": "karma start",
"build": "npm run test && rimraf dist && ui5 build --a --include-task=generateManifestBundle"
}
}
This is how the ui5.yaml is looking like
specVersion: '1.0'
metadata:
name: app-name
type: application
builder:
customTasks:
- name: transpile
afterTask: replaceVersion
---
specVersion: "1.0"
kind: extension
type: task
metadata:
name: transpile
task:
path: lib/transpile.js
This is how the transpile.js is looking like:
Be aware that this file should be placed in the root-dir/lib folder. root-dir is the folder where ui5.yaml is residing.
const path = require("path");
const babel = require("babel-core");
const log = require("#ui5/logger").getLogger("builder:customtask:transpile");
/**
* Task to transpiles ES6 code into ES5 code.
*
* #param {Object} parameters Parameters
* #param {DuplexCollection} parameters.workspace DuplexCollection to read and write files
* #param {AbstractReader} parameters.dependencies Reader or Collection to read dependency files
* #param {Object} parameters.options Options
* #param {string} parameters.options.projectName Project name
* #param {string} [parameters.options.configuration] Task configuration if given in ui5.yaml
* #returns {Promise<undefined>} Promise resolving with undefined once data has been written
*/
module.exports = function ({
workspace,
dependencies,
options
}) {
return workspace.byGlob("/**/*.js").then((resources) => {
return Promise.all(resources.map((resource) => {
return resource.getString().then((value) => {
log.info("Transpiling file " + resource.getPath());
return babel.transform(value, {
sourceMap: false,
presets: [
[
"env",
{
exclude: ["babel-plugin-transform-async-to-generator", "babel-plugin-transform-regenerator"]
}
]
],
plugins: [
[
"fast-async",
{
spec: true,
compiler: {
"promises": true,
"generators": false
}
}
]
]
});
}).then((result) => {
resource.setString(result.code);
workspace.write(resource);
});
}));
});
};
And finally this is the karma.conf.js setup:
module.exports = function (config) {
var ui5ResourcePath = "https:" + "//sapui5.hana.ondemand.com/resources/";
config.set({
// the time that karma waits for a response form the browser before closing it
browserNoActivityTimeout: 100000,
frameworks: ["ui5"],
// list of files / patterns to exclude
exclude: [],
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
"root_to_to_files/**/*.js": ["coverage"],
},
// test results reporter to use
// possible values: "dots", "progress"
// available reporters: https://npmjs.org/browse/keyword/karma-reportery
reporters: ["progress", "coverage"],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: false,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ["Chrome"],
// Continuous Integration modey
// if true, Karma captures browsers, runs the tests and exits
singleRun: true,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
// generates the coverage report
coverageReporter: {
type: "lcov", // the type of the coverage report
dir: "reports", // the path to the output directory where the coverage report is saved
subdir: "./coverage" // the name of the subdirectory in which the coverage report is saved
},
browserConsoleLogOptions: {
level: "error"
}
});
};
In our project this setup works fine with ES6 code and prints the coverage.
Hope this you help you. Please give me a feedback how this works.

Rest-spread not being transpiled when targeting edge with NextJS

I am trying to transpile my ES6 code via Babel, I am using the next/babel preset along with preset-env and I'm using the browsers: defaults target.
The NextJS preset comes with #babel/plugin-proposal-object-rest-spread in its plugins array, I'm wondering why I am getting an error when testing on edge that says Expected identifier, string or number, and when looking in the compiled JS for the error, I see it happens when {...t} occurs.
Here is my babel.config.js:
module.exports = {
presets: [
[
'next/babel',
{
'#babel/preset-env': {
targets: {
browsers: 'defaults'
},
useBuiltIns: 'usage'
}
}
]
],
plugins: [
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
['styled-components', { ssr: true, displayName: true, preprocess: false }],
[
'module-resolver',
{
root: ['.', './src']
}
]
],
env: {
development: {
compact: false
}
}
};
Any help on this would be greatly appreciated!
In the end my problem was related to a package that was not being transpiled by babel. My solution was to use NextJS' next-transpile-modules plugin to get babel to transpile the package code into something that would work on the browsers I need.
Here's an example of my NextJS webpack config with the package I need transpiled specified:
const withTM = require('next-transpile-modules');
module.exports = withTM({
transpileModules: ['swipe-listener']
});
SCRIPT1028: Expected identifier, string or number error can occur in 2 situations.
(1) This error get trigger if you are using trailing comma after your last property in a JavaScript object.
Example:
var message = {
title: 'Login Unsuccessful',
};
(2) This error get trigger if you are using a JavaScript reserved word as a property name.
Example:
var message = {
class: 'error'
};
solution is to pass the class property value as a string. You will need to use bracket notation, however, to call the property in your script.
Reference:
ERROR : SCRIPT1028: Expected identifier, string or number

How to load version number in angular (v4+) app from package.json?

I am trying to load the version number of my Angular application from package.json because that is where the version number is located. When looking up how to do this, most people suggest using require to load the json file like:
var pckg = require('../../package.json');
console.log(pckg.version);
When I put this code in the constructor of a component, I get undefined.
Next I try putting the require statement above the component by the imports like:
const { version: appVersion } = require('../../package.json')
export class StackOverflowComponent {
public appVersion
constructor() {
this.appVersion = appVersion
}
}
and I get Error: (SystemJS) Unexpected token : when the require is trying to parse the json file. When I hover over require I see that it is of type "NodeRequire(id: string)". Is this different than requirejs?
I am using systemjs and I noticed a lot of people with answers are referring to Webpack. Here are relevant files that may help you answer my problem.
tsconfig.json:
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es2015", "dom"],
"noImplicitAny": true,
"suppressImplicitAnyIndexErrors": true,
"allowSyntheticDefaultImports": true,
"typeRoots": [
"./node_modules/#types/"
]
},
"compileOnSave": true,
"exclude": [
"node_modules/*",
"**/*-aot.ts"
]
}
devDependencies in package.json:
"devDependencies": {
"#types/node": "^6.0.46",
"concurrently": "^3.0.0",
"lite-server": "^2.3.0",
"rollup": "^0.50.0",
"rollup-plugin-commonjs": "^8.2.1",
"rollup-plugin-node-resolve": "^3.0.0",
"rollup-plugin-uglify": "^2.0.1",
"source-map-explorer": "^1.5.0",
"typescript": "~2.3.2"
},
The problem you've encountered is that SystemJS is trying to interpret a JSON file as if it were executable. In order to get SystemJS to load JSON files sensibly, you need to use a JSON loader like systemjs-plugin-json.
You need to make it available in your SystemJS configuration. For instance, I use:
SystemJS.config({
paths: {
// Set an abbreviation to avoid having to type /node_modules/ all the time.
"npm:": "/node_modules/",
// ....
},
map: {
// The loader is known to SystemJS under the name "json".
json: "npm:systemjs-plugin-json",
// ...
},
packageConfigPaths: [
// Tell SystemJS that it should check the package.json files
// when figuring out the entry point of packages. If you omit this, then
// the map above would have to be "npm:systemjs-plugin-json/json.js".
"npm:*/package.json",
// ...
],
});
Then you need to use it. You could replace your require call with require('../../package.json!json'); but I suspect that TypeScript would not be happy with this due to the funky module name. The !json part tells SystemJS to use the json loader. I never do this. Instead, I set a meta in my configuration that tells SystemJS, "use the json loader when you load this file":
SystemJS.config({
meta: {
"path/to/package.json": {
loader: "json",
},
},
});
You need to figure out path/to/package.json on the basis of the rest of your SystemJS configuration, baseUrl in particular.
If you add the following to your typings.d.ts :
declare module '*.json' {
const value: any;
export default value;
}
you can then do this:
import * as pkg from '../path-to-root/package.json';
and later refer to it like this, e.g. in you component's constructor:
console.log(`version: ${pkg['version']}`);
or, equivalently,
console.log(`version: ${(<any>pkg).version}`);

i18next appends the default translation namespace to my namespaces

I am using i18n - aurelia's wrapper of i18next with the following configuration:
instance.i18next.use(Backend);
return instance.setup({
backend: {
loadPath: 'assets/locales/{{lng}}/{{ns}}.json',
},
detectFromHeaders: false,
lng: 'bg',
fallbackLng: 'bg',
ns: ['app', 'dp', 'management'],
defaultNS: 'app',
fallbackNS:'app',
attributes: ['t', 'i18n'],
useCookie: false,
getAsync: false,
debug: false
});
I have a component that switches to a different language via the setLocale(language) function. It works fine for the translations, however, when I switch between the languages for some reason i18next adds the translation.json to my namespaces although I don't use it and it makes an xhr call to get it and I get a 404 error for translation.json - a namespace I don't even want in the first place. Is there an option to remove it altogether from the namespaces?
Thanks in advance
The issue is not part of Aurelia-I18N but one of i18next itself. The only workaround I found so far is to set the fallbackLng to false.
{
backend: {
loadPath: './locales/{{lng}}/{{ns}}.json',
},
lng : 'de',
ns: ['foo'],
defaultNS: "foo",
attributes : ['t','i18n'],
fallbackLng : false, <----- SET THIS TO FALSE TO AVOID A SEARCH FOR translation NS
debug : false
}
This is a known issue that can be tracked here: https://github.com/aurelia/i18n/issues/47

Serverless Framework with Node MySQL: PROTOCOL_INCORRECT_PACKET_SEQUENCE error

I'm having difficulties implementing a simple query on a AWS Lambda NodeJS (with Serverless Framework). Running it locally works, but when I upload it to AWS and then try to run it using the API Gateway endpoint, I get this error:
{
"code": "PROTOCOL_INCORRECT_PACKET_SEQUENCE",
"fatal": true
}
I can't find any information on Google, StackOverflow or GitHub about this error, and I can't figure out what I'm doing wrong.
This is what I'm trying.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '',
user : '',
password : '',
database : ''
});
function getLists (client_id,api_key,callback){
connection.query("SELECT * FROM list WHERE client_id = ?",
[client_id],function(error, results){
connection.end();
callback(error,results);
}
)};
module.exports.run = function(event, context, cb) {
getLists(event.x_mail_list_client_id,'',function(error,results){
if(error){
return cb(null,error);
}
return cb(null,results);
});
};
In general the problem you encounter is the disability of the serverless-optimizer-plugin to handle dynamically loaded NPM modules or globals correctly (e.g. when using the mysql NPM package). So you have to exclude it from optimization.
The solution heavily depends on the serverless version and the Node version you use, so I will list the different solutions below:
Severless v4 + Node v4:
Set the excludes in your s-component.json as follows:
"custom": {
"optimize": {
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql"
]
}
}
Serverless v5 + Node v4:
Components have been obsoleted and removed in this serverless version favoring functions instead. So apply the optimizer configuration directly to your s-function.json configuration files.
Node v5:
The NPM executable included with Node v5 internally does dependency optimization and dependency module flattening. This is not yet really compatible with the current serverless-optimizer-plugin. The solution here is to add the dependencies that are already optimized by NPM as proposed by #Masatsugu Hosoi in his answer above like this
"custom": {
"optimize": {
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql",
"node_modules/bignumber.js",
"node_modules/readable-stream",
"node_modules/isarray",
"node_modules/core-util-is",
"node_modules/inherits",
"node_modules/string_decoder"
]
}
}
edit awsm.json.
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql",
"node_modules/bignumber.js",
"node_modules/readable-stream",
"node_modules/isarray",
"node_modules/core-util-is",
"node_modules/inherits",
"node_modules/string_decoder"
]
https://github.com/felixge/node-mysql/issues/1249
For any coming in the future
what worked for me to add the following in the webpack.config.js file
optimization: {
minimize: false
}
Mysql does not seem to like the minification
I just had this exactly same problem.
The problem is with the browserify and the mysql module. Unfortunately I couldn't find a real solution.
By reading the code the browserify is the only available option as builder.
https://github.com/jaws-framework/JAWS/blob/master/lib/commands/deploy_lambda.js
You can set the 'builder' as false. This will simply zip all your files before sending them to Amazon.
Unfortunately (again) just doing this will not work. For some reason all files are inside a 'node_module' folder to work you must take the files out before upload the package.
Still, all this is manual...
edit: There is already an open issue about this last part:
https://github.com/jaws-framework/JAWS/issues/239