What Path is the Babel Plugin module-alias Actually Using? - babeljs

I'm trying to use Babel's "module-alias" plug-in with the "proxyquire" testing library, but I'm not having a lot of luck.
Library Backstory
(feel free to skip if you are familiar with both module-alias/proxyquire)
Proxyquire let's you mock out a module's dependencies for testing, like so:
const someFunctionToTest =
proxyquire(pathToSomeFunctionToTestsModule, {
pathToDependency: fakeVersionOfDependency
});
Babel's module-alias plugin let's you make your import paths more convenient and consistent. For instance, I can specify (in .babelrc):
"plugins": [
["module-alias", [
{ "src": "./", "expose": "~" }
]],
and then instead of having to type (when importing from a module nested three directories deep) require('../../../someModule') I can just typerequire('~/someModule')`.
The Problem
My problem is, they don't work together. If I havesomeModule that depends on someDependency:
// src/someModule.js
const someDependency = require('~/src/someDependency');
doSomethingWith(someDependency);
and then I want to test someModule with a mock version of someDependency, I should be able to do:
const proxiedSomeModule =
proxyquire('~/src/someModule', {
'~/src/someDependency': fakeVersionOfSomeDependency
});
... but proxyquire tells me `Error: Cannot find module '~/src/someModule'.
Presumably ("behind the scenes") Babel is converting '~/src/someModule' into its real path, so when Proxyquire looks for the aliased path it can't find it.
The Question
My question is: is there any way I can find out what the real path of '~/src/someModule' is, after Babel converts it (ie. when proxyquire deals with it)? Or alternatively is there any way to get proxyquire to just work with the aliased paths?

It turns out the "real" path (for '~/someModule') generated by module resolver is just the ../../someModule path. However, it also turns out that there is no need to convert paths by hand.
The module resolver plug-in will convert the arguments to any functions on its transformFunctions list. This means that you can convert any string to its non-aliased form by doing the following:
Define a simple passthrough function, e.g. const resolveModulePath = path => path;
Add that function (along with proxyquire) to the transformFunctions list in .babelrc:
["module-resolver", {
"transformFunctions": ["proxyquire", "resolveModulePath"]
}]
Wrap any paths which aren't arguments to a function with resolveModulePath:
proxyquire('~/some/path/someModule', {
[resolveModulePath('~/some/other/path')]: {
someFunction: fakeSomeFunction
}
})
Note that the first path in the above doesn't need to be escaped, as its an argument to a transformed function. Only the second path ('~/some/other/path') needs to be wrapped, because it's part of an object which is an argument; the string itself isn't an argument, until it's wrapped.
For further info see: https://github.com/tleunen/babel-plugin-module-resolver/issues/241#issuecomment-350109168

Related

Specifying window (global) variable type hinting in VSCode from external JS file without typescript

This may be a silly question but I really don't know where to look.
I'm creating a browser testing environment for a pretty large-scale API written in typescript. This API uses esbuild to build the typescript files into a /dist/ folder with a single index.js entry-point and its appropriate d.ts file.
I've created a /tests/ folder to hold some browser files that includes an index.html file with Mocha and Chai imported. It also imports /dist/index.js which is set globally to a window.myAPI variable.
In /tests/index.html:
import * as myAPI from "./dist/index.js"
Alongside index.html in the tests folder, there are separate JS files included for different tests that run things on window.myAPI... to do assertion tests.
search.test.js
book.test.js
navigate.test.js
I then run a server to host at the root. These separate tests are then imported from /tests/index.html. The separate tests look like this inside:
const { chai, mocha } = window;
const { assert } = chai;
describe("Search", function() {
describe("Setup", function() {
it("Setting URL should work", function() {
const call = myAPI.someCall()
assert.ok(call);
});
});
});
mocha.run();
Everything works, but I have no code hinting for myAPI. I'd like to be able to see what functions are available when I type myAPI, and what parameters they take, and what they should return - along with all my comments on each function.
In typescript you can do things like ambient declarations, but I don't want to make my tests typescript because then I add an unnecessary build step to the tests. But it would be as easy as:
/// <reference path = "/dist/index.d.ts" />
How can I tell VSCode that window.myAPI is an import of /dist/index.js and should import the types as well so I can see them ?
I'm open to different solutions to this, but I feel like this should be pretty simple. I don't know if ESLint is capable of doing something like this, but I tagged it because I feel it's relevant.
Thanks!

Flutter write script for to write code in project

I have a file inside my Flutter-project. A simple .dart file which looks like this:
class EnLanguage implements BaseLanguage {
#override
Map<String, String> get language => {'test': 'test'};
}
Now my goal is that I write I script which I by executing goes through all my Project-files, searches for specific Strings ( the ones with a .tr ending) and adds it to the map in the class above (key and value are the same).
I couldn't find any way to achieve this. How does a simple script looks like that can write inside my project files? Im not asking for the whole logic, I just need a start. I couldn't find anything..
Have a look at the package dcli and specifically the pack command. It does a chunk of what you need.
Not quite certain what you mean by strings ending with a .tr.
But to process each script.
var project = DartProject.self.pathToPackage;
find('*.dart', workingDirectory: project)
.forEach((script) {
read(script). forEach((line) {
If (line. contains('.tr'))
{
Extract line...
Write to generated file..
}

typescript can't resolve non-relative path in import

I have project structure like this
|--src
|--app.component
|--index.ts
|--home.component
|--index.ts
|--tsconfig.json
|--webpack.config.js
And I'm trying to do stuff below in app.component-index.ts
import { HomeComponent } from 'components/home.component'
Typescript couldn't find this module and throws
error TS2307: Cannot find module 'home.component'
Typescript docs say next:
A non-relative import to moduleB such as import { b } from "moduleB",
in a source file /root/src/folder/A.ts, would result in attempting the
following locations for locating "moduleB":
/root/src/folder/moduleB.ts
/root/src/moduleB.ts
/root/moduleB.ts
/moduleB.ts
So for my case I expect it would be like
/src/components/app.component/components/home.component
/src/components/components/home.component
/src/components/home.component
Thanks in advance.
P.S. In my webpack.config I've setted root.resolve to src and everything bundles correct. Typescript-loader prints errors to terminal but everything is bundled and works correctly
So I can guess at the "why" portion of this but I'm relatively new to TypeScript. I have gotten this to work though so I'll try explaining based on that solution as best I can.
What you expect based on the TypeScript Docs would be mostly correct if:
'components/home.component'
were treated as a 'Non-relative import'. I'm fairly certain (based on the solution that worked for me) that TypeScript treats it as an absolute path from the 'compilerOptions.baseUrl' field in your tsconfig.json.
What worked for me was to set it like so:
{
"compilerOptions": {
"baseUrl": ".",
// Other options
}
}
Which essentially tells TypeScript to try and find something like
'components/home.component'
by looking in the same directory as the tsconfig.json file for a directory called 'components' and then to look for a file/directory within it called 'home.component'.
So if your structure looks like:
|--src
|--app.component
|--index.ts
|--home.component
|--index.ts
|--tsconfig.json
|--webpack.config.js
And you set baseUrl to "." you would probably need to format your import like
import { HomeComponent } from 'src/home.component'

Check if a command exists using qmake

I am working on a project which incorporates C code, as well as (MASM-like) assembly. I want to be able to compile it on Linux, as well as Windows, thus I am using a third-party assembler (jwasm) as follows:
QMAKE_PRE_LINK += jwasm -coff -Fo$$assembly_obj $$PWD/assembly.asm
(here, assembly_obj holds the directory I want jwasm to save the output. Oh, by the way: when using jwasm it is critical to first specify all the parameters, and only at the end the input files, otherwise it will ignore the parameters)
To make it easier for other people to compile the project, I would like to be able to check if jwasm is in their path, and if not, emit an error() telling them how to fix this. However, I am not sure if this is even possible using qmake. I have tried:
exists("jwasm") { # Always false
message("jwasm found!")
}
as well as:
packagesExist(jwasm) { # Always true
message("jwasm found!")
}
I have looked around in the qmake docs, but couldn't find any other alternatives...

Eclipse OSGI config: relative paths and/or #config.dir-like substitutions?

In my RCP app, I would like to point a property (osgi.java.profile) to a file, and would prefer using paths relative to my installation and config dir.
Is there a definitive spec on what kind of variables are supported in config.ini?
#config.dir seems to be supported, there are references in the builtin, and it's always mentioned as typical example (e.g this SO answer )
However, looking at docs like Eclipse help/Runtime Options, it mentions a few "symbolic locations" like #user.home; however that seems fairly limited and doesn't include #config.dir.
Have even dug into org.eclipse.osgi sources as well, and found no references to this (I did find LocationManager and its hard coded variable substitutions for #user.dir & co).
Can I refer to arbitrary system properties there in some way?
Is this #config.dir a special case, only handled by P2? UPDATE: this seems to be the case.. looking at Eclipse SDK, About .. Configuration dialog shows #config.dir unresolved, probably taken literally by the Equinox..
Thanks for any hints.
I'm late to the party, but hopefully this will help others in the future.
Starting with Eclipse 3.8/4.2 (June 2012), you can substitute Java properties and environment variables into your config.ini file (Eclipse Bug 241192). The Equinox launcher does not support substitution in the eclipse.ini launcher file. The syntax uses dollar signs ($VARIABLE$) to indicate variable substitution:
osgi.configuration.area=$APPDATA$/MyCompany/MyProgram/configuration
osgi.user.area=$APPDATA$/MyCompany/MyProgram/user
osgi.instance.area=$APPDATA$/MyCompany/MyProgram/instance
I imagine you could use something like this for your purposes:
osgi.java.profile=$osgi.install.area$/path/to/profile.txt
You can use a platform URL (Platform URI scheme) to achieve this, i.e.
osgi.java.profile = platform:/config/java_profile.txt
in config.ini, would point to the file java_profile.txt in the current configuration directory.
You might also use existing system properties in config.ini:
osgi.java.profile = ${osgi.configuration.area}/java_profile.txt
From org.eclipse.core.runtime.adaptor.LocationManager, here are the special tokens:
// Data mode constants for user, configuration and data locations.
private static final String NONE = "#none"; //$NON-NLS-1$
private static final String NO_DEFAULT = "#noDefault"; //$NON-NLS-1$
private static final String USER_HOME = "#user.home"; //$NON-NLS-1$
private static final String USER_DIR = "#user.dir"; //$NON-NLS-1$
Why not use two system property variables?
One is named -Dmy.relativepath=filename, which is processed by your code of relative path of eclipse installation folder(workspace or anywhere), another is called -Dmy.path=absolutepath.
The system property is passed to the jvm, you need some tricky(translate the variable in runtime) in the native launcher(like eclipse.exe) if you wants to use variable in its value.
Look how osgi.java.profile is resolved in org.eclipse.osgi.framework.internal.core.Framework:
// check for the java profile property for a url
String propJavaProfile = FrameworkProperties.getProperty(Constants.OSGI_JAVA_PROFILE);
if (propJavaProfile != null)
try {
// we assume a URL
url = new URL(propJavaProfile);
} catch (MalformedURLException e1) {
// try using a relative path in the system bundle
url = findInSystemBundle(propJavaProfile);
}
That means osgi.java.profile must point either to a fully qualified URL, or to a relative path in system bundle (org.eclipse.osgi). This makes impossible usage of installation directory relative path without patching Eclipse.