automatically updating path alias import after renaming/moving files - javascript

I'm using babel-plugin-module-resolver to make path alias.
{
"presets": ["#babel/preset-env", "#babel/preset-react"],
"plugins": [
[
"module-resolver",
{
"alias": {
"~": "./resources/src"
}
}
]
]
}
But whenever I start to move or modify a file name, the corresponding path in relevant import files are not automatically updated.
Does anyone know how I can make the renaming work with paths aliases?

Related

Eslint doesn't respect jsconfig paths

I have my express.js project in monorepo. I want to add custom path alias to it.
The directory structure is:
./
server/
----> jsconfig.json
----> .eslintrc.js
----> src/
--------> index.js
--------> modules/auth
-------------> auth.controller.js
jsconfig.json
{
"compilerOptions": {
"module": "ES6",
"baseUrl": "./",
"paths": {
"#modules/*": [
"src/modules/*"
]
}
},
"exclude": ["node_modules"]
}
.eslintrc.js
module.exports = {
env: {
es2021: true,
node: true,
},
extends: [
'airbnb-base',
],
parserOptions: {
ecmaVersion: 12,
sourceType: 'module',
},
rules: {
'no-console': 'error',
'no-debugger': 'error',
},
settings: {
'import/resolver': {
alias: {
map: [
['#modules/*', 'src/modules/*'],
],
extensions: ['.js', '.json'],
},
},
},
};
Simply, I just tried to import auth controller in my index.js file.
import authRoutes from '#modules/auth/auth.routes';
but I get the following error: Unable to resolve path to module '#modules/auth/auth.controller' .eslint import/no-unresolved
please, don't suggest to turn off the rule.
I've alreadyy tried eslint-import-resolver-jsconfig, but I got Cannot resolve jsConfig, SyntaxError } on 150.
Because I used monorepo, there was a problem for ESLint or even lint-staged.
So now I have only one project per repository and:
Added custom paths in jsconfig.json:
"paths": {
"#modules/*": [
"./src/modules/*"
]
}
Installed eslint-import-resolver-jsconfig and added the following configuration to the eslint.json:
"extends": [
"airbnb-base",
"eslint:recommended"
],
"plugins": ["import"],
"settings": {
"import/resolver": {
"jsconfig": {
"config": "jsconfig.json"
}
}
}
Installed the Babel plugin babel-plugin-module-resolver and added the following settings to the .babelrc:
"plugins": [
[
"module-resolver",
{
"alias": {
"#modules": "./src/modules"
}
}
]
]
But, again: This only works if you have one project per repository and all your configuration files (.*rc, package.json, etc) are in the root level.
To achieve the above I use the module-alias package.
After installing it as a normal dependency, npm i --save module-alias, add the following to your package.json:
"_moduleAliases": {
"#modules": "./src/modules"
}
That will basically define the mappings for all the aliases you want to define.
To make it work, you will now need to import the following on top of your application under index.js:
require("module-alias/register"); // If using commonJS
// or
import "module-alias/register"; // If transpiling es6
You are now all set and should be able to import your files with absolute paths looking as:
const authRoutes = require("#modules/auth/auth.routes")
// or
import authRoutes from "#modules/auth/auth.routes";
In case eslint still flags the unresolved path, you may need to update your jsconfig.json or tsconfig.json to contain the below:
"paths": {
"#modules/*": ["src/modules/*"]
}
You can find the package documentation and read more about its usage here.

VueJs Module build failed: Error: Couldn't find preset "#vue/app" relative to directory

