Eslint not defined issue with imports - javascript

I have an App.js file like this:
import './bootstrap';
if (document.getElementById('vue')) {
new Vue({
});
}
It imports a bootstrap javascript file which holds the Vue npm package(node module).
In my bootstrap file I import it like so:
import Vue from 'vue';
When I run eslint with this setup though I get told:
'Vue' is not defined.
If the eslinter only checks per file this seems really obvious since the actually Vue variable is defined in a file that is imported. Can this be fixed cleanly though or do I have to edit my .eslintrc.js for a case like this?

I believe ES6 imports only apply to the current file (which is the main benefit of a module system – to avoid global contamination). Importing a module without bindings won't also make that module's imports available; they remain scoped to that module only.
You have a few options:
You can explicitly import it everywhere you need it (the intended way with modules).
import Vue from 'vue';
You can export Vue (and anything else) from your bootstrap file and import everything:
In bootstrap.js:
import Vue from 'vue';
export { Vue };
In App.js:
import * as bootstrap from './bootstrap';
const Vue = bootstrap.Vue;
You can make Vue global from in your bootstrap file, but it defeats the benefit of modules:
window.Vue = Vue;
The import and export articles at MDN give a good overview of different possible ways of importing and exporting.

You can try few configuration of eslint in .eslintrc to get this working. This error is coming with es6-modules, you can try playing with following config:
{
"parserOptions": {
"ecmaVersion": 6,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true
}
},
"rules": {
"semi": 2
}
}

Related

Can't import Vonage Client SDK into my preact (vite) project

I have a Preact project using Vite. I want to use the nexmo-client SDK from vonage but when I import using the ES method it breaks my project.
// app.tsx
import NexmoClient from 'nexmo-client';
I get the following error in the console.
index.js:19 Uncaught ReferenceError: global is not defined
at index.js:19:19
at index.js:12:22
at node_modules/nexmo-client/dist/index.js (index.js:16:1)
at __require (chunk-J43GMYXM.js?v=f3505250:11:50)
at dep:nexmo-client:1:16
However if I import it using via a script tag it works just fine.
// index.html
<script src="node_modules/nexmo-client/dist/nexmoClient.js"></script>
// app.tsx
const NexmoClient = window.NexmoClient;
OK, there are two problems here.
Firstly, NexmoClient tries to use global which is not available on the browser.
Secondly, NexmoClient has a dependency on socket.io-client, for some reason Vite imports a Node version of the socket.io-client that again tries to use modules that are not available on the browser, namely 'child_process'.
To fix both issues you can provide the following config to Vite, this should make sure the resulting build is compatible with the brother.
// vite.config.js or vite.config.ts
import { defineConfig } from 'vite'
import preact from '#preact/preset-vite'
export default defineConfig({
plugins: [preact()],
define: {
global: {},
},
resolve: {
alias: {
"xmlhttprequest-ssl": "./node_modules/engine.io-client/lib/xmlhttprequest.js"
}
}
})

Use index file to export .tsx modules

