Navigating through Typescript references in Webstorm using ES6 module syntax - intellij-idea

We are using Typescript with Intellij Webstorm IDE.
The situation is we use ES6 import syntax and tsc compiler 1.5.3 (set as custom compiler in Webstorm also with flag --module commonjs)
The problem is it is imposible to click through (navigate to) method from module (file)
// app.ts
import * as myModule from 'myModule';
myModule.myFunction();
// myModule.ts
export function myFunction() {
// implementation
}
When I click on .myFunction() in app.ts I expect to navigate to myModule.ts file but this doesn't happen?
EDIT:
The way we exported functionality was bit different as in first example:
export: {
myFunction1,
myFunction2,
// ...
};

When I click on .myFunction() in app.ts I expect to navigate to myModule.ts file but this doesn't happen
This is working fine in the current WebStorm release.

I found out the problem, my example in question was simplified too much. In real code we are using:
export: {
myFunction1,
myFunction2
// ...
};
and this really doesn't work.
I have to change it to:
export function myFunction1() { /* impl */ }
export function myFunction2() { /* impl */ }
then it works.

Related

How to import node-java and use it correctly?

Now I am trying to call our APIs in our own Jar.
In VS Code extension example project, I tried to npm install java to install it in modules dir.
In my extension.ts it looks like below:
import * as vscode from "vscode";
import * as java from "java";
// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {
// Use the console to output diagnostic information (console.log) and errors (console.error)
// This line of code will only be executed once when your extension is activated
console.log(
'Congratulations, your extension "test-ext" is now active!'
);
context.subscriptions.push(
vscode.commands.registerCommand("test-ext.callLocalJar", async () => {
console.log('test caller start.');
java.classpath.push("testapis.jar");
console.log('test caller start.');
}
)
);
}
// this method is called when your extension is deactivated
export function deactivate() {}
But now I got a failure in the very beginning when activating it...
error:
Activating extension 'boyka.test-ext' failed:
Cannot find module 'c:\Users\boyka\Workspaces\test-ext\build\Release\nodejavabridge_bindings.node'.
My package.json is like
"dependencies": {
"java": "^0.12.2"
}
I am not sure of the root cause, tried to research and add Java home to PATH but luck.
Anyone has this node-java usage experience that could help? Will appreciate that!
https://github.com/joeferner/node-java
Thanks
b.

Nuxt avoid import of client-side script for server-side rendering

In my nuxt.js application, I have a script that imports an NPM package which is only compatible with browser contexts (it references document, location, window, etc.)
Is there a way to exclude this from SSR?
import thing from "#vendor/thing"; // causes `document not defined` error
export default showThing(){
if (process.client) {
thing();
}
}
I can use the method with process.client but this file is still imported in my components.
You could import it dynamically rather than in every context.
As explained in my answer here: https://stackoverflow.com/a/67825061/8816585
In your example, that would be something like this
export default showThing(){
if (process.client) {
const thing = await import('#vendor/thing')
thing()
}
}

Is there a bundler/tool that does not bundle by default, just do specified transforms like compiling SCSS modules?

I want to create a UI library and publish it to NPM. I don't like however the idea of bundling the code into single file and adding bundler code around my code, which is what all bundlers do by default (well, bundler must bundle I guess).
I'm using TypeScript and I build my non-ui packages with tsc. I want to keep that and let bundler or other tool just run through the result and change few things.
For example let's take this file:
import React from "react";
import styles from "./b.module.scss";
const B = () => {
return (
<div className={styles.index}>index</div>
);
};
export { B };
It's getting compiled into this ESM code:
import React from "react";
import styles from "./b.module.scss";
const B = () => {
return (React.createElement("div", { className: styles.index }, "index"));
};
export { B };
//# sourceMappingURL=b.js.map
Not much changes, but this is what I want at this step.
Now I want the tool to:
see the module.scss import
build b.css file, replacing class names with mangled ones
replace import styles from "./b.module.scss"; with import "./b.css";
replace { className: styles.index } with something like: { className: "b_index_f9cb22" } (that reflect new class name in b.css)
and that's basically all
I guess those are the steps normally taken by webpack plugins, but webpack does more than that, like I said - adding its own code, bundling things together, minimizing the code, etc. Some of these things I seem to be able to skip, but still the output is far from my original one.
Is there a tool that allows me to do what I want?

“window is not defined” in Nuxt.js

