eslint not formatting index.ts on save - visual-studio-code

In vscode settings I have:
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true,
}
"eslint.enable": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
],
When saving something.ts with this:
import { useContext } from 'react';
import { transactionsValueProps } from './interface';
import { TransactionsContext } from './TransactionsContext';
It moves import { TransactionsContext } from './TransactionsContext'; above import { transactionsValueProps } from './interface';. Not sure why because it's not alphabetically correct, but if that's the default of eslint, so be it.
However, when I save index.ts with this:
export * from './interface';
export * from './TransactionsContext';
export * from './useTransactionsContext';
It doesn't move things around. In fact, I can sort it as I wish, and nothing will get sorted.
How come? Am I missing something in vscode settings??

Related

Differences between Prettier CLI and VSCode extension

I tried to align VSCode extension and my local version of Prettier CLI in my project in order to get same results from both tools.
Prettier VSCode Extension : v9.10.4 (depends on prettier >=2.8.0)
Prettier : v2.8.0
With the following settings
// .vscode/settings.json
{
"prettier.documentSelectors": ["**/*.svg"],
"prettier.resolveGlobalModules": false,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.requireConfig": true,
"prettier.prettierPath": "./node_modules/prettier",
}
// .prettierrc
{
"printWidth": 80,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"arrowParens": "always",
"bracketSameLine": false,
"overrides": [
{
"files": ["*.tsx"],
"options": {
"parser": "typescript"
}
}
]
}
And here is my test file
import * as React from 'react';
function Test() {
const [indicatorStyle, setIndicatorStyle] = React.useState<React.CSSProperties>({});
}
The "Format Document" option from VSCode gives this result
import * as React from 'react';
function Test() {
const [indicatorStyle, setIndicatorStyle] = React.useState<
React.CSSProperties
>({});
}
And the result from Prettier 2.8.0 CLI
import * as React from 'react';
function Test() {
const [indicatorStyle, setIndicatorStyle] =
React.useState<React.CSSProperties>({});
}
What should I do to get the same result instead (the result from Prettier CLI looks better in this case) ?
Thank you.
It seems to be related to a cache problem. After restarting VSCode I get the same results on both tools now!

How to add a plugin in Aurelia

I am trying to use wavesurfer.js in an Aurelia project. I am not able to use the wavesurfer.js. After building it says Container Element not found.
my app.js looks like this
import * as wavesurfer from '../node_modules/wavesurfer/dist/wavesurfer.js';
export class App {
wavesurferObj = WaveSurfer.create({
container: '#waveform',
waveColor: 'violet',
progressColor: 'purple',
scrollParent: true,
});
constructor() {
wavesurferObj.load('http://ia902606.us.archive.org/35/items/shortpoetry_047_librivox/song_cjrg_teasdale_64kb.mp3');
wavesurferObj.on(ready, function () {
wavesurferObj.play();
});
}
}
and my main.js looks like this
// regenerator-runtime is to support async/await syntax in ESNext.
// If you target latest browsers (have native support), or don't use async/await, you can remove regenerator-runtime.
import * as wavesurfer from '../node_modules/wavesurfer/dist/wavesurfer.js';
// import * as timeline from '../node_modules/wavesurfer/plugin/wavesurfer.timeline.js';
// import * as regions from '../node_modules/wavesurfer/plugin/wavesurfer.regions.js';
import 'regenerator-runtime/runtime';
import * as environment from '../config/environment.json';
import {
PLATFORM
} from 'aurelia-pal';
export function configure(aurelia) {
aurelia.use
.standardConfiguration()
.feature(PLATFORM.moduleName('resources/index'));
aurelia.use.plugin(PLATFORM.moduleName('wavesurfer'));
// aurelia.use.plugin(PLATFORM.moduleName('timeline'));
// aurelia.use.plugin(PLATFORM.moduleName('regions'));
aurelia.use.developmentLogging(environment.debug ? 'debug' : 'warn');
if (environment.testing) {
aurelia.use.plugin(PLATFORM.moduleName('aurelia-testing'));
}
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));
}
and just the build section in Aurelia.json looks like this
"build": {
"options": {
"server": "dev",
"extractCss": "prod",
"coverage": false
},
"bundles": [{
"name": "vendor-bundle.js",
"dependencies": [{
"name": "wavesurfer",
"path": "../node_modules/wavesurfer/dist",
"main": "wavesurfer"
},
{
"name": "wavesurfer.timeline",
"path": "../node_modules/wavesurfer/plugin",
"main": "wavesurfer.timeline",
"deps": [
"wavesurfer"
]
},
{
"name": "wavesurfer.regions",
"path": "../node_modules/wavesurfer/plugin",
"main": "wavesurfer.regions",
"deps": [
"wavesurfer"
]
}
]
}]
},
Here is the error:
WaveSurfer is not defined.
Can someone indicate what is the right way to add this plugin please.
Thanks a lot in advance.
Without having a look at all of your actual code, i'm guessing you have at least 3 errors:
First one is using different variable names: wave surfer is imported as wavesurfer, but the way it's used is WaveSurfer, notice the case.
Using direct path to the dist file in a node_modules package:
import * as wavesurfer from '../node_modules/wavesurfer/dist/wavesurfer.js';
It should be:
import * as wavesurfer from 'wavesurfer';
3rd one is targeting an element via a CSS selector string #waveform. If this is not ready by the time you create an instance of class App, it will not work properly. Where is #waveform? from the document? from app.html? If it's from the document, it's ok, but if it's from app.html, you will need to change that code to something like this
<template>
....
<div ref="waveformElement"></div>
</template>
And in your app code:
import * as WaveSurfer from 'wavesurfer';
export class App {
bind() {
this.wavesurferObj = WaveSurfer.create({
container: this.waveformElement,
waveColor: 'violet',
progressColor: 'purple',
scrollParent: true,
});
this.wavesurferObj.load( 'http://ia902606.us.archive.org/35/items/shortpoetry_047_librivox/song_cjrg_teasdale_64kb.mp3');
this.wavesurferObj.on(ready, () => {
this.wavesurferObj.play();
});
}
}