It's a common thing to create a index.js file in an React application with the only purpose to export several modules, in order to avoid having too many import statements on other components. This can be done by:
index.js
export { Credits } from './Credits.js';
export { SocialMedia } from './SocialMedia.js';
any module that might use those exports:
import * as var_name from index.js
And this is very nice. It wraps exports into a single file. However, when I changed my project to React with typescript, I found that .tsx files cannot be exported like that. The image below is the error I got after changing the project to typescript and the extensions became .tsx
Is there a way of 'bundle' export React .tsx files with the structure shown above? If not, what is the simplest way of centralizing .tsx files export?
My webpack.config.js:
module.exports = {
module: {
rules: [{
test: /\.scss$/,
use: ["sass-loader"]
}]
}
};
You can definitely use the same style of having an index file to group up exports for a whole folder. The simplest way around your problem would be to omit the file extension (assuming you only have one "index" file in the folder).
For example, let's say you have a component in 'common/Example.tsx':
import React from 'react'
export const Example = () => (<div>I'm an example component</div>)
You can then export it in an index file 'common/index.tsx':
export { Example } from './Example'
And import it from somewhere else, e.g. 'App.tsx':
import { Example } from './common'

Can't import vue2-google-maps component to main.js

After installing vue2-google-maps with npm, I'm trying to import the component to my main.js. But I keep getting an error. I never had problem importing packages to main.js or to other .vue files.
Versions:
vue 2.6.10
vue2-google-maps#0.10.7
vue-cli 2.9.6 but also tried with 3.11.0
import App from "./App.vue";
import store from "./store/store.js";
import * as VueGoogleMaps from "vue2-google-maps";
Vue.use(
VueGoogleMaps,
{
load: {
key: "AIzaSyBYULuuIqKYMJVrEk1PjpUDQQYkGMmP0iM",
libraries: 'places'
}
}
);
I'm getting the error in this line : import * as VueGoogleMaps from "vue2-google-maps";
Error Message: Could not find a declaration file for module 'vue2-google-maps'.
'c:/Users/BotiVegh/vueJS_projects/vue-store-gallery-map/node_modules/vue2-google-maps/dist/main.js'
implicitly has an 'any' type. Try npm install
#types/vue2-google-maps if it exists or add a new declaration (.d.ts)
file containing declare module 'vue2-google-maps';ts(7016)
Do I need to change something in the config file?
You could try adding "noImplicitAny": false to your tsconfig.json file
This disables warnings on expressions and declarations with an implied 'any' type

Build module to use it in environment without modules

Our application uses TypeScript's namespaces and do not use any kind of modules. We want to use react-datepicker, which is written using modules.
For example, it contains the next code:
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import onClickOutside from 'react-onclickoutside';
import moment from 'moment';
import { Manager, Popper, Target } from 'react-popper';
...
export default DatePicker;
Or transpiled:
var React = _interopDefault(require('react'));
var PropTypes = _interopDefault(require('prop-types'));
var classnames = _interopDefault(require('classnames'));
var onClickOutside = _interopDefault(require('react-onclickoutside'));
var moment = _interopDefault(require('moment'));
var reactPopper = require('react-popper');
...
exports['default'] = DatePicker;
It is required to build some js-bundle for this package, that will contain react-datepicker itself as global variable DatePicker, and all its dependecies, besides react, moment, classnames.
These libraries are already added to the application as global variables (React, moment, classNames), so it should use these global variables.
Is there some plugins and techniques for rollup, webpack, etc. that can help to build such bundle?
You can achieve this with rollup, you would need to use its external and globals option like this:
external: ['react', 'react-dom', 'moment', 'classnames'],
globals: {
'react': 'React',
'react-dom': 'ReactDOM',
'classnames': 'classNames',
'moment': 'moment'
},
Depending on the source file you're using, you might need to use these 2 plugins:
import commonjs from "rollup-plugin-commonjs";
import resolve from 'rollup-plugin-node-resolve';
Also, you might need to use rollup-plugin-replace because react-datepicker seems to include process.env.NODE_ENV in its code, and you will need to remove that.
In case you would like to see a full working example, check this repo I created:
https://github.com/mxcoder/rollup-iife-react-datepicker

How to shorten import path

I'm writing a React-Redux app now. And a question appeared in my mind. I often have to write such strings like:
import * as mainActions from '../../../main/actions/main-actions';
import {wysiwygComponent} from '../../../../components.jsx';
So I'm kind of sick of these "../../..". Is there any way to make components having global names or paths?
This is when module loaders come in handy.
If you use Webpack 2.x, you can modify the Path Resolver Configuration like this
resolve: {
modules: [
path.resolve('./client'),
path.resolve('./node_modules')
]
},
You specify a number of directories in modules which will turn
import Header from '../../components/Header';
import TransactionForm from '../TransactionForm';
into
import Header from 'components/Header';
import TransactionForm from 'TransactionForm';
Reference: No Relative Path

Categories