I get an error porting from Vue.js to Nuxt.js.
I am trying to use vue-session in node_modules. It compiles successfully, but in the browser I see the error:
ReferenceError window is not defined
node_modules\vue-session\index.js:
VueSession.install = function(Vue, options) {
if (options && 'persist' in options && options.persist) STORAGE = window.localStorage;
else STORAGE = window.sessionStorage;
Vue.prototype.$session = {
flash: {
parent: function() {
return Vue.prototype.$session;
},
so, I followed this documentation:
rewardadd.vue:
import VueSession from 'vue-session';
Vue.use(VueSession);
if (process.client) {
require('vue-session');
}
nuxt.config.js:
build: {
vendor: ['vue-session'],
But I still cannot solve this problem.
UPDATED AUGUST 2021
The Window is not defined error results from nodejs server side scripts not recognising the window object which is native to browsers only.
As of nuxt v2.4 you don't need to add the process.client or process.browser object.
Typically your nuxt plugin directory is structured as below:
~/plugins/myplugin.js
import Vue from 'vue';
// your imported custom plugin or in this scenario the 'vue-session' plugin
import VueSession from 'vue-session';
Vue.use(VueSession);
And then in your nuxt.config.js you can now add plugins to your project using the two methods below:
METHOD 1:
Add the mode property with the value 'client' to your plugin
plugins: [
{ src: '~/plugins/myplugin.js', mode: 'client' }
]
METHOD 2: (Simpler in my opinion)
Rename your plugin with the extension .client.js and then add it to your plugins in the nuxt.config.js plugins. Nuxt 2.4.x will recognize the plugin extension as to be rendered on the server side .server.js or the client side .client.js depending on the extension used.
NOTE: Adding the file without either the .client.js or .server.js extensions will render the plugin on both the client side and the server side. Read more here.
plugins: ['~/plugins/myplugin.client.js']
There is no window object on the server side rendering side. But the quick fix is to check process.browser.
created(){
if (process.browser){
console.log(window.innerWidth, window.innerHeight);
}
}
This is a little bit sloppy but it works. Here's a good writeup about how to use plugins to do it better.
Its all covered in nuxt docs and in faq. First you need to make it a plugin. Second you need to make your plugin client side only
plugins: [
{ src: '~/plugins/vue-notifications', mode: 'client' }
]
Also vendor is not used in nuxt 2.x and your process.client not needed if its in plugin with ssr false
In Nuxt 3 you use process.client like so:
if (process.client) {
alert(window);
}
If you've tried most of the answers here and it isn't working for you, check this out, I also had the same problem when using Paystack, a payment package. I will use the OP's instances
Create a plugin with .client.js as extension so that it can be rendered on client side only. So in plugins folder,
create a file 'vue-session.client.js' which is the plugin and put in the code below
import Vue from 'vue'
import VueSession from 'vue-session'
//depending on what you need it for
Vue.use(VueSession)
// I needed mine as a component so I did something like this
Vue.component('vue-session', VueSession)
so in nuxt.config.js, Register the plugin depending on your plugin path
plugins:[
...
{ src: '~/plugins/vue-session.client.js'},
...
]
In index.vue or whatever page you want to use the package... import the package on mounted so it is available when the client page mounts...
export default {
...
mounted() {
if (process.client) {
const VueSession = () => import('vue-session')
}
}
...
}
You can check if you're running with client side or with the browser. window is not defined from the SSR
const isClientSide: boolean = typeof window !== 'undefined'
Lazy loading worked for me. Lazy loading a component in Vue is as easy as importing the component using dynamic import wrapped in a function. We can lazy load the StepProgress component as follows:
export default {
components: {
StepProgress: () => import('vue-step-progress')
}
};
On top of all the answers here, you can also face some other packages that are not compatible with SSR out of the box and that will require some hacks to work properly. Here is my answer in details.
The TLDR is that you'll sometimes need to:
use process.client
use the <client-only> tag
use a dynamic import if needed later on, like const Ace = await import('ace-builds/src-noconflict/ace')
load a component conditionally components: { [process.client && 'VueEditor']: () => import('vue2-editor') }
For me it was the case of using apex-charts in Nuxt, so I had to add ssr: false to nuxt.config.js.

Aurelia Webpack loader unable to find a module I add as a feature

I have a small Aurelia app built with Webpack. Under my src folder I have util folder with index.ts inside. In main.ts I turn the feature on like this:
import { Aurelia, PLATFORM } from "aurelia-framework";
export function configure(aurelia: Aurelia) {
aurelia.use
.standardConfiguration()
.developmentLogging()
.feature(PLATFORM.moduleName("util"));
aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName("app")));
}
util/index.ts:
import { FrameworkConfiguration } from 'aurelia-framework';
export function configure(config: FrameworkConfiguration): void {
config.globalResources([
"./converters",
"./rest"
]);
}
converters and rest are Typescript modules under util.
I'm following the instructions from Aurelia Hub.
When I open the app in the browser I see the following error:
Uncaught (in promise) Error: Unable to find module with ID: util/index
at WebpackLoader.<anonymous> (aurelia-loader-webpack.js:187)
at step (aurelia-loader-webpack.js:36)
at Object.next (aurelia-loader-webpack.js:17)
at aurelia-loader-webpack.js:11
at Promise (<anonymous>)
at webpackJsonp.64.__awaiter (aurelia-loader-webpack.js:7)
at WebpackLoader.webpackJsonp.64.WebpackLoader._import (aurelia-loader-webpack.js:152)
at WebpackLoader.<anonymous> (aurelia-loader-webpack.js:252)
at step (aurelia-loader-webpack.js:36)
at Object.next (aurelia-loader-webpack.js:17)
If I reference the modules directly instead of the feature e.g.
import { Rest } from '../util/rest';
Then I get no errors and the app loads successfully. But I want to have these modules globally available.
Using aurelia-webpack-plugin version 2.0.0-rc.2
Would appreciate your advice.
Take a look at this:
https://github.com/aurelia/templating-resources/blob/master/src/aurelia-templating-resources.js
Edit:
I have gotten it working. The key is that you need to explicitly call PLATFORM.moduleName('./relative/path/to/file') on each path specifically and that the call needs to be made from the file (actually technically the same directory but still...) that calls config.globalResources().
In other words you can't shortcut the following code:
config.globalResources(
PLATFORM.moduleName('./resource1'),
PLATFORM.moduleName('./resource2')
);
Don't try to map the resources to PLATFORM.moduleName or to dynamically construct file names.
You should change your path PLATFORM.moduleName("util") into PLATFORM.moduleName("./util"). Then you can be able to use path relative to your util folder to register your globalResources. Also you can look into here for sample project structure. Also see this line of code, aurelia added /index to moduleName if it not included as it was based on convention.
If you already try using aurelia CLI, the created project under src/resources is registered as a feature.