VSCode IntelliSense autocomplete aliased imports

I'm using alias on the webpack.config.js as:
const srcDir = join(__dirname, '..', 'src');
const webpackConfig = {
resolve: {
alias: {
"constants": `${srcDir}/constants",
And I have configured it on the jsconfig.json as:
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"constants/*": ["./src/constants/*"],
My imports are in the format:
import CONSTANT from 'constants/constant';
It works for babel/webpack transpilation, but no for VSCode IntelliSense autocompletion.
I tried to play with the baseUrl and the paths, but no luck so far.

Mocking a class in typescript with jest

I am trying to unit test (with Jest) my handler module that makes use of a summary class.
My original summary class looks like:
import DynamoDBClient from './ddbClient/DynamoDBClient'
import { DynamoDB } from 'aws-sdk'
import { iSummaryReader, iObsSummariesAttributes } from './Summary.d'
import { JSONAPIResource } from '../JSONAPIResponse'
export default class Summary {
reader: iSummaryReader
constructor(reader: iSummaryReader) {
this.reader = reader
}
getSummary = async (keyName: string, keyValue: string): Promise<JSONAPIResource<iObsSummariesAttributes>> => {
return new Promise<JSONAPIResource<iObsSummariesAttributes>>((resolve, reject) => {
const gettingItem = this.reader.getItem(keyName, keyValue)
console.log(gettingItem)
gettingItem.then((resp) => {
resolve(resp)
}).catch((err: Error) => {
reject(err.message)
})
})
}
}
In my handler module I import with import Summary from './lib/Summary'
(Note: same line is used in handler.test.ts
Inside the handler function
try {
const dynamodbObj: iSummaryReader = new DynamoDBClient(documentClient, someTable)
const summary = new Summary(dynamodbObj)
const data: JSONAPIResource<iObsSummariesAttributes> = await summary.getSummary('id', someID)
}
My results depend on my approach if try an automatic mock
jest.mock('./lib/Summary', () =>
{
return {
getSummary: jest.fn()
}
})
I get the error
TypeError: Summary_1.default is not a constructor
If I create a manual mock under lib/__mocks__/Summary.ts with jest.mock('./lib/Summary') it does work until I get the point
expect(Summary).toHaveBeenCalledTimes(1)
Where it complains about me not being able to do this on summary. I also am unable to access my method to test that they are being called this way.
Note: My hanlder is for a lambda function so I am unable to inject the class that way where I have successfully tested that I can mock an injected class.
EDIT
The tsconfig.json is:
{
"compilerOptions": {
"rootDir": "./src",
"outDir": "./build",
"declaration": false,
"target": "es2015",
"moduleResolution": "node",
"module": "commonjs",
"noImplicitReturns": true,
"noImplicitThis": true,
"strictNullChecks": true,
"alwaysStrict": true,
"lib": [
"dom",
"es2015.promise",
"es2017.object",
"es2016"
],
},
"include": [
"src/**/*.ts"
],
}
I do not know why this was failing, but I the following steps seem to work to fix it.
Change the class export from default
From
`export default class Summary {`
to
`class summary`
+ export = summary at the end
Use import = require to import it.
import Summary = require('./lib/Summary')
Those two changes allowed it to find the jest.mock.

Webpack / typescript require works but import doesn't

I'm trying to import a node_module into a TypeScript file. I'm using an adaptation of angular2-webpack-starter for my project structure.
import ace from 'brace';
In one of my files gives me
Cannot find module 'brace'.
But
var ace = require('brace');
Works fine. According to this issue I shouldn't be having any problems.
My webpack config file is copied from angular2-webpack-starter.
My tsconfig.json is as follows
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"sourceMap": true
},
"files": [
"src/bootstrap.ts",
"src/vendor.ts",
"src/polyfills.ts"
],
"filesGlob": [
"./src/**/*.ts",
"!./node_modules/**/*.ts"
],
"compileOnSave": false,
"buildOnSave": false
}
Why would one work but not the other?
The answer is related to this issue. If a module doesn't have type data available (via a .d.ts file), the ES6 module syntax
import name from "module-name";
import * as name from "module-name";
import { member } from "module-name";
//etc
will not work and one must use the CommonJS alternative,
var name = require("module-name");