My .cTags is working fine in mostly cases. However in a scenario mentioned below it's not working as expected.
Directory Structure
root
- a
- foo.js
- bar.js
- index.js
- b
- current-file.js
current-file.js
import { foo } from './a'
foo()
index.js
export { default as foo } from './foo'
foo.js
const foo = () => 'foo'
export default foo
When i am trying to jump in definition of foo from current-file.js its navigating to a/index.js instead of a/foo.js
I think this is not a limitation about the cTags, but about the ES6 language itself.
The curly braces import will first lookup for the file named a, if not found, it will look for the directory named 'a' with its index.js file (auto-resolved, e.g: a/index.js). It won't look for a file into a directory.
The curly braces are only looking for the non-default exports from a file, and it's not looking through directories.
Example (NOTE: the directory a has been renamed to c as codesandbox reserved the name a in his engine)
You can try to remove the /c.js file to load the c/index.js file instead.
Also, I suggest you this thread which can give you more tips on curly brackets in js
You might be able to do a read through a directory with the fs.readDir api and automatically require/export the files in your index.js; But the index.js will be loaded.
Related
Every time I try to import into my nodejs file I get the error, cannot import outside a module
I have tried multiple solutions on StackOverFlow such as adding
"type":"module"
and setting file extensions to .mjs
I want to import constants from a different file but I am not sure how to
example
functions.js
export const myFunc = (param1) => return 'hello'
backend.js
import {myFun} from './.js'
How should I import them?
Sorry I accessed a similar question for constants but the same method does not work for functions
First, "type": "module" needs to be in the package.json or both JS files need to end in .mjs. You seem to be aware of this, but just making sure as the filenames you have provided don't end in .mjs, and you haven't provided your package.json.
When using arrow functions, the return is implied. If you try to use return in an arrow function, an error will occur. Also, in backend.js, you are importing myFun, which is not in functions.js. I believe you meant to import myFunc.
functions.mjs
export const myFunc = (param1) => "hello"
backend.mjs
import { myFunc } from './functions.mjs'
console.log(myFunc("test"))
The code environment is browser. bundle tool is webpack. I have a router.js file like:
import foo from './views/foo.vue'
import bar from './views/bar.vue'
import zoo from './views/zoo.vue'
//use foo, bar, zoo variables
I've many '.vue' files to import like this under views folder. Is there a programmatical way to auto import all [name].vue as local variable [name]? So when I add or remove a vue file in views, I don't need to manually edit router.js file. this one seems a little dirty.
for (let name of ['foo', 'bar', 'zoo']) {
global[name] = require(`./views/${name}.vue`)
}
Nope, that's it. You have a choice between dynamic import and automation, or explicit coding and type-checking / linting.
Unfortunately, it's one or the other. The only other way to do it is meta-programming, where you write code to write your code.
So you generate the import statements in a loop like that, and write the string into the source file, and use delimiting comment blocks in the source file to identify and update it.
The following works for me with webpack and vue.
I actually use it for vuex and namespaces. Hope it helps you as well.
// imports all .vue files from the views folder (first parameter is the path to your views)
const requireModule = require.context('./views', false, /\.vue$/);
// create empty modules object
const modules = {};
// travers through your imports
requireModule.keys().forEach(item => {
// replace extension with nothing
const moduleName = item.replace(/(\.\/|\.vue)/g, '');
// add item to modules object
modules[moduleName] = requireModule(item).default;
});
//export modules object
export default modules;
I'm trying to rewrite bunch of legacy JS files into module structure. I have obfuscated plugin which contains out of few files, which in turn work with single global variable. The order of execution of these files matters.
Example:
file1.js
var myModule = {someStuff};
file2.js
myModule.someProperty = someValue;
What i want to achieve is to import them all somehow and get this global variable myModule.
Possible implementation:
myModule.js
import myModule from "file1.js";
import myModule from "file2.js"; // ofc i know it does not work this way
export default class myProgramm {
constructor(){
myModule.run({options});
}
}
What i tried so far is webpack provide plugin (https://webpack.js.org/plugins/provide-plugin/), but it doesn't work with multiple files. Also i tried to use provide-multiple-plugin (adopted to webpack 4) from this gist :https://gist.github.com/shellscape/a7461022503f019598be93a512a1901a. But it seems to include files in nearly random order, so it can happen that myModule is not defined, while file2.js is executed first.
For example, if I have the following in my app,
import Node from 'infamous/motor/Node'
console.log(Node)
that works just fine. But the moment I actually do something with it,
import Node from 'infamous/motor/Node'
console.log(new Node)
then TypeScript will complain because there's no type definition for Node. How do I define the type of Node?
The library has no type declarations of it's own. I tried something like
import MotorNode from 'infamous/motor/Node'
declare class MotorNode {}
console.log(' --- ', new MotorNode)
but I get the error
./src/app.tsx(6,8): error TS2440: Import declaration conflicts with local declaration of 'MotorNode'
When I need to do what you are trying to do, I create an externals.d.ts file in which I put module augmentations for my project and make sure that my tsconfig.json includes it in the compilation.
In your case the augmentation might look something like this:
declare module "infamous/motor/Node" {
class Node {
// Whatever you need here...
}
export default Node;
}
I put it in a separate file because a module augmentation like this has to be global (must be outside any module), and a file that contains a a top-level import or export is a module. (See this comment from a TypeScript contributor.)
I can't seem to get any import to work when the module isn't defined as a string. What is going on?
test.ts
import b = module('Backbone')
Does not work:
backbone.d.ts
declare module Backbone {
export class Events {
...
Works:
backbone.d.ts
declare module "Backbone" {
export class Events {
...
Edit 1:
FYI From 10.1.4
An AmbientModuleIdentification with a StringLiteral declares an external module. This type of declaration is permitted only in the global module. The StringLiteral must specify a top-level external module name. Relative external module names are not permitted
I don't understand how it's useful to not specify it as the string literal format as found here and here. It works if you use ///<reference... without a string literal module but I'm trying to generate AMD modules that depend on these libraries so I need the import to work. Am I the minority and I have to go and modify each .d.ts to be the string literal version?
Edit 2:
Declaring a module using a string literal requires that your import is an exact match if that string literal. You can no longer use relative or absolute paths to the location of this module/module definition even if it is not located in the same directory as the file trying to import it. This makes it that a ///<reference and an import are required but produces a module with tsc --module AMD that was exactly looking for (path to module is as dictated by the module string literal "Backbone").
For example.
+- dep/
|- backbone.d.ts
|- test.ts
backbone.d.ts:
declare module "Backbone" {
export class Events {
Works: test.ts:
///<reference path="../dep/backbone.d.ts" />
import b = module('Backbone')
// generates
// define(["require", "exports", 'Backbone']
Does not work: test.ts:
import b = module('./dep/Backbone')
Note that this works as well...
declare module "libs/Backbone" {
...
///<reference path="dep/backbone.d.ts" />
import b = module('libs/Backbone')
...
// generates
define(["require", "exports", 'libs/Backbone']
When you write this:
declare module Backbone {
It means you have already a module which is in the global scope (so you can immeadiately use it, no import is required). But when you write this:
declare module "Backbone" {
It means you specify how the imported module (import ... = module("...")) will look.