How to map module name twice in Jest? - jestjs

I am using Jest to test a SvelteKit application. I have a plugin that allow me to import .svg file as a Svelte component. I also have a module name mapper for $lib import.
I map .svg module to an empty Svelte component. It works unless I use $lib prefix to import .svg file.
import Icon from '../lib/icons/icon.svg' // Works
import Icon from '$lib/icons/icon.svg' // Does not work
Jest only map module name once. So $lib/icons/icon.svg never gets mapped to an empty Svelte component.
moduleNameMapper: {
// ?url import
'^.+\\.svg\\?url$': 'jest-transform-stub',
'^\\$lib(.*)$': '<rootDir>/src/lib$1',
'^(.*)env$': '<rootDir>/src/lib/utils/testEnv',
'^\\$app(.*)$': [
'<rootDir>/.svelte-kit/dev/runtime/app$1',
'<rootDir>/.svelte-kit/build/runtime/app$1',
'<rootDir>/.svelte-kit/runtime/app$1'
],
'^.+\\.svg$': '<rootDir>/src/lib/EmptyIcon.svelte'
},

Related

How to do lazy export in Typescript

Module: shared-module
export * from "./common-types";
export * from "./lots-of-large-classes"
Let's say I have 200 large classes and import the above module like
Module: Main
import { CommonTypeClass } from "shared-module"
Now all 200 classes "also" will load as they are resolved in static scope and referred in my import.
To avoid this I tried
Object.defineProperty(module.exports, 'lots-of-large-classes', {
// The lots-of-large-classes folder is very large. To avoid pulling it in from static
// scope, we lazy-load the module.
get: () => require('./lots-of-large-classes'),
});
But VS Code isn't showing the lots-of-large-classes import.
import { LargeClassOne } from 'shared-module/lots-of-large-classes'; // ISN'T WORKING
However, above solution also still loads all classes as there is an index file which loads all classes.
How can I selective load LargeClassOne from lots-of-large-classes folder without loading other classes through shared-module?
Something like with overhead of loading one large class alone which is being imported.
import { LargeClassOne } from 'shared-module/lots-of-large-classes';
It's not possible to statically import dynamically-loaded data. Using subpath exports in the package.json for "shared-module" will help you accomplish your goal.
You can combine this with TypeScript's path mapping feature for very flexible import specifiers.

Is it possible to import a function in a modules subfolder

I'm trying to access the decode() method in the jsQR module.
I found an example that called decode() directly but that was from an HTML file, not nodejs.
In visual code I see this...
I know that the default export is defined in index.d.ts but is there anyway of importing the other classes/functions on the rest of the dist folder?
I've tried to import using require("jsqr/decoder") and require("jsqr/decoder/decode") to no avail.
EDIT
To be clear, I don't want jsQR, the default export. That deals with images. I'm trying to explicitly call the decode() method in the pic which accepts a BitMatrix
There are no limitations in what you can require from node_modules. So, with your case it should look like:
TypeScript\ESM Modules:
import { decode } from 'jsqr/dist/decoder/decoder';
CommonJS:
const { decode } = require('jsqr/dist/decoder/decoder');
UPD: If you take a look into dist folder for jsqr package, you can find that there are only d.ts files. Which means that you can not import it from there.
But, you can find an actual export of the module here:
Which means that you should able to import it from jsqr:
const { decode } = require('jsqr');

How do I set up a node component package to allow importing single components?

I have a Vue.js component package with a main file that looks like this:
export { default as Button } from './components/button'
export { default as Tooltip } from './components/tooltip'
export { default as Alert } from './components/alert'
This works fine when importing from the app, like:
import { Button } from 'components'
But I realized that this imports the entire library, even though I'm only asking for Button.
What do I need to do to my components library to allow importing like below, so that it only imports the button?
import Button from 'components/button"
I build the components repo uses Webpack 2, if that’s helpful.

import * best practice in node and react

Should I be importing my node modules using *
example
import * from 'express';
import * from './../../myCode';
Is it correct that by using the * that all exports will be imported which will make me bring functionality which will increase the file size.
import * as myCode from './../../myCode';
This inserts myCode into the current scope, containing all the exports from the module in the file located in ./../../myCode.
import React, { Component } from 'react';
class myComponent extends Component { ... }
By Using above syntax your bundler ( e.g : webpack) will still bundle the ENTIRE dependency but since the Component module is imported in such a way using { } into the namespace, we can just reference it with Componentinstead of React.Component.
For more information you can read mozilla ES6 module docs.
The answer is, it depends: there is no best practice for import/export since it's very up to you and your use-case. But normally I will just import what I need, not everything. And yes, if you do import * the file size of bundle.js can be big.

Using TypeScript Declaration For External JavaScript Library

I'm not sure if this extreme edge case or something but I cannot seem to find straight forward documentation on how to do this (or I'm just really not understanding what is available):
I am developing an ionic application and as part of that I need to use the ALKMaps JavaScript library (which is similar to Google Maps API). To do so, I created a local npm module and within that I created a alkmaps.d.ts file as recommended by https://www.typescriptlang.org/docs/handbook/declaration-files/by-example.html#objects-with-properties). However, I cannot seem to figure out how to properly import it into my angular code. The same document suggests that using <reference path=''> tags is not good but that is the only thing that seems to satisfy the tsc compiler.
My declaration file, alkmaps.d.ts, looks like (inside excluded for brevity):
declare namespace ALKMaps {
export class Map { ... }
...
}
And I was trying to import it into a file like:
import { ALKMaps } from 'alkmaps'; // Error: File '.../alkmaps.d.ts' is not a module
I also tried the following but got the same error.
import ALKMaps = require('alkmaps');
Using the reference tag seems to work within this module but then the project that utilizes this module still throws the "is not a module" error (that might warrant a separate question)
From https://github.com/Microsoft/TypeScript/issues/11420 I found the idea of using export = ALKMaps or export as namespace ALKMaps but adding those to my declaration file resulted in different errors instead.
Can anyone please explain in a straightforward way how to use declaration files representing external JS libraries in a typescript node module?
This is how I was able to get alkMaps into my Angular 2 app
Insert the script into the index.html file.
Declare an ALKMaps variable in the component that you are adding the map
imports .....
declare let ALKMaps : any;
#Component({
selector: 'show-map',
templateUrl: 'show-map.component.html'
})
export class ShowMapComponent implements Oninit{
map : any;
constructor() {
}
ngOnInit() {
ALKMaps.APIKey = "apiKey";
this.map = new ALKMaps.Map("map", {displayProjection: new ALKMaps.Projection("EPSG:4326")});
}
}
This will get the map to display and you can put different layers on the map, however the map does not display correctly. #Mike, if you were able to get further than this, will you please comment?
EDIT: The tiles on the image were elongated and not connected. After inspecting the css the main.css, after building, set a global property on the img element to:
img {
max-width:100%
}
The tiles for the map are originally set to 256% for the width. To correct the element, I changed the property for img in the style sheet.
show-map {
img {
max-width: 256%
}
}

Resources