I'm using vue-tour in my app, the problem is that when i imported the library my app doesn't work anymore, this the error when i try the command npm run dev:
error in ./~/vue-tour/dist/vue-tour.umd.js
Module build failed: Error: Couldn't find preset "#vue/app" relative to directory "C:\\xampp\\htdocs\\avanttia\\node_modules\\vue-tour"
at C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\options\option-manager.js:293:19
at Array.map (<anonymous>)
at OptionManager.resolvePresets (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\options\option-manager.js:275:20)
at OptionManager.mergePresets (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\options\option-manager.js:264:10)
at OptionManager.mergeOptions (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\options\option-manager.js:249:14)
at OptionManager.init (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\options\option-manager.js:368:12)
at File.initOptions (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\index.js:212:65)
at new File (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\file\index.js:135:24)
at Pipeline.transform (C:\xampp\htdocs\avanttia\node_modules\babel-core\lib\transformation\pipeline.js:46:16)
at transpile (C:\xampp\htdocs\avanttia\node_modules\babel-loader\lib\index.js:46:20)
at Object.module.exports (C:\xampp\htdocs\avanttia\node_modules\babel-loader\lib\index.js:163:20)
# ./resources/assets/js/wizard/main.js 49:15-34
# multi ./resources/assets/js/wizard/main.js
Importing the library like this:
import '#/bootstrap'
import VueDragDrop from 'vue-drag-drop'
import VueTour from 'vue-tour'
import Wizard from '#/wizard/containers/Wizard.vue'
require('/node_modules/vue-tour/dist/vue-tour.css')
const Vue = window.Vue
Vue.use(VueTour)
Vue.use(VueDragDrop)
const vm = new Vue({
el: '#wizard-app',
render: h => h(Wizard)
})
export default vm
Edit:
This is mi .babelrc config file:
{
"presets": [
[ "env", {
"targets": {
"uglify": true,
"node": "current"
},
"modules": false,
"loose": true,
"useBuiltIns": true,
"debug": true,
}]
],
"plugins": [
["component", [{
"libraryName": "element-ui",
"styleLibraryName": "theme-chalk"
}]],
["module-resolver", {
"alias": {
"#": "./resources/assets/js"
}
}],
["transform-es2015-template-literals", {
"loose": true,
"spec": true
}]
],
}
and the .babelrc config file from the vue-tour library:
{
"presets": [
"#vue/app"
]
}
Why vue can't find #vue/app?, looks like there is a conflict in the alias property, but i have no idea how to change without breaking the project config.
update:
if in the node_modules/vue-tour library i change the .babalrc file to this:
"presets": [
"es2015"
]
it works as expected, but this is undesired as i have to change everywhere i have to deploy this project.
After days struggling with this issue, i finally found a solution for this:
In the webpack.mix.js the es2015 transpilation was done like this:
{
test: /\.js$/,
exclude: /node_modules\/(?!(some-library)\/).*/,
include: [/node_modules\/vue-tour/], // <---Added this line!
use: {
loader: 'babel-loader',
options: {
presets: ['env']
}
}
}

Using jquery in a shared webpack module, which is outside the webpack root

