I have a problem involving configuring tsconfig path alias with react-native, at the moment I just did 2 changes:
tsconfig file
"extends": "expo/tsconfig.base",
"compilerOptions": {
"jsx": "react",
"strict": true,
"baseUrl": "./src",
"paths": {
"#/assets/*": ["assets/*"],
"#/components/*": ["components/*"],
"#/context/*": ["context/*"],
"#/hooks/*": ["hooks/*"],
"#/locales/*": ["locales/*"],
"#/routes/*": ["routes/*"],
"#/screens/*": ["screens/*"],
"#/services/*": ["services/*"],
"#/types/*": ["types/*"],
"#/utils/*": ["utils/*"],
}
},
"plugins": [
{
"name": "typescript-styled-plugin"
}
]
}
babel.config.js
module.exports = function(api) {
api.cache(true);
const plugins = [
[
require.resolve("babel-plugin-module-resolver"),
{
root: ["./src"],
extensions: [
'.js',
'.jsx',
'.ts',
'.tsx',
'.android.js',
'.android.tsx',
'.ios.js',
'.ios.tsx',
],
alias: {
"#/components": "./components",
"#/ui": "./ui",
"#/util": "./util",
"#/screens": "./screens",
"#/navigation": "./navigation",
"#/constants": "./constants",
"#/assets": "./assets",
"#/hooks": "./hooks",
},
},
]
]
return {
presets: ['babel-preset-expo'],
plugins
};
};
The problem seems in the babel config, because I can do all my imports with # and they are found correctly, just when I run the application I get the following errors:
VM34:2 Uncaught ReferenceError: process is not defined
at Object.4043 (<anonymous>:2:13168)
at r (<anonymous>:2:306599)
at Object.8048 (<anonymous>:2:9496)
at r (<anonymous>:2:306599)
at Object.8641 (<anonymous>:2:1379)
at r (<anonymous>:2:306599)
at <anonymous>:2:315627
at <anonymous>:2:324225
at <anonymous>:2:324229
at HTMLIFrameElement.e.onload (index.js:1:1)
Cannot find module '#/locales/de/common.json'
tried to add cwd: "babelrc",to the configuration, the module error disappeared but the process one stayed
Anybody know what is wrong and can give me a hand on this? thanks a lot :slightly_smiling_face:
Related
I use Vue 3 on Vite.js with Eslint + Airbnb config. Airbnb config has a rule eslint(import/no-unresolved), which is good, but Eslint doesn't know how to resolve alias path.
I want to use aliases for paths — example:
import TableComponent from '#/components/table/TableComponent.vue'˙
Environment is in plain JavaScript.
I managed to set up my vite.config.js so that the app can resolve paths like this:
import path from 'path';
import { defineConfig } from 'vite';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [{
find: "#", replacement: path.resolve(__dirname, 'src')
},],
},
});
Vue app works like that and resolves the import path correctly, but Eslint keeps reporting the error: Unable to resolve path to module eslint(import/no-unresolved)
How and where can I tell Eslint how to resolve aliases?
I have tried:
install eslint-plugin-import eslint-import-resolver-alias --save-dev
// .eslintrc.js
// ...
extends: [
'eslint:recommended',
'plugin:import/recommended',
'airbnb-base',
'plugin:vue/vue3-strongly-recommended',
],
settings: {
'import/resolver': {
alias: {
map: [
['#', 'src'],
],
},
},
},
But that doesn't work.
EDIT:
Solved the issue, see the accepted answer if you're using plain JavaScript like I do.
If you're using TypeScript, see if Seyd's answer can help you.
this solves the issue in my TypeScript project.
npm install eslint-import-resolver-typescript
After eslint-import-resolver-typescript installation
{
// other configuration are omitted for brevity
settings: {
"import/resolver": {
typescript: {} // this loads <rootdir>/tsconfig.json to eslint
},
},
}
should be added to .eslintrc.js.
my tsconfig.json (remove unwanted settings)
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"strict": false,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"types": ["vite/client", "node"],
"baseUrl": ".",
"paths": {
"#/*": ["src/*"]
},
"allowJs": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"exclude": ["node_modules"]
}
Check the discussion here:
In case someone runs into this problem, this works in my case*:
settings: {
'import/resolver': {
alias: {
map: [
['#', './src'],
],
},
},
},
*In my case, Vue's root is 'src' directory, while Eslint's is one level higher, so it needs the './src' path.
Huge thanks to #https://github.com/aladdin-add for the answer through the github question!
I had the same problem, and even I fixed the src path it still hat the issue. It did not work until I added extensions:
"settings": {
"import/resolver": {
"alias": {
"map": [
["#", "./src"]
],
"extensions": [".js",".jsx"] <--- HERE
}
}
},
1. Use & export aliases in vite.config.js
// vite.config.js
import { resolve } from 'path';
import { defineConfig } from 'vite';
export const aliases = {
'#': resolve(__dirname, './src'),
'#u': resolve(__dirname, './src/utils'),
};
export default () => defineConfig({
// ...
resolve: {
alias: aliases,
},
})
2. Create .eslintrc with ES Modules support. (Thanks to Morgan's answer)
2.1 npm i esm -D
2.2 Create sibling to .eslintrc.js — .eslintrc.esm.js.
2.3 Put your your ESLint config into .eslintrc.esm.js.
// .eslintrc.esm.js
export default {
root: true,
extends: ['#vue/airbnb', 'plugin:vue/recommended'],
// ...
}
2.4 Inside .eslintrc.js include this code:
const _require = require('esm')(module)
module.exports = _require('./.eslintrc.esm.js').default
3. Import, map & use aliases from vite.config.js in .eslintrc.esm.js
3.1 npm i eslint-import-resolver-alias -D
3.2 Inside .eslintrc.esm.js include following code:
// .eslintrc.esm.js
import { aliases } from './vite.config';
const mappedAliases = Object.entries(aliases).map((entry) => entry); // [[alias, path], [alias, path], ...]
export default {
// ...
settings: {
'import/resolver': {
alias: {
map: mappedAliases,
},
},
},
}
I can't for the life of me get this to work, I've tried everything above. Is there something else wrong with my file?
// .eslintrc.cjs
/* eslint-env node */
require("#rushstack/eslint-patch/modern-module-resolution");
module.exports = {
root: true,
extends: [
"airbnb",
"plugin:vue/vue3-essential",
"eslint:recommended",
"#vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
// Using the accepted answer
settings: {
"import/resolver": {
alias: {
map: [["#", "./src"]],
},
},
},
};
** UPDATE **
The only way I was able to get this to work was using this: eslint-config-airbnb link here, the readme was particularly helpful.
npm add --dev #vue/eslint-config-airbnb #rushstack/eslint-patch
My .eslintrc.js is now:
/* eslint-env node */
require("#rushstack/eslint-patch/modern-module-resolution");
const path = require("node:path");
const createAliasSetting = require("#vue/eslint-config-airbnb/createAliasSetting");
module.exports = {
root: true,
extends: [
"plugin:vue/vue3-essential",
"#vue/eslint-config-airbnb", // <-- added
"eslint:recommended",
"#vue/eslint-config-prettier",
],
parserOptions: {
ecmaVersion: "latest",
},
rules: {
"import/no-unresolved": "error",
},
settings: {
...createAliasSetting({
"#": `${path.resolve(__dirname, "./src")}`,
}),
},
};
Huzzah!
In the README.md of eslint-plugin-import it is said:
Currently Node and webpack resolution have been implemented, but the resolvers are just npm packages, so third party packages are supported (and encouraged!).
Here you can see the list of the third party resolvers.
One that worked for me was this: eslint-import-resolver-custom-alias, and this is how I used it:
settings:
import/resolver:
eslint-import-resolver-custom-alias:
alias:
'#': './app/javascript'
extensions:
- '.js'
- '.vue'
For me the # had been set as an alias for app/javascript inside vite.config.ts, you should change this based on your project configurations.
in .eslintrc.js add
settings: {
'import/resolver': {
alias: {
map: [['#', './src/']],
extensions: ['.js', '.vue'],
},
},
},
I was setting up Typescript and Webpack on an old project of mine and suddenly encountered this error:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
Then I have created a new project from scratch that goes as follow:
webpack.config.js
const webpack = require('webpack');
const path = require('path');
module.exports = {
mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
entry: {
main: './src/index.ts'
},
module: {
rules: [
{
test: '/\.ts$',
use: {
loader: 'babel-loader',
options: {
presets: [
'#babel/preset-env',
'#babel/preset-typescript'
]
}
},
exclude: /node_modules/
}
]
},
resolve: {
extensions: ['.ts'],
},
plugins: [
new webpack.CleanPlugin(),
],
output: {
filename: '[name].[contenthash].js',
path: path.join(__dirname, 'dist')
},
}
tsconfig.json
{
"compilerOptions": {
"baseUrl": "./",
"rootDir": "src",
"outDir": "dist",
"lib": ["ES6", "DOM"],
"target": "es5",
"module": "es6",
"noImplicitAny": true,
"removeComments": true
}
}
src/index.ts (sourced from here)
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
let greeter = new Greeter("world");
greeter.greet();
... and the error appears again :/
ERROR in ./src/index.ts 2:12
Module parse failed: Unexpected token (2:12)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
I feel like I'm missing something, what it can be?
ps: I have tried also different loaders as ts-loader and awesome-typescript-loader.
Thanks! Any help is appreciated :*
The root cause is that your Typescript rule isn't matching ("currently no loaders are configured to process this file"), so Webpack is reading your TS files as Javascript and getting thrown by the TypeScript-specific : on line 2 character 12. From your webpack.config.js:
test: '/\.ts$',
This should be a regular expression. Note the lack of single quotes:
test: /\.ts$/,
See Webpack docs Rule.test and Condition for more.
I have a .ts file in my project which makes use of imports. These imports, of course, don't work in the browsers, so I want to compile my typescript files to be supported in browsers
{
"compilerOptions": {
"noImplicitAny": true,
"lib": ["es2017", "es7", "es6", "dom"],
"module": "CommonJS",
"target": "es5"
},
"files": [
"test.ts"
]
}
Just for testing, I added the test.ts. It's contents are
import Axios from "axios";
var axios = Axios.create();
axios.get("https://www.example.com");
Now, when I run the build process, this is the result
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var axios_1 = require("axios");
var axios = axios_1.default.create();
axios.get("https://www.example.com");
And when I use this in my index.html
<script src="test.js"></script>
It simply says ReferenceError: exports is not defined
I can't imagine that it can be so hard and difficult to compile TypeScript using imports to browser-compatible JavaScript. Any help would be greatly appreciated.
It works, when I use webpack and a webpack.config.js which looks like this
const path = require('path');
module.exports = {
entry: './test.ts',
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: [ '.tsx', '.ts', '.js' ],
},
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
};
However, do I really need webpack for this? I'm not against webpack and the plan was to use it later on anyway, but still, is there no other way?
In my nextjs project I have mapped path in jsconfig.json to make easy absolute imports
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"#/*": ["./*"]
},
"target": "es6",
"module": "commonjs",
"experimentalDecorators": true
}
}
My import paths look like this
import { VIEW } from '#/src/shared/constants';
My eslintrc.js has settings specified as
module.exports = {
... ,
settings: {
"import/resolver": {
alias: {
extensions: [".js"],
map: ["#", "."]
}
}
}
}
I am still getting the error saying can't resolve "#/what/ever/my/path/is"
How do I make eslint realize the jsconfig path
I was using babel-eslint as my parser in eslintrc. While searching, I realized I need to add babel-plugin-module-resolver in babelrc to resolve the modules. In this file we can define our mapped paths which are there in our jsconfig.
Hence adding the following plugin in the babelrc file compiled my code successfully.
[
"module-resolver",
{
"alias": {
"#": "./"
}
}
]
According to the docs for eslint-import-resolver-alias, the map property should be an array of arrays, so try this:
module.exports = {
... ,
settings: {
"import/resolver": {
alias: {
extensions: [".js"],
map: [ ["#", "."] ]
}
}
}
}
Also, double-check that you actually have eslint-import-resolver-alias installed - it's easy to forget!
In my React project, where ./ is the root directory, I have configured webpack so that I can import any file from within my ./src directory.
For example, consider the following directory structure:
./
|-src/
| |-components/
| | |-Button/
| | | |-index.js
| | | |-Button.jsx
where src/components/Button/index.js contains just this:
export { default } from './Button';
Now let's say I create another component in src/components/NewComponent, which is structured similarly to src/components/Button, but inside my NewComponent.jsx I am doing the following:
import Button from 'components/Button'
The above compiles just fine because I have set up my webpack correctly.
What I would like to be able to do, is for VSCode to be able to take me to the definition of the Button component when I alt+click on the word Button of the import statement, and take me to the index.js file's contents when I alt+click on the components/Button part.
I cannot seem to be able to do that.
My jsconfig.json is the following, as of the time of writing:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"baseUrl": "./",
"paths": {
"src/*": ["./src/*"]
}
},
"exclude": ["node_modules", "build", "dist"]
}
And, for good measure, the relevant part of my webpack config:
const PATHS = {
node_modules: path.resolve(__dirname, 'node_modules'),
src: path.resolve(__dirname, 'src'),
style: path.resolve(__dirname, 'style'),
assets: path.resolve(__dirname, 'assets'),
test: path.resolve(__dirname, 'test')
};
module.exports = {
resolve: {
modules: [
path.resolve(__dirname),
PATHS.node_modules,
PATHS.src,
PATHS.style,
PATHS.assets,
PATHS.test
],
mainFiles: ['index', 'index.js', 'index.jsx', 'index.scss'],
extensions: ['.jsx', '.js', '.json', '.scss', '.css']
},
....
I think your configuration is correct the only mistake you've made is in the path setting.
Try this:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"baseUrl": "./",
"paths": {
"components/*": ["./src/components/*/index"]
}
},
“Include”: [“./src/**/*”],
"exclude": ["node_modules", "build", "dist"]
}
or just type import Button from 'src/components/Button'
after this close-reopen the project et voilà ;)