Find ES6-module in which entity is declared - javascript

TL;DR There is some imported entity on ES6-module. Should find original ES module and line number, where this entity has been initially declared - not re-imported / re-exported.
There is some hierarchy of nested imported ES6-modules, some of which are not controlled by library code and had been imported from well-known place - it's some user-side configuration file.
Imagine following files structure:
config.js (not controlled)
import nested from './nested';
export default {
param1: { aaa: 10, bbb: 20 },
param2: nested
}
nested.js (not controlled)
export default {
ccc: 30,
ddd: 40
}
index.js (controlled)
import config from './config'
const ddd = config.ddd;
if(notValid(ddd)) {
const decl = %FIND_DECLARATION%(ddd);
console.log('Config variable "config.ddd" is not valid');
console.log('You declared it here: ', decl);
}
Output should be like following
You declared it here:
File webpack://./nested.js , line 2
ddd: 40
^^^^^^^
Should write function %FIND_DECLARATION%, which can find original ES-module and line number for some object declaration, and retrieve it's source code
Environment is webpack. Any dirty hacks are welcome if can't be solve without it.

Related

How to import a variable from a JavaScript file and use it in TypeScript?

I'm trying to make a userscript in TypeScript using Webpack and Hogan.js pre-compiled templates.
For it to work, I need to import a compiled file, carousel_inner.js. This file is auto-generated, so no modifications to it are allowed.
if (!!!templates) var templates = {};
templates["carousel_inner"] = new Hogan.Template({code: function (c,p,i) { var t=this;t.b(i=i||"");t.b("<a class=\"carousel-");t.b(t.v(t.f("class",c,p,0)));t.b("\" href=\"\" style=\"background-image: url(");t.b(t.v(t.f("background-image",c,p,0)));t.b(")\">\r");t.b("\n" + i);t.b(" <div>\r");t.b("\n" + i);t.b(" <h4>");t.b(t.v(t.f("h4",c,p,0)));t.b("</h4>\r");t.b("\n" + i);t.b(" <h5>");t.b(t.v(t.f("h5",c,p,0)));t.b("</h5>\r");t.b("\n" + i);t.b(" <p>");t.b(t.v(t.f("p",c,p,0)));t.b("</p>\r");t.b("\n" + i);t.b(" </div>\r");t.b("\n" + i);t.b("</a>");return t.fl(); },partials: {}, subs: { }});
I'm trying different strategies to import the templates variable and export it for usage elsewhere, but I always end up with a "templates is not defined" error.
Here's a failed attempt.
// index.ts
import "./js/carousel_inner";
export default templates;
// main.ts
import templates from "./templates";
console.log(`templates: ${templates}`);
The project is here.
Make a declaration type file.
carousel_inner.d.ts (.d.ts IS REQUIRED)
declare module "carousel_inner.js" {
interface types {
[index:string]:unknown;
}
/* OR */
type types = unknown;
/* OR */
const types:unknown;
export default types;
}
It will give types to a file that is being imported.
I use the following for importing sql files occasionally.
declare module "*.sql" {
const content: string;
export default content;
}
Just use the type you want instead of unknown.

require or import in forEach loop

I have the following object:
const basePoints = {}
which I need to fill with json files. Currently I do:
import WH11 from 'assets/WH11';
const basePoints = { WH11}
I have like a dozen of such Json files but only 2-3 can be used at a given time. INstead of importing and loading all the JSON files i don't need, I want to require/import based on a config file as shown below:
and my config.js:
const config = {
basePoints: {
"WH11": "West Gate",
"WH12": "West Gate Back Drop"
}
}
WH11, WH12 etc basically exist in json format in my assets directory:
assets/basepoints/WH11.json
{
"startingID" : 198
}
etc. Now there can a dozen or more of such json files. The user just adds the ones to be used for the month in config.js.
Is there a way to require/import the json file based on the config file. The app can't compile if I do:
Object.keys(config.basePoints).forEach(key => {
basePoints[key] = require('../assets/basepoints/' + key + '.json');
});
the error is unexpected require().
You can use the latest ES2020 feature - Dynamic Import
Syntax -
import('/modules/<module_name>')
.then(module => {
//
})
.catch(err => {
//
});
You can learn more about it in this MDN document (scroll down to the dynamic import section) -
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import