I have multiple layouts, which depend on some shared typescript files, thats why I want to share this files with multiple layouts which are using webpack.
I'm trying to include jquery in my ajax.ts and get this error:
ERROR in ../_shared/ajax.ts
Module not found: Error: Can't resolve 'jquery' in '{...}/layouts/_shared'
_shared/ajax.ts:
import * as $ from 'jquery';
export class AjaxListener {
constructor(){
// use jquery with $
}
}
layoutA/app.ts:
import { AjaxListener } from "../_shared/ajax";
import { App } from "../_shared/app";
let app = new App();
let ajaxListener = new AjaxListener();
My Folder Structure looks like this:
/layouts
/_shared
/ajax.ts
/app.ts
/layoutA
/app.ts
/webpack.config.js
/package.json (contains "#types/jquery": "^2.0.47" and "jquery": "^3.2.1")
/tsconfig.json
tsconfig.json:
{
"compilerOptions": {
"module": "es6",
"target": "es6",
"sourceMap": true
},
"exclude": [
"node_modules",
"typings/browser",
"typings/browser.d.ts",
"typings/main",
"typings/main.d.ts"
]
}
webpack.config.js:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
var path = require("path");
var distPath = path.join(__dirname, "dist");
module.exports = [
{
entry: {
app: ['./app.sass', './app.ts']
},
resolve: {
extensions: [".tsx", ".js", ".ts", ".sass"]
},
cache: false,
output: {
path: distPath,
filename: "[name]_scripts.js"
},
module: {
rules : [
{
enforce: 'pre',
// "test" is commonly used to match the file extension
test: /\.js$/,
loader: "source-map-loader"
},
{
// "test" is commonly used to match the file extension
test: /\.tsx?$/,
exclude: [/node_modules/],
use: [ 'babel-loader', 'ts-loader' ]
},
{
test: /\.sass$/,
use: [
{
loader: "style-loader" // creates style nodes from JS strings
},{
loader: "css-loader", options: { sourceMap: true } // translates CSS into CommonJS
},{
loader: "sass-loader", options: { sourceMap: true } // compiles Sass to CSS
}
]
}
]
},
devtool: "eval"
}
]
If I try to import jquery inside layoutA/app.ts file (webpack root), it works fine. Since the ajax.ts lives outside this folder, which is the best way to import libraries like jquery, lodash etc. in these files?
The following points must be observed for the best way to load js libraries in your context:
Install every js library (e.g. jquery) with a package manager like npm
To each library it needs a TypeScript definitions file (e.g. #types/jquery, to find under npmjs.com)
Install this TypeScript definition file also with npm
Note every TypeScript definition in the tsconfig.json under "files" like
"files":[
"node_modules/#types/jquery/index.d.ts",
"node_modules/#types/requirejs/index.d.ts",
]
Do this compellingly (point 1-4) with the library requirejs. This is a js file and module loader.
Now you are ready to load the js library in the TypeScript main file like:
require(["jquery", "urijs"], function($, uri) {
// your code
});
Other notes:
In the index.html file: reference under the script tags only the js bundle files, builded by e.g. webpack.
Webpack needs a TypeScript loader.
Reference exported TypeScript classes in the tsconfig.json file under 'files' and also in the TypeScript file like:
import {Car} from "./classes/Car";
Hope it helps you, to get a proper structur!
Supplement:
Try the following: reference a js library in your ayax.ts like:
private example = require("./[path to npm library]/node_modules/test/src/test.js");
If you call the library name like 'test' in the require command, then its not possible to resolve 'test'. It try to resolve over the package.json and can not find it because its outside of the root.

Trying to integrate redux into react application. Webpack is choking on store.js

I'm trying to integrate redux into an existing react application. All of my react code is within jsx files. Now i'm introducing redux and a store.js. during the compilation webpack errors on an exepected token error on store.js
webpack.config.js
var webpack = require('webpack');
var path = require('path');
var BUILD_DIR = path.resolve(__dirname, 'project/static/public/js');
var APP_DIR = path.resolve(__dirname, 'project/static/public/js/components');
module.exports = {
entry: APP_DIR + '/App.jsx',
output: {
path: BUILD_DIR,
filename: 'bundle.js'
},
resolve: {
alias: {
'react': path.join(__dirname, 'node_modules', 'react')
}
},
module : {
loaders : [
{
test : /\.jsx/,
include : APP_DIR,
loader : 'babel',
presets : ['es2015']
},
{
test : /\.js/,
include : BUILD_DIR,
exclude : /bundle.js||bundle.js.map||node_modules/,
loader : 'babel',
presets : ['es2015']
}
]
},
watchOptions: {
poll: true
}
};
.babelrc
{
"presets": [
"es2015",
"react"
],
"env": {
"start": {
"presets": [
"react-hmre"
]
}
},
"plugins": [
["transform-es2015-arrow-functions", { "spec": true }],
["transform-class-properties"]
]
}
store.js
import { applyMiddleware, createStore} from 'redux';
import combineReducers from './reducers/index.js'
export default createStore(combineReducers)
error message
ERROR in ./project/static/public/js/store.js
Module parse failed: /home/username/git/project/project/static/public/js/store.js Line 1:
Unexpected token
You may need an appropriate loader to handle this file type.
| import { applyMiddleware, createStore} from 'redux';
| import combineReducers from './reducers/index.js'
|
# ./project/static/public/js/components/App.jsx 15:13-32
These files have gone through multiple iterations in trying to resolve and better understand redux. I think the problem is with my webpack configuration.
Which version of Babel are you using? I guess that you need to use the babel-loader in the webpack rule. This configuration works fines with Babel 7 and Webpack 4.
WEBPACK RULE:
{
test: /\.js$/,
include : BUILD_DIR,
exclude : /bundle.js||bundle.js.map||node_modules/,
use: {
loader: 'babel-loader',
},
},
And .babelrc file example:
{
"presets": [[
"#babel/preset-env", {
"useBuiltIns": "entry"
}],
"#babel/preset-react"],
"plugins": [
"#babel/plugin-proposal-class-properties",
"#babel/plugin-proposal-export-default-from",
"react-hot-loader/babel"
]
}
Please, keep in mind you need to install babel-loader at least version 8.0.0, babel core 7.0.0 and webpack 4.23.
But, I'm pretty sure that the problem is that you need to use the babel-loader plugin in webpack. Visit https://github.com/babel/babel-loader
Best!

When publishing NPM package I get an empty object my setup is (ES6,Babel,Webpack,React,Redux,Sagas)

Maybe somebody can help me with this.
I try to publish npm package with the following configuration:
webpack:
production: {
entry: [
'./src',
'./src/app.scss',
'draft-js/dist/Draft.css'
],
devtool: "source-map",
output: {
path: path.join(__dirname, 'lib'),
filename: 'stewie-editor.js',
library: 'stewie-editor',
libraryTarget: 'umd',
umdNamedDefine: true
}
},
package.json section dealing with library publishing
"main": "lib/stewie-editor.js",
"files": [
"lib",
"src"
],
My src/index.js file looks like this
import EditorComponent from 'EditorComponent';
import EditorFactory from 'EditorFactory';
export {
EditorFactory,
EditorComponent
}
.babelrc
{
"presets": ["es2015", "stage-2", "react"],
"plugins": ["babel-plugin-add-module-exports"],
"env": {
"test": {
"plugins": [
["css-modules-transform", {
"generateScopedName": "[name]__[local]",
"extensions": [".css", ".scss"]
}]
]
},
"dev": {
"plugins": [["react-transform", {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}]
}]]
}
}
}
I looked at the following example and there everything is working.
strangely with my setup things don't work
In a different project when I install stewie-editor npm package and import exported classes from the package like so:
import { EditorFactory } from 'stewie-editor';
I get undefined. When I try to look at the contents of the whole package importing it like so:
import stewie from 'stewie-editor';
I get an empty Object.
Your help will be very appreciated.
The empty object is as a result of a missing keyword in your index.js file: default.
You can fix this by rewriting the index.js file to:
export default {
EditorFactory,
EditorComponent
}
Well I figured out what was the problem. Adding scss and .css in webpack entry point resulted in an empty object. So I removed them from entry point and added as imports inside my EditorComponent.js file. That fixed the issue. Everything got exported.

Categories