eslint - webpack aliases - javascript

I have a webpack configuration file, which is actually a factory function (react-universally boilerplate).
I've added resolve option and it looks like this:
resolve: {
// These extensions are tried when resolving a file.
extensions: config('bundleSrcTypes').map(ext => `.${ext}`),
// This is required for the modernizr-loader
// #see https://github.com/peerigon/modernizr-loader
alias: {
modernizr$: path.resolve(appRootDir.get(), './.modernizrrc'),
Config: path.resolve(appRootDir.get(), './config'),
},
},
With this config I'm able to access the reducers like import config from 'Config', but my linter is throwing me errors:
'Config' should be listed in the project's dependencies. Run 'npm i -S Config' to add it (import/no-extraneous-dependencies)
'Config' should be listed in the project's dependencies. Run 'npm i -S Config' to add it (import/no-extraneous-dependencies)
Missing file extension for "Config" (import/extensions)
How can I add aliases to my eslinter configuration? I've tried several packages listed in the top google results for this problem, but they do not work. Is it possible to add the aliases to the .eslintrc manually?

You can list your aliases through the import/core-modules option under settings.
in your .eslintrc
"settings": {
"import/core-modules": [
"config-alias",
"another-alias"
]
}

Since the config import is a special exception, you can tell ESLint to ignore that line (for all rules or just a single rule)
https://eslint.org/docs/user-guide/configuring#disabling-rules-with-inline-comments

Related

Module parse failed: Unexpected token ? Optional chaining not recognised in threejs svgloader.js [duplicate]