How To import sanitize.js to react apps Function / class not found

I've some problem, in my project I need to add Sanitize.js on my project, I've copied to my own 3rd party folder ex vendor
to import it I'm using
import {san} from '../../vendor/Sanitize' //There's No error when compiling this one
but there's an error when I run the page, I'm trying to call the function from Sanitize.js as in readme saying to use it just do like this
var s = new san.Sanitize({
elements: ['a', 'span'],
attributes: {
a: ['href', 'title'],
span: ['class']
},
protocols: {
a: { href: ['http', 'https', 'mailto'] }
}
});
s.clean_node(p);
The Error is
san.Sanitize is not a function/ class constructor
Any idea why this is happening? or did I miss something? There's no Error in compiling process, the error only occurs when I try to run the web page,
Because Sanitize.js is not a module.
Maybe you can try the following solution:
Add export default Sanitize; in end of sanitize.js.
Use import Sanitize from "./sanitize"; to import it.
Remove the following code from sanitize.js.
if ( typeof define === "function" ) {
define( "sanitize", [], function () { return Sanitize; } );
}

Javascript Unable to validate computed reference to imported namespace

Not sure if I need to add another jshint library or if I should do this a different way.
I have a file (for explanations reasons we'll call it stuff-functions.js) that exports functions like this...
export function a() {
return 'stuff';
}
export function b() {
return 'more stuff';
}
export function c() {
return 'even more stuff';
}
In another file I'm importing that file and calling that function by an argument...
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}
It works fine, but in the console I'm getting an eslint error...
Unable to validate computed reference to imported namespace 'stuffFunctions'
So, should I go about this differently or hunt down some sort of eslint library that allows for this?
EDIT...
I've added this line to stop the error // eslint-disable-line
I was just curious if there was a better way to do this. Maybe something like...
import {a, b, c} from './stuff-functions';
export default class someReactClass {
myFunc(functionToCall) {
const myStuffFunctions = {
a: a,
b: b,
c: c
};
return myStuffFunctions[functionToCall]();
}
...
}
Seems redundant though. :/
The error is being reported by the import/namespace rule in the eslint-plugin-import plugin. It's occurring because you are deciding which imported function will be called at runtime:
stuffFunctions[functionToCall]();
The plugin's static analysis cannot verify that this is a valid import and it reports it as an error.
The simplest solution would be to add an ESLint comment to reconfigure the rule to allow computed references:
/*eslint import/namespace: ['error', { allowComputed: true }]*/
import * as stuffFunctions from './stuff-functions'
export default class someReactClass {
myFunc(functionToCall) {
return stuffFunctions[functionToCall]();
}
...
}

Importing data object from file-to-file

I have a .JSON (named dataOut.json) file that looks similar to the following:
[
{
"scan_type": "nexpose",
"date_time": "2011-07-18 11:11:11",
"source_address": "1108",
"source_lat": "40.581160",
"source_lng": "-105.184110",
"dest_address": "11.166.181.0",
"dest_lat": "30.003880",
"dest_lng": "-604.800360"
},
...
]
I have a script that seperates the source/destination data points, and places the output in separate files, here is my code for doing so.
So here is my problem, I need to export the object variable "scan_type" from the code above, to another .JS file, named jsontonbh.js .
I tried using module exports:
//exporting 'scan_type'
obj.forEach(block => {
...
module.exports = {scan_type:block.scan_type};
...
});
and then importing it in my jsontobh.js file by requiring it, as shown here:
let sourceFile = require('./jsonParents.js');
obj.forEach(block => {
console.log(sourceFile.scan_type)
});
this code returns the error "Unexpected end of JSON input"
How can I export this variable scan_type from my first script, to my second script?

Categories