Using tsconfig paths with Angular libraries? - javascript

I'm creating an Angular library and within tsconfig.lib.json I've added the following paths configuration:
"compilerOptions": {
"outDir": "../../out-tsc/lib",
"target": "es2015",
"declaration": true,
"inlineSources": true,
"types": [],
"lib": [
"dom",
"es2018"
],
"paths": {
"#fs/*": ["src/lib/*"]
}
}
However attempting to import things like:
import { Test } from '#fs/Test'
Does not work. Anyone know if Angular libraries support hte paths configuration option within tsconfig.lib.json?
Generally I use typescript-transform-paths to perform path transformation on the compiled result, and I was hoping Angular had baked something like this in for libraries?

Try using the following pattern in your tsconfig.json file :
"paths": {
"#services/*": ["app/path/to/services/*"],
"#components/*": ["app/path/to/some/deeply/nested/component/*"],
"#environments/*": ["environments/*"]
},
Then when importing:
import { yourServiceClass } from "#services/yourServiceClass";

Related

jsconfig.json Can't Work with "require" Node.js?

I'm studying the jsconfig.json file, the documentation doesn't mention explicitly whether it works with "import" and "require", or just "import".
This is the jsconfig.json I created (for Express project):
{
"compilerOptions": {
"baseUrl": "./",
"module": "CommonJS",
"target": "es2020",
"paths": {
"#/controllers/*": ["controllers/*"],
}
},
"exclude": ["node_modules", "**/node_modules/*"]
}
I can't do like this:
const userController = require('#/controllers/user-controller');
// Error: Cannot find module '#/controllers/user-controller'
Why can't I use "require"? I Tried it in React and it worked with "import".

Using Javascript module in Typescript Vue project

The problem
I'm trying to use https://github.com/moonwave99/fretboard.js in my Vue project. I try to import the module in a component as follows:
<template>
<div>
<div id="fretboard" />
</div>
</template>
<script lang="ts">
import { Fretboard } from '#moonwave99/fretboard.js';
const fretboard = new Fretboard({
el: '#fretboard',
fretColor: 'blue',
dotFill: 'red'
});
fretboard.render([
{
string: 5,
fret: 3
},
{
string: 4,
fret: 2
},
{
string: 2,
fret: 1
}
]);
</script>
This results in the following error:
Could not find a declaration file for module '#moonwave99/fretboard.js'. '/Users/xxx/guitar-apps/node_modules/#moonwave99/fretboard.js/dist/fretboard.cjs.js' implicitly has an 'any' type.
Try `npm install #types/moonwave99__fretboard.js` if it exists or add a new declaration (.d.ts) file containing `declare module '#moonwave99/fretboard.js';`Vetur(7016)
I've tried runing the npm install #types/moonwave99__fretboard.js command but that also resulted in an error, saying '#types/moonwave99__fretboard.js#latest' is not in the npm registry..
I've been looking all over the place, but couldn't find a solution that worked for my project. Anybody out there who has a solution to my problem?
Things I've tried
Creating a declaration file containing declare module '#moonwave99/fretboard.js in the root of my project directory
Adding "allowJs": true to my tsconfig.ts file
Additional information
My tsconfig looks like:
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"allowJs": true,
"importHelpers": true,
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env",
"jest"
],
"paths": {
"#/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}
The .d.ts file should be in one of the include paths configured in tsconfig.json, and according to the tsconfig.json you've posted, that's src or tests. These typings are typically stored in src root (you'll see src/shims.vue.d.ts in a Vue CLI-generated project).
You could add a src/fretboard.d.ts file, containing declare module '#moonwave99/fretboard.js'. Then, you'd have to restart VS Code, so that the typings are indexed properly, which would resolve the error.
Solved with on file src/.env.d.ts add declare module 'vue-image-zoomer'.
All done. Vanished the error of module not found.
Happy coding.

How to get Visual Studio Code to navigate to a React component's source file?

Consider a typical ReactJS file, like:
import Popup from 'components/Popup/Popup';
// ...
<Popup
trigger={
<SVG src={pinIcon} className={pinClassName} />
}
content={pinTooltipText}
position="bottom center"
hideOnScroll
className="popup-xl--hide"
/>
In VS Code, I want to go to the file that is my component, so jump to components/Popup/Popup. Using Go To Definition:
It sends me up to the import declaration. I can't jump to that file. This is a pain to manage as we have dozens of components and properties moving through them all. Being able to quickly navigate "down" the component stack by going to each definition would be mind-numbingly awesome.
If you have import aliases, through webpack or babel, you can create a jsconfig.json file with the paths property in the compilerOptions.
Here's a Next project's jsconfig.json configured for #/ aliases to the src/ directory.
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"#/*": ["./src/*"],
}
},
"exclude": [
"node_modules",
"dist",
".next",
".cache",
"bundles",
"out"
],
"include": [
"pages/**/*",
"src/**/*",
]
}
It may be needed to restart VS Code, then you should be able to CTRL+click any <Component> or import paths to navigate to it.
For me, installing flow-bin solved the problem, I got this warning from vs-code while working on react project.
npm install flow-bin -g
If you go up to the listing of the item within the import statement and hit [F12] again, you'll get this window:
Within that window, you can double click anywhere within that left hand window, and it will open the file to that location.
for me the first code did not work, I spend a few to fixing it. here is my code:
jsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"target": "es2017",
"jsx": "react",
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"paths": {
"#/*":["src/*"],
"root/*": ["./*"]
}
},
"exclude": [
"node_modules",
"dist",
".next",
".cache",
"bundles",
"out"
],
"include": [
"build/**/*",
"server/**/*",
"e2e/**/*",
"pages/**/*",
"src/**/*",
"stories/**/*"
]
}