Project setup:
Vuejs 3
Webpack 4
Babel
TS
We created the project using vue-cli and add the dependency to the library.
We then imported a project (Vue Currency Input v2.0.0) that uses optional chaining. But we get the following error while executing the serve script:
error in ./node_modules/vue-currency-input/dist/index.esm.js
Module parse failed: Unexpected token (265:36)
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
| getMinValue() {
| let min = this.toFloat(-Number.MAX_SAFE_INTEGER);
> if (this.options.valueRange?.min !== undefined) {
| min = Math.max(this.options.valueRange?.min, this.toFloat(-Number.MAX_SAFE_INTEGER));
| }
I read that Webpack 4 doesn't support optional chaining by default. So, we added the Babel plugin for optional chaining. This is our babel.config.js file:
module.exports = {
presets: ["#vue/cli-plugin-babel/preset"],
plugins: ["#babel/plugin-proposal-optional-chaining"],
};
(But, if I am correct, this plugin is now enable by default in the babel-preset. So this modification might be useless ^^)
One thing that I don't understand is that we can use optional chaining in the .vue files.
I created a SandBox with all the files: SandBox
How could I solve this error?
I was able to overcome this issue using #babel/plugin-proposal-optional-chaining, but for me the only way I could get Webpack to use the Babel plugin was to shove the babel-loader configuration through the Webpack options in vue.config.js. Here is a minimal vue.config.js:
const path = require('path');
module.exports = {
chainWebpack: config => {
config.module
.rule('supportChaining')
.test(/\.js$/)
.include
.add(path.resolve('node_modules/PROBLEM_MODULE'))
.end()
.use('babel-loader')
.loader('babel-loader')
.tap(options => ({ ...options,
plugins : ['#babel/plugin-proposal-optional-chaining']
}))
.end()
}
};
NB replace "PROBLEM_MODULE" in the above with the module where you have the problem.
Surprisingly I did not need to install #babel/plugin-proposal-optional-chaining with NPM. I did a go/no-go test with an app scaffolded with #vue/cli 4.5.13, in my case without typescript. I imported the NPM module that has been causing my grief (#vime/vue-next 5.0.31 BTW), ran the serve script and got the Unexpected token error on a line containing optional chaining. I then plunked the above vue.config.js into the project root and ran the serve script again, this time with no errors.
My point is it appears this problem can be addressed without polluting one's development environment very much.
The Vue forums are in denial about this problem, claiming Vue 3 supports optional chaining. Apparently not, however, in node modules. A post in this thread by atflick on 2/26/2021 was a big help.
Had same issue with Vue 2 without typescript.
To fix this you need to force babel preset to include optional chaining rule:
presets: [
[
'#vue/cli-plugin-babel/preset',
{
include: ['#babel/plugin-proposal-optional-chaining'],
},
],
],
Can also be achieved by setting old browser target in browserslist config.
Most importantly, you need to add your failing module to transpileDependencies in vue.config.js:
module.exports = {
...
transpileDependencies: ['vue-currency-input],
}
This is required, because babel by default will exclude all node_modules from transpilation (mentioned in vue cli docs), thus no configured plugins will be applied.
I had a similar problem. I'm using nuxt but my .babelrc file looks like the below, and got it working for me.
{
"presets": [
["#babel/preset-env"]
],
"plugins":[
["#babel/plugin-transform-runtime",
{
"regenerator": true
}
]
],
"env": {
"test": {
"plugins": [
["transform-regenerator", {
"regenerator": true
}],
"#babel/plugin-transform-runtime"
],
"presets": [
["#babel/preset-env", {
"useBuiltIns": false
}]
]
}
}
}
I managed to fix the solution by adding these lines to package.json:
...
"scripts": {
"preinstall": "npx npm-force-resolutions",
...
},
"resolutions": {
"acorn": "8.0.1"
},
...

Webpack resolve alias and compile file under that alias

I have project which uses lerna ( monorepo, multiple packages ). Few of the packages are standalone apps.
What I want to achieve is having aliases on few of the packages to have something like dependency injection. So for example I have alias #package1/backendProvider/useCheckout and in webpack in my standalone app I resolve it as ../../API/REST/useCheckout . So when I change backend provider to something else I would only change it in webpack.
Problem
Problem appears when this alias is used by some other package ( not standalone app ). For example:
Directory structure looks like this:
Project
packageA
ComponentA
packageB
API
REST
useCheckout
standalone app
ComponentA is in packageA
useCheckout is in packageB under /API/REST/useCheckout path
ComponentA uses useCheckout with alias like import useCheckout from '#packageA/backendProvider/useCheckout
Standalone app uses componentA
The error I get is that Module not found: Can't resolve '#packageA/backendProvider/useCheckout
However when same alias is used in standalone app ( that has webpack with config provided below ) it is working. Problem occurs only for dependencies.
Potential solutions
I know that one solution would be to compile each package with webpack - but that doesn't really seem friendly. What I think is doable is to tell webpack to resolve those aliases to directory paths and then to recompile it. First part ( resolving aliases ) is done.
Current code
As I'm using NextJS my webpack config looks like this:
webpack: (config, { buildId, dev, isServer, defaultLoaders }) => {
// Fixes npm packages that depend on `fs` module
config.node = {
fs: "empty"
};
const aliases = {
...
"#package1/backendProvider": "../../API/REST/"
};
Object.keys(aliases).forEach(alias => {
config.module.rules.push({
test: /\.(js|jsx)$/,
include: [path.resolve(__dirname, aliases[alias])],
use: [defaultLoaders.babel]
});
config.resolve.alias[alias] = path.resolve(__dirname, aliases[alias]);
});
return config;
}
You don’t need to use aliases. I have a similar setup, just switch to yarn (v1) workspaces which does a pretty smart trick, it adds sym link to all of your packages in the root node_modules.
This way, each package can import other packages without any issue.
In order to apply yarn workspaces with lerna:
// lerna.json
{
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [
"packages/**"
],
}
// package.json
{
...
"private": true,
"workspaces": [
"packages/*",
]
...
}
This will enable yarn workspace with lerna.
The only think that remains to solve is to make consumer package to transpile the required package (since default configs of babel & webpack is to ignore node_module transpilation).
In Next.js project it is easy, use next-transpile-modules.
// next.config.js
const withTM = require('next-transpile-modules')(['somemodule', 'and-another']); // pass the modules you would like to see transpiled
module.exports = withTM();
In other packages that are using webpack you will need to instruct webpack to transpile your consumed packages (lets assume that they are under npm scope of #somescope/).
So for example, in order to transpile typescript, you can add additional module loader.
// webpack.config.js
{
...
module: {
rules: [
{
test: /\.ts$/,
loader: 'ts-loader',
include: /[\\/]node_modules[\\/]#somescope[\\/]/, // <-- instruct to transpile ts files from this path
options: {
allowTsInNodeModules: true, // <- this a specific option of ts-loader
transpileOnly: isDevelopment,
compilerOptions: {
module: 'commonjs',
noEmit: false,
},
},
}
]
}
...
resolve: {
symlinks: false, // <-- important
}
}
If you have css, you will need add a section for css as well.
Hope this helps.
Bonus advantage, yarn workspaces will reduce your node_modules size since it will install duplicate packages (with the same semver version) once!

Error: Cannot use GraphQLSchema "[object GraphQLSchema]" from another module or realm

Given the following code:
import { graphql } from 'graphql'
import graphqlTools from 'graphql-tools'
const { makeExecutableSchema } = graphqlTools
const typeDefs = `
type Query {
as: [A]
}
type A {
x: Int,
y: Int
}
`
const schema = makeExecutableSchema ({ typeDefs })
graphql(schema, '{ as { x, y } }').then(console.log)
I get this error:
Error: Cannot use GraphQLSchema "[object GraphQLSchema]" from another
module or realm.
Ensure that there is only one instance of "graphql" in the
node_modules directory. If different versions of "graphql" are the
dependencies of other relied on modules, use "resolutions" to ensure
only one version is installed.
What's going on?
This situation may also occur when the version of the graphql module you have installed is different from the version installed and used by graphql-tools.
I have found you can correct this by either:
Changing the version of graphql in your project's package.json file to match exactly what graphql-tools depends on in its package.json file.
Removing graphql as a dependency and just installing graphql-tools. Then you will automatically receive whatever graphql module version that graphql-tools installs (as long as you don't depend on any other packages that install another, conflicting version).
In other cases you might have the correct version, but it may be installed multiple times. You can use npm ls graphql to see all the installed versions. Try running npm dedupe to remove duplicate installations.
This happens because graphql-tools module imports graphql from its CommonJS module, while my code does it from the ES module. That is, each object in my own module comes from the ES module, while graph-tool's not.
Solution
It's as easy as importing anything from graphql importing the CommonJS module, and both objects from graphql and graphql-tools will be able to talk each together:
import graphql_ from 'graphql/index.js'
import graphqlTools from 'graphql-tools'
const { graphql } = graphql_
const { makeExecutableSchema } = graphqlTools
const typeDefs = `
type Query {
as: [A]
}
type A {
x: Int,
y: Int
}
`
const schema = makeExecutableSchema ({ typeDefs })
graphql(schema, '{ as { x, y } }').then(console.log)
My problem was both .js an .mjs graphql files are resolved due to wrong webpack configuration.
Root cause:
From TypeMapper.mjs file in graphql-compose, import statement does not have file extension and that was a failure on webpack bundle. In order to solve it, I required to add fullySpecified:false into the webpack config.
{
test: /\.m?js/,
include: /node_modules/,
type: "javascript/auto",
resolve: {
fullySpecified: false
}
}
And I also modified resolve statement like
resolve: {
extensions: [".ts", ".js", ".mjs"] // that was the actual problem
}
Since fullySpecified config has been set to false, webpack was trying to resolve files without extension respect to the order of resolve.extentions config. Due to the wrong order in that config, graphql files with .js ext were been resolving although all other files were using .mjs one.
Solution:
Simply re-order resolve.extensions config as
resolve: {
extensions: [".ts", ".mjs", ".js"]
}
In my case, I added the webpack-node-externals library to the webpack configuration, and I was able to run my bundled application.
externalsPresets: { node: true },
externals: [nodeExternals()],
I am using webpack version 5.*
Also I am using yarn package manager, so I added resolutions in my package.json
"resolutions": {
"graphql": "^15.3.0"
}
For me, it was solved by downgrading some packages like this:
"apollo": "^2.33.4", "graphql": "^15.5.0",
I also deleted node_modules and package-lock.json and installed packages with yarn instead of npm.
I got this exact error when my .npmrc did not have proper entries such as username and password. We are using jFrog to normalise package installation. .npmrc should be located at root with proper entries.
ex: .npmrc file which works
#<company-name>:registry=<registry-url>
//<artifactory-name>:_password=${PASSWORD}
//<artifactory-name>:username=${JFROG_USERNAME}
//<artifactory-name>:email=${YOUR_EMAIL}
//<artifactory-name>:always-auth=true

`.babelrc` file can't find presets in a nested node_modules folder

I have a directory structure like this:
> build
> node_modules
> webpack.config.js
> .babelrc
> .gitignore
My .babelrc looks like this:
{
"presets": ["es2015", "stage-0", "react"]
}
Currently I'm getting the following error...
Module build failed: Error: Couldn't find preset "es2015" relative to directory
Are there any options within the .babelrc file that will allow me to specify the path to node_modules? Or any other way to fix this issue?
Unfortunately there is no way to move the node_modules out to the root.
Unfortunately there is currently no option in .babelrc to control the way Babel loads modules. But there are a few workarounds to solve the problem in various situations.
Babel actually accepts both strings and (module) objects as presets and plugins, so you can pass either the module's name (in which case Babel will try to resolve and load it using its own mechanism), or you can load the module yourself and pass it directly to Babel.
The problem is that if you use .babelrc, as it's JSON, you can obviously only pass the module's name, which subjects you to Babel's built-in module-loading mechanism.
If you use webpack, you can abandon .babelrc altogether and directly pass options to Babel in webpack config, like this:
query: {
presets: [
'babel-preset-es2015',
'babel-preset-react',
'babel-preset-stage-0',
].map(require.resolve),
}
See: How to set resolve for babel-loader presets
If you use Babel directly, in your own code, then you can still use .babelrc, but change the code that reads it, to load the presets and plugins yourself.
for example, if you have the following code to read .babelrc:
var fs = require('fs');
var babelrc = fs.readFileSync('./.babelrc');
var config = JSON.parse(babelrc);
require('babel-core/register')(config);
You can change it to something like:
var fs = require('fs');
var babelrc = fs.readFileSync('./.babelrc');
var config = JSON.parse(babelrc);
config.presets = config.presets.map(function(preset) {
return require.resolve('babel-preset-' + preset);
});
config.plugins = config.plugins.map(function(plugin) {
return require.resolve('babel-plugin-' + plugin);
});
require('babel-core/register')(config);
You're looking for the resolve property in webpack.
resolve lets you set the source location for your modules:
resolve: {
modulesDirectories: ['build/node_modules']
},

"No ESLint configuration found" error

Recently, we've upgraded to ESLint 3.0.0 and started to receive the following message running the grunt eslint task:
> $ grunt eslint
Running "eslint:files" (eslint) task
Warning: No ESLint configuration found. Use --force to continue.
Here is the grunt-eslint configuration:
var lintTargets = [
"<%= app.src %>/**/*/!(*test|swfobject)+(.js)",
"test/e2e/**/*/*.js",
"!test/e2e/db/models/*.js"
];
module.exports.tasks = {
eslint: {
files: {
options: {
config: 'eslint.json',
fix: true,
rulesdir: ['eslint_rules']
},
src: lintTargets
}
}
};
What should we do to fix the error?
The error you are facing is because your configuration is not present.
To configure the eslint type
eslint --init
then configure as your requirement.
then execute the project again.
I've had the same error. It seems to need configuration.
Go to your project root & run in terminal
./node_modules/.bin/eslint --init
Try to swap config with configFile. Then :
Create eslint.json file and
Point the right location of it (relative to Gruntfile.js file)
Place some configuration in that file (eslint.json), i.e.:
.
{
"rules": {
"eqeqeq": "off",
"curly": "warn",
"quotes": ["warn", "double"]
}
}
for more examples, go here.
I hade the same problem with Gulp and running "gulp-eslint": "^3.0.1" version.
I had to rename config: to configFile in Gulp task
.pipe(lint({configFile: 'eslint.json'}))
For those having the same problem, this is how we've fixed it.
Following the Requiring Configuration to Run migration procedure, we had to rename eslint.json to .eslintrc.json which is one of the default ESLint config file names now.
We've also removed the config grunt-eslint option.
Create a new file on the root directory called .eslintrc.json file:
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": "error"
}
}
Just follow the steps
1.create eslint config file name eslintrc.json
2.place the code as given below
gulp.src(jsFiles)
// eslint() attaches the lint output to the "eslint" property
// of the file object so it can be used by other modules.
.pipe(eslint({configFile: 'eslintrc.json'}))
// eslint.format() outputs the lint results to the console.
// Alternatively use eslint.formatEach() (see Docs).
.pipe(eslint.format())
// To have the process exit with an error code (1) on
// lint error, return the stream and pipe to failAfterError last.
.pipe(eslint.failAfterError());
Webpack
I had eslint.rc file in my root project directory but event though
I was getting error.
Solution was to add exclude property to "eslint-loader" rule config:
module.exports = {
// ...
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
loader: "eslint-loader",
options: {
// eslint options (if necessary)
}
},
],
},
// ...
}
We faced this problem today and realized, that the issue was not caused inside the project that we were working on, but inside a package that we had a link on using the command:
yarn link
Which is a feature often useful to test out new features or when trying to debug an issue in a package that manifests itself in another project.
We solved it by either removing the link, or in case of ember.js disabling the developer mode of our addon package.
index.js
module.exports = {
isDevelopingAddon: function() {
return false;
},
...
}
gulp.task('eslint',function(){
return gulp.src(['src/*.js'])
.pipe(eslint())
.pipe(eslint.format())
});
`touch .eslintrc` instead of .eslint
these two steps may help you!
Run the command ember init.
When it asks for overwriting the existing file(s). Type n to skipping overwriting the file.
Now it will automatically create required files like .eslintrc, etc.
For me the same issue occurred when i copied my folder except dist, dist_production and node_modules folder to another system and tried running ember build.

Categories