Is there a clean way of importing modules? - javascript

I am currently working on a project where I have to import a file to my index.js file.
Here's a snippet:
import './inspector'
import { openSidebar, collapse } from './inspector'
I would like to import everything from the inspector.js in order to run more logic inside that file and at the same time importing openSidebar and collapse function inside it. But I noticed that I'm getting an eslint error no-duplicate-imports in my editor.
How to resolve this issue? I'm still learning on how importing in javascript fully works. I was thinking that maybe removing one of the imports will still work. Thank you in advance.

All of a module's code will run whenever the module is imported, no matter what gets imported - even if nothing is imported. Given the following module:
// inspector.js
console.log('running inspector');
export const openSidebar = () => console.log('opening sidebar');
export const collapse = () => console.log('collapsing');
The following code would successfully log running inspector (in addition to whatever other code existed on the top level of that module):
import './inspector';
The following line would also log it:
import { openSidebar, collapse } from './inspector';
So you should be able to use just that version above, which will run the top level code and import the required values from the module.

Related

Referencing vanilla js file in TypeScript getting file is not a module

I'm trying to import a file into TypeScript that's basically just a js file that you'd put into a tag. I've tried a few different things.
// global.d.ts
declare module 'myfile.js'
Inside of the react file:
// component.tsx
import { foo } from '../lib/myFile.js' // This is saying it is not a module
Inside of the js file, it looks like this a few times so not sure how I need to reference the file:
(function( something ) {
something.Foo = function (){}
}(window.something = window.something || {}));
Any thoughts on how I could use this file? Do I need to go through and declare typings for everything in it?
EDIT: I've added allowJS to my tsconfig but it still doesn't work.
You can only import what is exported from the file.
If your file contains only immediately invoked functions, or top level code, you only need to import the file itself like this:
import '../lib/myFile.js'
This is a little weird, however. I would suggest wrapping everything with a function and exporting then importing that function instead.

Unable to import an API module into a nested component (Vue)

I've been struggling with a very odd bug(?) with regards to importing an API module into a nested component in a Vue app.
This is the simplest I could reduce the issue down to.
https://codesandbox.io/s/rough-tree-fqj7o
Essentially, the DogsCreate component renders the CreateDogsModal, which is importing the dogs module from the API directory.
As you can see, the codesandbox errors out even on the base URL with the error Cannot read property 'default' of undefined. If running this code locally not on codesandbox, the base URL renders ok, but if you go to /dogs/create, the error then becomes Failed to resolve component: CreateDogsModal.
The things I've found that fix this are:
Commenting out the API import statement in CreateDogsModal (not an option for us, we need to be able to create and import API modules)
Commenting out the TopNav component in main.js (...also not an option for us)
Importing the TopNav component in App.vue with a relative import or #/components/TopNav.vue works fine, but strangely importing CreateDogsModal and CreateTemplate in DogsCreate.vue with a relative import or #/components/[component-name].vue does not. Also, the latter would be somewhat acceptable as a long-term solution, but I'd prefer the #/components shorthand and that still leaves the root cause undetermined.
I'm using the default vue-cli webpack configuration and have checked via vue inspect that the alias seems to be set properly.
I've been spinning my wheels for a week trying to figure this out and just...cannot. Does anyone have any ideas for what may be happening?
It seems like a race condition in Webpack, using parallel builds, but I'm honestly not sure. I can see CreateDogsModal being pulled in from two places, starting from main.js:
'main.js'
- import 'App.vue'
- import '#/components/index.js'
- import and export 'CreateDogsModal.vue'
- import 'router/index.js'
- import '#/views/Dogs/DogsCreate.vue'
- import '#/components/index.js'
- import and export 'CreateDogsModal.vue'
One workaround is to remove the race by making the CreateDogsModal an async component in DogsCreate:
// DogsCreate.vue
import { defineAsyncComponent } from "vue";
import { CreateTemplate } from "#/components";
export default {
name: "DogsCreate",
components: {
CreateTemplate,
CreateDogsModal: defineAsyncComponent(() => import("#/components/CreateDogsModal.vue")),
},
};
demo

prismjs not working between different routes using vuerouter in vuejs

