ESLint Error when using in an adonisjs and inertia project.
I still haven't been able to find any configuration to fix this problem. Can anyone from the community help resolve this?
tsconfig.json
{
"extends": "adonis-preset-ts/tsconfig.json",
"include": [
"**/*"
],
"exclude": [
"node_modules",
"build"
],
"compilerOptions": {
"outDir": "build",
"rootDir": "./",
"sourceMap": true,
"paths": {
"App/*": [
"./app/*"
],
"Config/*": [
"./config/*"
],
"Contracts/*": [
"./contracts/*"
],
"Database/*": [
"./database/*"
]
},
"types": [
"#adonisjs/core",
"#adonisjs/repl",
"#adonisjs/session",
"#adonisjs/view",
"#adonisjs/shield",
"#japa/preset-adonis/build/adonis-typings",
"#eidellev/inertia-adonisjs"
]
}
}
--
Parsing error: ESLint was configured to run on `<tsconfigRootDir>/resources\js\Pages\Home.vue` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
The extension for the file (`.vue`) is non-standard. You should add `parserOptions.extraFileExtensions` to your config.
Related
I am coding with a NodeJS project in VS Code. The core code is in JavaScript and the declarations are written in ".d.ts" files. ESlint is enabled to enforce code style.
What I want is:
to check types for the JavaScript files when editing them in VS Code (not only when importing them as modules)
and it's better not to use /** #type {import('./utils').Rectangle} */ because it may bring a long #type string.
The project structure is as below:
workspace/
.eslintrc
tsconfig.json
utils.js
utils.d.ts
utils.d.ts is like (this code refers to another Stack Overflow question, but I can't find it):
export type Rectangle = {
width: number,
height: number
};
export as namespace _Utils;
utils.js is like:
/** #type {_Utils.Rectangle} */
let rect;
And VS Code returns ts(2552) "Cannot find name _Utils" in the hover information of _Utils.Rectangle.
tsconfig.json is as below (referring to How to use TypeScript declaration files alongside JavaScript):
{
"compilerOptions": {
"target": "es2021",
"module": "commonjs",
"sourceMap": true,
"declaration": true,
"rootDir": ".",
"allowJs": true,
"allowSyntheticDefaultImports": true,
"isolatedModules": true,
"noEmit": true,
"maxNodeModuleJsDepth": 2
},
"include": [
"**/*.d.ts"
]
}
.eslintrc is as below:
{
"env": {
"browser": true,
"commonjs": true,
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": "latest"
},
"rules": {
"indent": [
"error",
2
],
// "linebreak-style": [
// "error",
// "windows"
// ],
"quotes": [
"error",
"single"
],
"semi": [
"error",
"always"
]
},
"overrides": [
{
"files": "**/*.ts",
"parser": "#typescript-eslint/parser",
"extends": [
"eslint:recommended",
"plugin:#typescript-eslint/recommended"
],
"plugins": [
"#typescript-eslint"
]
}
]
}
So what should I do next?
I'm making React component library. Project structure is something like:
src/
components/
utils/
hooks/
Now I'm trying to generate types (.d.ts.) files using rollup. Types are generated but e.g. my component NumberInput is using absolute import from Input component like so:
import Input from "components/Input/Input";
Now imports in NumberInput.d.ts look exactly the same:
import Input from "components/Input/Input";
But now those imports in d.ts files are not gonna be resolved since there is no tsconfig.json for generated code (I Guess).
tsconfig.json
{
"compilerOptions": {
"module": "esnext",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"declaration": true,
"esModuleInterop": true,
"baseUrl": "src/",
"paths": {
"components/*": ["components/*"],
"models/*": ["hooks/*"],
"utils/*": ["utils/*"]
}
},
"exclude": ["node_modules", "build", "dist", "scripts", "acceptance-tests", "webpack", "jest"],
"types": ["typePatches"]
}
rollup.config.js
export default {
input: [
"./src/index.ts",
...getFiles("./src/components", extensions),
...getFiles("./src/hooks", extensions),
...getFiles("./src/utils", extensions)
],
output: [
{
dir: "dist",
format: "esm",
sourcemap: true
}
],
external: ["react", "react-dom", "styled-components"],
plugins: [
resolve(),
commonjs(),
typescript({
tsconfig: "./tsconfig.build.json",
declaration: true,
declarationDir: "dist"
}),
image(),
url({
include: ["**/*.woff2"],
limit: Infinity
}),
css(),
terser()
],
external: ["react", "react-dom", "styled-components"]
};
Is there any way I can control absolute imports when types are being generated? I wanna use absolute imports inside my project, but when types are generated I rly don't care how they look as long as they work.
The best working solution imo is nicely summed up in this article by using rollup-plugin-dts.
In plugin you can pass compilerOptions parameter, with basePath and paths so it will correctly resolve absolute imports of type declarations.
rollup.config.ts file:
...
plugins: [
dts({
compilerOptions: {
baseUrl: tsConfig.compilerOptions.baseUrl,
paths: tsConfig.compilerOptions.paths,
},
}),
],
...
You have told typescript for files, but rollup does not know how to actually resolve rollup will look in home folder if you write components/a.ts
There is a plugin for rollup #rollup/plugin-alias
plugins: [
alias({
entries: [
{ find: 'components', replacement: 'your path to components folder' },
]
})
]
EDIT
I am running a next.js project, as the project grew my imports became harder and harder to read.
Which is why I really love the path aliasing in jsconfig.json. Makes everything so much cleaner.
However, and that's a big however, I used to be able to click on any variable (or import) holding cmd and would be directly taken to the final definition. Same with getting a peek ("Code Peek") into the module/variable that I was importing.
This functionality did not seem to work with aliases. Installing module-resolver helped on the top level. I.e. click-through through is now possible for everything starting with #/Components but not the lower level aliases. Any Idea how to fix that?
Caveats:
I know I should, but I am currently not yet using es-lint,
nor am I explicitly using webpack (I know next.js uses it under the hood)
Plain Javascript (no typescript)
Those tools are surely useful, but I want to keep the additional tooling to a minimum right now.
Configs:
This is my jsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"#/Components/*": ["components/*"],
"#/Concepts/*": ["components/Concepts/*"],
...
}
}
}
this is my .babelrc
{
"presets": ["next/babel"],
"plugins": [
["styled-components", { "ssr": true }],
["module-resolver", {
"root": ["."],
"alias": {
"#/Components": "components",
"#/Concepts": "components/Concepts",
...
}
}]
]
}
I am importing like this (both imports work):
Click-through works:
import { Bold } from "#/Components/styles";
Click-through does not work:
import { DefaultMarginSlider, Formula } from "#/Concepts/utils";
for completeness sake here is my package.json
I got it working with the following config settings
jsconfig.json
{
"compilerOptions": {
"target": "es2020",
"module": "commonjs",
"allowSyntheticDefaultImports": true,
"baseUrl": "src",
"jsx": "react",
"noImplicitAny": false,
"paths": {
"components/*": [
"./components/*"
],
"utils/*": [
"./utils/*"
],
"UI/*": [
"./UI/*"
],
"assets/*": [
"./assets/*"
]
}
},
"exclude": ["node_modules"]
}
my .eslintec file looks like
{
"env": {
"browser": true,
"es6": true
},
"extends": [
"plugin:import/react",
"airbnb"
],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"settings": {
"import/resolver": {
"alias": {
"map": [
[
"UI",
"./src/UI"
],
[
"components",
"./src/components"
],
[
"assets",
"./src/assets"
]
],
"extensions": [
".js",
".jsx",
".svg",
".png"
]
},
"webpack": {
"config": "config/webpack.config.js"
}
}
},
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"parser": "babel-eslint",
"plugins": [
"react",
"react-hooks",
"import",
"resolver-alias"
],
"rules": {}
}
And there are the extra plugins I installed to get it working
eslint-import-resolver-alias
eslint-import-resolver-webpack
eslint-plugin-import
And this is my webpack config to resolve while building
resolve: {
modules: ['node_modules', paths.appNodeModules].concat(
modules.additionalModulePaths || []
),
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-dom': '#hot-loader/react-dom',
'components': path.resolve(__dirname, '../src/components'),
'assets': path.resolve(__dirname, '../src/assets'),
'UI': path.resolve(__dirname, '../src/UI'),
'utils': path.resolve(__dirname, '../src/utils'),
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
plugins: [
PnpWebpackPlugin,
new ModuleScopePlugin(paths.appSrc, [paths.appPackageJson]),
],
},
For next.js you can skip the above webpack config and eslint-import-resolver-webpack npm package. It will work fine.
When building my TypeScript project (all node modules are up to date) with the following configuration I get a error message called "Error: When building multiple chunks, the output.dir option must be used, not output.file."
Can anyone help? Thanks.
// [EDIT: I've simplified this configuration as the original
// one caused some misunderstandings]
// rollup.config.js
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
import typescript from 'rollup-plugin-typescript2'
import { uglify } from 'rollup-plugin-uglify'
import gzip from 'rollup-plugin-gzip'
export default {
input: 'src/main/my-project.ts',
output: {
file: 'dist/my-project.umd.production.js',
format: 'umd',
name: 'MyProject',
sourcemap: false,
globals: {
'react': 'React'
}
},
external: ['react'],
plugins: [
resolve(),
commonjs(),
typescript({
exclude: 'node_modules/**'
}),
uglify(),
gzip()
]
}
This is my tsconfig.json in case it may be important.
The build script is started by rollup --c rollup.config.js:
{
"compilerOptions": {
"target": "ES5",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"downlevelIteration": true,
"sourceMap": true,
"lib": ["es5", "es6", "dom"],
"esModuleInterop": true,
"baseUrl": ".",
"typeRoots": [
"node_modules/#types"
],
"types": [
"node", "react", "react-dom", "mocha", "chai"
]
},
"files": [
"src/main/my-project.ts"
],
"include": [
"./src/**/*.ts*"
]
}
I had a similar issue and as a fix I needed to specify the output module in package.json
{
...
"module": "./dist/index.esm.js",
...
}
And it's aligned with the rollup config:
output: [
{ file: pkg.main, format: 'cjs' },
{ file: pkg.module, format: 'esm' },
]
For all those how are still struggling to get this issue fixed and you are using dynamic imports in the component than you should add inlineDynamicImports: true just above output object
It seems that the configuration wasn't the problem, but there was still something wrong with the versions of my node modules.
After I did the following, everything worked fine again:
> ncu -u
> npm update
> npm install
The goal
I have an application that I'd like to migrate to TypeScript progressively. I'd like to be able to:
import *.ts files in Vue single file components
import *.ts files in regular *.js files.
import *.js files in *.ts files
My setup
The app was set up using vue-cli 3.x. I'm using Airbnb ESLint config.
The majority of the application is written in JS, but all newly added modules are written in TypeScript.
My .eslint.js config, before adding TypeScript was:
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/essential',
'#vue/airbnb',
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
parserOptions: {
parser: 'babel-eslint',
},
};
After I installed #vue/cli-plugin-typescript, typescript and #vue/eslint-config-typescript modules (using the vue add #vue/typescript command) I started getting ESLint errors after importing *.ts files in *.js files. These were only ESLint errors, not TypeScript or Babel compilation errors.
So I've modified the .eslint.js config as follows:
module.exports = {
root: true,
env: {
node: true,
},
extends: [
'plugin:vue/essential',
'#vue/airbnb',
],
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off',
},
overrides: [
{
files: [
'**/*.js',
'**/*.vue'
],
parserOptions: {
parser: 'babel-eslint',
},
},
{
files: [
'**/*.ts'
],
parserOptions: {
parser: 'typescript-eslint-parser',
},
}
],
};
I've added override sections in order to apply different parsers depending on a file extension.
My tsconfig.json file:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"allowJs": true,
"baseUrl": ".",
"types": [
"webpack-env",
"jest"
],
"paths": {
"#/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
So it is a standard tsconfig.json that vue-cli generates. The only thing I've changed was the allowJs: true - thanks to this I can import JS modules that don't have d.ts types definitions - that makes the migration easier.
The question
It all seems to be configured properly, but occasionally I'm getting ESLint errors. It looks like sometimes babel-eslint instead of typescript-eslint-parser is used to lint *.ts files. I don't know how to reproduce it, but I'm almost sure that it happens when I import *.ts files in *.vue files. Errors are usually gone when I stop and start Webpack again (with yarn serve).