Vue linting errors for defineEmits function - javascript

I'm having an issue with the linting for my Vue SPA. I'm using the defineEmits function from the script setup syntactic sugar (https://v3.vuejs.org/api/sfc-script-setup.html). The errors just do not make any sense, does anyone know how to fix this (without disabling these rules for the affected files, because it happens to every usage of defineEmits). The weird thing is that the defineProps function works without errors, which follows the same syntax. Can anyone help me out here?
My linter complains about these errors:
22:14 error Unexpected space between function name and paren no-spaced-func
22:27 error Unexpected whitespace between function name and paren func-call-spacing
23:3 error 'e' is defined but never used no-unused-vars
23:27 error 'value' is defined but never used no-unused-vars
Code that is generating these errors (the defineEmits is the source of all the errors:
<script lang="ts" setup>
const emit = defineEmits<{
(e: 'update:modelValue', value: string): void
}>()
defineProps<{
modelValue: string
name: string
items: string[]
}>()
const onInput = (e: Event) => {
emit('update:modelValue', (e.target as HTMLInputElement).value)
}
</script>
My linting eslintrs.js file (the imported shared rules do not modify the rules eslint is complaining about):
const path = require('path')
const prettierSharedConfig = require(path.join(__dirname, '../prettier-shared-config.json'))
module.exports = {
settings: {
'import/resolver': {
typescript: {},
node: {
extensions: ['.js', '.ts', '.vue'],
},
},
},
env: {
browser: true,
es2021: true,
'vue/setup-compiler-macros': true,
},
extends: ['plugin:vue/essential', 'airbnb-base'],
parserOptions: {
ecmaVersion: 13,
parser: '#typescript-eslint/parser',
sourceType: 'module',
},
plugins: ['vue', '#typescript-eslint'],
rules: {
...prettierSharedConfig.rules.shared,
'vue/multi-word-component-names': 'off',
'vue/no-multiple-template-root': 'off',
},
}
Update:
I did some further digging and saw this happening:
type EmitsType = {
(e: 'update:modelValue', value: string): void
}
const emit = defineEmits<EmitsType>()
With the following linting output:
23:3 error 'e' is defined but never used no-unused-vars
23:27 error 'value' is defined but never used no-unused-vars
It seems that the linter cannot properly process these types.

I had the same issue, I've found 2 solutions, it fixes this problem but I'm not pretty sure if I was doing it wrong.
Add '#typescript-eslint/recommended' to your eslintrc
plugins: [
...,
'#typescript-eslint/recommended',
],
or
Add 'func-call-spacing' rule
rules: {
...
'func-call-spacing': 'off', // Fix for 'defineEmits'
}
Here's the additional details about the no-unused-vars.
https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/docs/rules/no-unused-vars.md

You should use #typescript-eslint/no-unused-vars for your eslint rule. It will show the correct result.
"rules": {
"#typescript-eslint/no-unused-vars": "error",
}

Related

How to Polyfill node core modules using vite

It seems that vite does not do automatic polyfills anymore - vite 4.0.0
How do you guys go about this? I have tried multiple variations of what I could find over the internet and none of them seems to be solid.
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
✘ [ERROR] The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
Build failed with 2 errors:
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_buffer.js" cannot be marked as external
error: The injected path "/Users/marian/code/OzoneV2/app-web/node_modules/#esbuild-plugins/node-globals-polyfill/_virtual-process-polyfill_.js" cannot be marked as external
my config
// yarn add --dev #esbuild-plugins/node-globals-polyfill
import { NodeGlobalsPolyfillPlugin } from "#esbuild-plugins/node-globals-polyfill";
// yarn add --dev #esbuild-plugins/node-modules-polyfill
import { NodeModulesPolyfillPlugin } from "#esbuild-plugins/node-modules-polyfill";
// You don't need to add this to deps, it's included by #esbuild-plugins/node-modules-polyfill
import rollupNodePolyFill from "rollup-plugin-node-polyfills";
export default {
resolve: {
alias: {
// This Rollup aliases are extracted from #esbuild-plugins/node-modules-polyfill,
// see https://github.com/remorses/esbuild-plugins/blob/master/node-modules-polyfill/src/polyfills.ts
// process and buffer are excluded because already managed
// by node-globals-polyfill
util: "rollup-plugin-node-polyfills/polyfills/util",
sys: "util",
events: "rollup-plugin-node-polyfills/polyfills/events",
stream: "rollup-plugin-node-polyfills/polyfills/stream",
path: "rollup-plugin-node-polyfills/polyfills/path",
querystring: "rollup-plugin-node-polyfills/polyfills/qs",
punycode: "rollup-plugin-node-polyfills/polyfills/punycode",
url: "rollup-plugin-node-polyfills/polyfills/url",
string_decoder: "rollup-plugin-node-polyfills/polyfills/string-decoder",
http: "rollup-plugin-node-polyfills/polyfills/http",
https: "rollup-plugin-node-polyfills/polyfills/http",
os: "rollup-plugin-node-polyfills/polyfills/os",
assert: "rollup-plugin-node-polyfills/polyfills/assert",
constants: "rollup-plugin-node-polyfills/polyfills/constants",
_stream_duplex: "rollup-plugin-node-polyfills/polyfills/readable-stream/duplex",
_stream_passthrough: "rollup-plugin-node-polyfills/polyfills/readable-stream/passthrough",
_stream_readable: "rollup-plugin-node-polyfills/polyfills/readable-stream/readable",
_stream_writable: "rollup-plugin-node-polyfills/polyfills/readable-stream/writable",
_stream_transform: "rollup-plugin-node-polyfills/polyfills/readable-stream/transform",
timers: "rollup-plugin-node-polyfills/polyfills/timers",
console: "rollup-plugin-node-polyfills/polyfills/console",
vm: "rollup-plugin-node-polyfills/polyfills/vm",
zlib: "rollup-plugin-node-polyfills/polyfills/zlib",
tty: "rollup-plugin-node-polyfills/polyfills/tty",
domain: "rollup-plugin-node-polyfills/polyfills/domain",
},
},
optimizeDeps: {
esbuildOptions: {
// Node.js global to browser globalThis
define: {
global: "globalThis",
},
// Enable esbuild polyfill plugins
plugins: [
NodeGlobalsPolyfillPlugin({
process: true,
buffer: true,
}),
NodeModulesPolyfillPlugin(),
],
},
},
build: {
rollupOptions: {
plugins: [
// Enable rollup polyfills plugin
// used during production bundling
rollupNodePolyFill(),
],
},
},
};
I encountered the same issue "cannot be marked as external" when working with the bip39 package and getting error because of buffer not defined. I tried many stuffs so not sure how what I solved, but here is my configuration (working with svelteKit):
In vite.config.js:
import { sveltekit } from '#sveltejs/kit/vite';
import type { UserConfig } from 'vite';
const config: UserConfig = {
plugins: [sveltekit()],
resolve: {
alias: {
// polyfills
Buffer: 'vite-compatible-readable-buffer',
stream: 'vite-compatible-readable-stream',
util: 'rollup-plugin-node-polyfills/polyfills/util',
}
}
};
export default config;
In layout.ts:
import { Buffer as BufferPolyfill } from 'buffer'
declare var Buffer: typeof BufferPolyfill;
globalThis.Buffer = BufferPolyfill
In app.html:
<script>
/**
* this is a hack for error: global is not defined
*/
var global = global || window
</script>
I hope it helps. I'm new to svelte and I don't 100% know what I'm doing :p

Jest throwing ReferenceError to default exports

Jest is unable to find functions which are export default but IS able to find export const. I can go through and redefine how all of my functions are exported/imported, but I feel this is likely just a config issue but have been unable to find any solution on the docs or github issues to solve it.
Does anyone know of some jest config which can be used to resolve this?
GOOD
file:
export const MyFunction = () => {..
spec:
import { MyFunction } from "src/MyFunction";
=> ● Pass
BAD
file:
export default MyFunction = () => {..
spec:
import MyFunction from "src/MyFunction";
=> ● Test suite failed to run
ReferenceError: MyFunction is not defined
My jest.config.js:
/*
* For a detailed explanation regarding each configuration property, visit:
* https://jestjs.io/docs/en/configuration.html
*/
module.exports = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Automatically restore mock state between every test
restoreMocks: true,
// Make calling deprecated APIs throw helpful error messages
errorOnDeprecated: true,
// An array of directory names to be searched recursively up from the requiring module's location
moduleDirectories: ["node_modules", "src", "test/unit"],
// The test environment that will be used for testing
testEnvironment: "node",
// The glob patterns Jest uses to detect test files
testMatch: ["**/test/**/**/*.spec.(js|jsx|ts|tsx)"],
transformIgnorePatterns: [
"node_modules/(?!(jest-)?react-native|react-clone-referenced-element|#react-native-community|expo(nent)?|#expo(nent)?/.*|react-navigation|#react-navigation/.*|#unimodules/.*|unimodules|sentry-expo|native-base|#sentry/.*)",
],
transform: {
"\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js",
},
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
testPathIgnorePatterns: ["/node_modules/"],
reporters: ["default", "jest-junit"],
collectCoverage: true,
coverageReporters: ["lcov", "text-summary"],
coveragePathIgnorePatterns: [
"/node_modules/",
"src/img/",
"src/styles/",
"test/factories/",
"test/fixtures/",
],
// Whether to use watchman for file crawling
watchman: true,
setupFilesAfterEnv: ["#testing-library/jest-native/extend-expect"],
preset: "jest-expo",
globals: {
__DEV__: true,
THEME: true,
SEGMENT_KEY_STORE_INFO: true,
INITIAL_STATE: true,
EMPTY_MESSAGE: true,
},
};
export default MyFunction = () => {..
Change this to
export default const MyFunction = () => {..
Ok guys stupid one here, but the solution is to change the default export to:
MyFunction.js:
export default () => {..
Ie drop the name in the export default function declaration. Hope this helps someone having this issue.

Class constructor cannot be invoked without 'new'

Appreciate that this questions has been asked a few times, but almost all the cases that I've encountered have been the ones where someone tried to extend a non-native class. My case is different. I have a very simple base class called CObject which is as follows:
export class CObject extends BaseObject {
constructor() {
super();
}
static url(path: string): string { return ""; }
static wssUrl(): string { return ""; }
static callMethod(method, path: string, params: any, noConvertData?: boolean): Promise<any> { return null; }
static post(path: string, params: any, noConvertData?: boolean): Promise<any> {
return CObject.callMethod('post', path, params, noConvertData);
}
static put(path: string, params: any, noConvertData?: boolean): Promise<any> {
return CObject.callMethod('put', path, params, noConvertData);
}
static patch(path: string, params: any, noConvertData?: boolean): Promise<any> {
return CObject.callMethod('patch', path, params, noConvertData);
}
static get(path: string, params: any, noConvertData?: boolean): Promise<any> {
return CObject.callMethod('get', path, params, noConvertData);
}
static delete(path: string, params: any, noConvertData?: boolean): Promise<any> {
return CObject.callMethod('delete', path, params, noConvertData);
}
}
The entire hierarchy of classes including BaseObject, are just simple Typescript classes. However, when I extend a class from CObject and then try instantiating it, I get this dreaded error (4 days now!). The funny thing is that I can instantiate CObject on it's own without any issues. It's just derived classes that are giving the issue, even empty ones like this:
export class TestClass extends CObject {
constructor() {
super();
}
}
A point to note is that this code is shared between my Server (Node.js) and Client sides. The code works perfectly fine on the server side. No issues whatsoever.
I have tried looking at the babel generated code and it's just simple ES6 classes. All other TS generated classes work as fine and everything below CObject fails when it gets to calling the CObject constructor.
My .babelrc is given below:
{
"presets": [
"es2015-node5",
"react",
"stage-0",
"stage-1",
"bluebird"
],
"plugins": [
"transform-decorators-legacy",
"react-hot-loader/babel",
"transform-async-to-bluebird",
"transform-promise-to-bluebird",
"transform-runtime",
[
"module-alias",
[
{ "src": "./build/Server", "expose": "Server" },
{ "src": "./build/Shared", "expose": "Shared" },
{ "src": "./build/Client", "expose": "Client" }
]
]
],
"compact": "false"
}`
For client side compilation, my awesome-typescript-loader config in tsconfig.json is as follows:
EDIT: I was looking at the wrong ATL config. The full config is as follows:
"awesomeTypescriptLoaderOptions": {
"babelrc": true,
"useBabel": true,
"useWebpackText": true,
"useTranspileModule": true,
"doTypeCheck": true,
"forkChecker": true,
"presets": ["env", { "targets": "last 2 versions, ie 11", "modules": false }, { "exclude": ["transform-es2015-classes"] } ],
"babelOptions": {
"sourceMaps": true
},
"useCache": true
}
Client side webpack config is as follows:
var path = require('path');
var webpack = require('webpack');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
let outputDir = path.join(__dirname, "..", "dist", "Client");
console.log(`Output: ${outputDir}`);
module.exports = {
entry: "./src/Client/Browser/Src/Main.tsx",
output: {
filename: "client.js",
path: outputDir
},
target: 'web',
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: [".ts", ".tsx", ".js", ".json"],
plugins: [new TsconfigPathsPlugin({ configFile: "./tsconfig.json" })],
modules: [
"./node_modules",
"./src/Shared",
"./src/Client"
]
},
module: {
rules: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
}
};
Any help will be appreciated. Thank you.
Edit: The exact error is:
ConfigSection.ts?26cc:18 Uncaught TypeError: Class constructor CObject cannot be invoked without 'new'
at new ConfigSection (ConfigSection.ts?26cc:18)
at Object../src/Shared/Model/Config/ShAlpha.ts (ShAlpha.ts:338)
at __webpack_require__ (bootstrap:19)
Ok, thanks to Oscar Paz, I have been able to fix the issue. Turns out that the culprit was my ATL config:
"awesomeTypescriptLoaderOptions": {
"babelrc": true,
"useBabel": true,
"useWebpackText": true,
"useTranspileModule": true,
"doTypeCheck": true,
"forkChecker": true,
"presets": ["env", { "targets": "last 2 versions, ie 11", "modules": false }, { "exclude": ["transform-es2015-classes"] } ],
"babelOptions": {
"sourceMaps": true
},
"useCache": true
}
More specifically, this line:
"presets": ["env", { "targets": "last 2 versions, ie 11", "modules": false }, { "exclude": ["transform-es2015-classes"] } ],
even though I'd set:
"babelrc": true,
Expecting the .babelrc to get used, which is what was getting used for the Node.js code. This was causing multiple definitions (both ES6 and ES5) of the classes derived from CObject to be generated. So CObject was getting generated correctly:
let CObject = exports.CObject = class CObject extends _BaseObject.BaseObject {} ...
The first definition of ConfigSection was also getting generated correctly:
let ConfigSection = ConfigSection_1 = class ConfigSection extends Shared_Core_CObject__WEBPACK_IMPORTED_MODULE_1__["CObject"] {} ...
But then further down:
var ConfigSection = ConfigSection_1 = function (_CObject) {
(0, _inherits3.default)(ConfigSection, _CObject); ...
This is what was causing the error. I don't know why ATL isn't ignoring those options and why those options cause this sort of code-gen. Perhaps, someone with a better understanding can shed some light.
For fellow Googlers, another cause of this error: on 04/2019, using the non maintained why-did-you-update npm React module caused this error.
Removing the module and its invocation fixed the bug.
I found removing semi-colons from the end of lines using require() (and in my case, right before an IIFE) caused this issue.
const MyClass = require("./myclass")
(() => { ... code ... })()
Once I added semi-colons on the end, the issue was resolved. YMMV

I get, "SyntaxError: function statement requires a name" in FF, and "Uncaught SyntaxError: Unexpected token (" in IE, when importing D3 into Angular5

UPDATE: My lead was able to solve this probllem. Please see answer below, and I hope that this helps at least some people
The following code throws the exception, but note that when I don't import/use d3-selection, then the whole app runs without errors. As soon as I import select from 'd3-selection', I get the error that I mentioned in the title.
import { Component, ElementRef, ViewChild } from '#angular/core';
import { select } from 'd3-selection';
#Component({
selector: 'pie',
template: `<ng-content></ng-content>`
})
export class PieChartComponent {
#ViewChild('containerPieChart')
private element: ElementRef;
constructor() {
select(this.element.nativeElement);
}
}
I checked the possible dupes in here, and none applied to me, so here I am.
The code that is bundled/imported from TypeScript is:
function(name) {
return select(creator(name).call(document.documentElement));
}
I know this is invalid in JS, because functions must have names, or be IIFEs in order to omit the name. Or object declarations. So, why is d3 transpiling into invalid JS?
EDIT: I am using rollup.config.dev.js with the following code:
import bundles from './bundles.json';
import resolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import scss from 'rollup-plugin-scss';
import sourcemaps from 'rollup-plugin-sourcemaps';
const
DEV_DIRECTORY = `dev`
, MODULE_NAME_PATH = 'AST.app'
;
function createDevBundle(bundle) {
let bundleDirectory = `${DEV_DIRECTORY}/${bundle.name}`;
return {
input: bundle.input,
name: `${MODULE_NAME_PATH}.${bundle.name}`,
output: {
file: `${bundleDirectory}/${bundle.name}.js`,
format: 'umd'
},
exports: 'default',
plugins: [
resolve({
jsnext: true,
module: true
}),
commonjs(),
sourcemaps(),
scss({
output: `${bundleDirectory}/${bundle.name}.css`,
includePaths: ['../global/scss/base']
})
],
onwarn: function(warning) {
// Recommended warning suppression by angular team.
if (warning.code === 'THIS_IS_UNDEFINED') {
return;
}
// eslint-disable-next-line no-console
console.error(warning.message);
},
treeshake: false,
sourcemap: true
};
}
export default bundles.map(createDevBundle);
I wasn't able to, but my lead was able to fix this problem. The following packages were updated in the package.json:
"rollup-plugin-commonjs": "8.3.0",
"rollup-plugin-execute": "1.0.0",
"rollup-plugin-node-resolve": "3.0.3",
"rollup-plugin-sourcemaps": "0.4.2",
"rollup-plugin-uglify": "3.0.0"
An update was made to rollup.config.js and rollup.config.dev.js. The sections of name, exports, and sourcemap were moved over to the output section. See below:
function createDevBundle(bundle) {
let bundleDirectory = `${DEV_DIRECTORY}/${bundle.name}`;
return {
input: bundle.input,
output: {
file: `${bundleDirectory}/${bundle.name}.js`,
name: `${MODULE_NAME_PATH}.${bundle.name}`,
exports: 'default',
sourcemap: true,
format: 'umd'
}
... [omitted for brevity]

ESLint doesn't recognize node.js's 'global' object

The error:
3:5 error 'global' is not defined no-undef
My current ESLint config:
module.exports = {
parser: "babel-eslint",
env: {
browser: true,
es6: true,
"jest/globals": true,
jest: true
},
extends: ["eslint:recommended", "plugin:react/recommended", "prettier", "prettier/react"],
parserOptions: {
ecmaFeatures: {
experimentalObjectRestSpread: true,
jsx: true
},
sourceType: "module"
},
globals: {
testGlobal: true
},
plugins: ["react", "prettier", "jest"],
rules: {
"prettier/prettier": 1,
"no-console": 0
}
};
An simplified example test file that causes the ESLint error:
describe("Jest global:", () => {
it("should not cause ESLint error", () => {
global.testGlobal = {
hasProp: true
};
});
});
I expected this Jest feature to be covered by having the env: { jest: true } in the eslint config. I can of course disable the rule or line in the file, but then I'd need to do that every time I use global.
The global object is part of Node.js. It is not specific to Jest and therefore it's not included in the jest environment. In fact, you are running your unit tests in Node and you happen to use the global object for your tests. In general the globals defined for specific libraries are the ones they provide to make it more convenient to use them without having to import them. A counterexample would be AVA, which requires you to import it instead of defining globals.
If you want to use ESLint for the tests as well, you would have to add the node environment.
env: {
browser: true,
es6: true,
node: true,
jest: true
},

Categories