I've imported prism.js globally in main.js file.
Code block syntax highlighting working fine in Home components, but after routing to another page using vue-router, there is no effect.
in main.js
// Global Import
import 'prismjs/prism.js'
import 'prismjs/components/prism-swift.min.js' // swift lang
import './theme/prism-swift-theme.css'
in my about page component...
<pre><code class="language-swift">
private func setupSubviews() {
let value = "Loading code block";
}
</code></pre>
Unable to understand what's wrong here. Is there any way I can import node_modules prismjs files globally? I thought keeping main.js will work fine, but it's not adding globally between routes...
Once you install it with npm the best approach is to import it whenever it is used in each component seperately with import Prism from 'prismjs'. Just make sure to use the Prism.highlightAll() method in the component where you're using prism after the DOM is rendered whether in mount() hook or in the updated Vuejs hook using nextTick method to make sure all the DOM is rendered before using prism. So in your case you should use it this way:
import Prism from "prismjs"
updated: function () {
this.$nextTick(function () {
Prism.highlightAll();
})
}
make sure you call highlightAll in yor components seperately and not globaly.

How do I call a function in an external js file using typescrpt

We are trying a POC of adding Typescript and Webpack to our Angularjs project.
I am able to get my webpack bundle to generate, however at runtime the program cannot find the various functions in my validator.js. Can you please offer some advice?
login-view.components.ts
declare var findFormNode: any; //function in validator.js
//LogInUser
self.login = function ($event, command) {
if (findFormNode($event.target.id)) {
...
}
}
main.ts is importing the file
import "./../../../CommonStaticFiles/include/js/Validators.js";
bundle.js
eval("/* WEBPACK VAR INJECTION */(function($) {/*\r\n\r\n VALIDATORS\r\n\r\n ... n\n\nfunction findFormNode(
error
ReferenceError: findFormNode is not defined
at LoginController.self.login (login-view.component.ts:28)
at fn (eval at compile (angular.js:NaN), <anonymous>:4:267)
at callback (angular.js:29019)
In order for your functions to be properly imported, there are few things that you have to make sure of.
First, make sure you are exporting your functions correctly. Here's an example of how to export a function from Validator.js:
export const validateFunc1 = ():void => {};
Next, you have to make sure you are using proper import syntax. In order to import the function above, you would do the following:
import {validateFunc1} from "./../../../CommonStaticFiles/include/js/Validators.js";
Alternatively, if you want to import all exported functions at once, then you can use this syntax:
import * as validatorFuncs from "./../../../CommonStaticFiles/include/js/Validators.js";
Lastly, check that the location of Validators.js is correct. It's a common mistake to be looking in the wrong directory. Your code editor can usually help you find the right path to use.

how use npm packages with Vue SPA

i have created Vuejs app using vue-loader,now i need to use an installed npm package as follow :
var x = require('package-name')
Vue.use(x)
but i have this error :
Uncaught TypeError: plugin.apply is not a function
dose Vuejs require a special type packages or it can work with any JavaScript package and this error can be solved
There are many approaches.
I am adding with respect #smiller comment and thanks for sharing the link . I am adding information here in case the link someday not work .
Credit to this link :- https://vuejsdevelopers.com/2017/04/22/vue-js-libraries-plugins/
First approach of-course #crig_h
window.x = require('package-name')
There are certain drawback . don’t work with server rendering . Otherwise everything will work fine in browser as window is global to browser , any properties attract to it will be accessible to whole app.
The second approach is .
Use Import with the js portion in the .vue file , Like this.
if inside the '.vue' file.
<script>
import _ from 'lodash';
export default {
created() {
console.log(_.isEmpty() ? 'Lodash is available here!' : 'Uh oh..');
}
}
</script>
If you have seperate file for .js then same like this there will we no <script> tag.
And Third method
where ever in the project you import vue. You can write this statement
import Vue from "vue";
import moment from 'moment';
Object.definePrototype(Vue.prototype, '$moment', { value: moment });
This will set the relevant properties to to Vue . And you can use it any where like this . As Vue is global scope of app.
export default {
created() {
console.log('The time is ' . this.$moment().format("HH:mm"));
}
}
ADDED FOR CSS
you can do import in src/main.js file in vue.js project .
import './animate.css'
Also if you like to import in template .
Inside the template you can do this.
<style src="./animate.css"></style>
Also have a look on css-loader package . what it does ?
Plugins are specific Vue packages that add global-level functionality to Vue, so if you aren't using a Vue plugin then you don't need to register it with Vue using Vue.use().
In general there isn't any issue using non-vue-specific packages via npm but if you need to register something globally, you can usually get away with simply attaching it to window like so:
window.x = require('package-name');
Unfortunately none of these answers worked for me what i ended up doing is
export default {
computed() {
x () {
return require('package-name')
}
}
}
And then use it as x.functionName() or whatever
There is better solution ... First import your package in main.js
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
import Vue from "vue";
import App from "./App.vue";
import "package-name";
After that's you code inside mounted method as javascript
<script>
export default {
mounted() {
const any = require("package-name");
// your code as normal js
},
};
</script>

Categories