Typescript classes bundle with webpack

I have written a project on Typescript and setup to bundle it with webpack.
Main functionality is wrapped in one Main class, but it imports also other classes.
Need to export Main class and all dependent in to one bundle.js library to use in in other sites.
I've tried to bundle classes in separate project (without webpack just tsc).
this is tsconfig.json:
{
"compilerOptions": {
"module": "amd",
"target": "ES2015",
"declaration": true,
"outDir": "./dist",
"outFile": "./dist/index.js",
},
"include": [
"src/**/*"
]
}
but it is not usable since the error:
ReferenceError: define is not defined
compilled code contains edfine
define("Globals", ["require", "exports"], function (require, exports) {
and also with webpack but not sure have correct setup
the bundle file start with
(function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
in other words I have some classes:
Main.ts
A.ts
B.ts
C.ts
and I expected to get bundle.js file and use like this:
<script type="text/javascript" src="mylib/dist/index.js"></script>
//...
var a = new Main();
but stuck with understanding how it should Typescript and Jsvascript work together.
Will appreciate any help
Update:
Managed to solve with webpack. Main is asccessible from entry app.ts when compiled. So inside app.ts added window.onload handler and assigned class to window scope.
window.onload = function () {
window['MyClass'] = Main;
May be missing something but couldn't find good documentation about writing library on TypeScript for browsers.
Update2:
Ok. found answer. webpack option library works fine.
output: {
filename: "bundle.js",
path: __dirname + "/dist",
library: "MyMainClass"
},
also had to change tsconfig.json target option from es6 to es5
{
"compilerOptions": {
"baseUrl": ".",
"paths": { "*": ["types/*"] },
"lib": [
"dom",
"es6",
"dom.iterable",
"scripthost"
],
"module": "commonjs",
"target": "es5"
},
"exclude": [
"node_modules"
]
}

Angular 8 - Lazy loading modules : Error TS1323: Dynamic import is only supported when '--module' flag is 'commonjs' or 'esNext'

When I updated Angular from 7 to Angular 8, getting error for lazy loading modules
I have tried the options, which are there in the angular upgradation guide
Made the below changes:
Before
loadChildren: '../feature/path/sample-
tage.module#SameTagModule'
After
loadChildren: () => import('../feature/path/sample-
tags.module').then(m => m.CreateLinksModule)
error TS1323: Dynamic import is only supported when '--module' flag is
'commonjs' or 'esNext'.
You are using dynamic import so you have to change your tsconfig.json like this to target your code to esnext module
{
"compileOnSave": false,
"compilerOptions": {
"baseUrl": "./",
"outDir": "./dist/out-tsc",
"sourceMap": true,
"declaration": false,
"module": "esnext", // add this line
"moduleResolution": "node",
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"importHelpers": true,
"target": "es2015",
"typeRoots": [
"node_modules/#types"
],
"lib": [
"es2018",
"dom"
]
}
}
Also make sure to check tsconfig.app.json dont have module and target config something like this
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "./out-tsc/app",
"types": []
},
"include": [
"src/**/*.ts"
],
"exclude": [
"src/test.ts",
"src/**/*.spec.ts"
]
}
Just want to add my experience to #Tony's answer.
After changing tsconfig.json it still showed an error (red underline). Only after reopening the editor (I used VSCode) did I see the red underline disappear.
Just adding to #Tony's anwser, you might also need to do the same (change to "module": "esnext" ) in the tsconfig.app.json. In my case the tsconfig.json was already using esnext as the module but the tsconfig.app.json was still using es2015 and that caused this error.
I think the proper way to do this is to adjust tsconfig.app.json rather than tsconfig.json.
tsconfig.app.json
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/app",
"baseUrl": "./",
"module": "esnext",
"types": []
},
"exclude": [
"test.ts",
"**/*.spec.ts"
]
}
tsconfig.app.json is the Typescript configuration file specific to the app that sits beneath the root of the Angular workspace. The tsconfig.app.json exists so that if you are building an Angular workspace that has multiple apps in it, you can adjust the Typescript configuration separately for each app without having to write redundant configuration properties that overlap between the apps (hence the extends property).
Technically, you don't need tsconfig.app.json at all. If you delete it, you will have to place the "module": "esnext" in tsconfig.json. If you keep it there, it will take precedence over tsconfig.json, so you only need to add the "module":"esnext" line in tsconfig.app.json.
I resolved this issue only by adding
"include": ["src/**/*.ts"]
in my tsconfig.app.json file.
Just update the angular version by giving below command. The errors will disappear.
ng update #angular/core #angular/cli --next
After that, change the target and module in tsconfig.json file
"target": "esnext",
"module": "esnext",
i resolve this error by by doing following steps
step 1:
"module": "es2015" to
"module": "AMD" in tsconfig.json
step 2:
create a new file tsconfig.app.json in app root directory, copy code of Tony Ngo and paste into, then this problem will be resolved.
My angular version is 8.2 and I fixed it by just changing "module": "es2015" to "module": "es2020"
If you are using Ionic framework and VSCode you need to update your Typescript IDE version (> 4)!
I had this issue with angular 13, I noticed that some services had this issue while others didn't, the difference was
#import { Injectable } from '#angular/core/';
while this perfectly compiled without no issues on angular 9 but the fix was to remove the / at the end to become'
#import { Injectable } from '#angular/core';

Categories

Resources