Tsconfig `paths` equivalent for normal JS node - javascript

I have this on a TypeScript project, it's a nice config option on tsconfig.json that lets me create aliases for the folders
{
"compilerOptions": {
"paths": {
"#src/*": ["src/*"],
"#images/*": ["src/assets/images/*"],
"#styles/*": ["src/assets/styles/*"],
"#components": ["src/components"],
"#layout/*": ["src/layout/*"],
"#pages/*": ["src/pages/*"]
}
}
Is there a way to do the same on a project that does not use TypeScript, just regular Javascript in node with ES6 modules on?

I found that node already has something called Subpath imports, is not exactly the same but it works for me. For anyone looking for something similar, this just uses # instead of #:
on the package.json
"imports": {
"#src": "./src/*",
"#controllers/*": ["./src/controllers/*"],
"#routes/*": ["./src/routes/*"]
}
And then import on your app, – In this case I use ES modules:
import File from '#routes/file.js'

Related

Problems using a js module is ts project

I have a react ts project where I installed a pure js module: crypto-prices. Considering this module doesn't have any #types source, I created a decs.d.ts file with:
declare module "crypto-prices"
This removes the IDE issue. Yet, when I try to use the cryptoPrice modules through
import cryptoPrice from 'crypto-prices'
I get the following error:
Can't resolve 'crypto-prices' in ...
Import it like this,
import * as cryptoPrice from 'crypto-prices'
You need to include decs.d.ts in tsconfig.json. If decs.d.ts is in the same folder as tsconfig.json it should look something like below:
tsconfig.json
{
"include": [
"./src/**/*",
"./decs.d.ts"
],
"compilerOptions": {
...
}
}

How to use absolute/dynamic paths in NodeJs

Would like to use imports by using absolute/dynamic paths, like
import { GlobalVars } from "utils/GlobalVars.js";
but not like
import { GlobalVars } from "../../utils/GlobalVars.js";
With the help of below code snippet able to follow absolute/dynamic path facility in react
jsconfig.json (Which is created at root level of the project)
{
"compilerOptions": {
"baseUrl": "src"
},
"include": ["src"]
}
with the same code snippet unable to use absolute paths in NodeJs.
Do we have any other approach to use absolute paths in NodeJs or am i doing any mistake

NextJS where defines tilde '~' symbol in import path?

I read code in an app with NextJS. It imports component like import Head from '~/components/layout/head'
The project structure:
-app
---components
---pages
---public
I wonder where defines ~ as root dir in nextJS.
Where can I find the config of this?
Tried uncover the webpack config inside next package, but didn't find.
With Typescript's paths feature you can specify a module mapping.
// tsconfig.json
{
"compilerOptions": {
...
"baseUrl": "./src",
"paths": {
"#anything/utils/*": ["app/utils/*"],
"#anything/pipes/*": ["app/pipes/*"]
}
...
}
}
This will allow you to import using
import x from '#anything/utils/dateToNum';
that will be mapped to app/utils/dateToNum.
If your are using webpack, you will need to use tsconfig-paths-webpack-plugin.
According to the doc.
You can set the module mapping without extra libs.
In your file structure, try this example.
// tsconfig.json
{
"compilerOptions": {
...
"baseUrl": ".",
"paths": {
"~*": ["./*]
}
}
}
Then go to your files:
import { xxx } from '~/components';
// or
import xxx from '~/components/xxx';
I find this is because the babel plugin babel-plugin-root-import, since the project uses this plugin in babel config.
More about this plugin can check here.

How Should VSCode Be Configured To Support A Lerna Monorepo?

I have a lerna monorepo containing lots of packages.
I'm trying to achieve the following:
Ensure that VSCode provides the correct import suggestions (based on package names, not on relative paths) from one package to another.
Ensure that I can 'Open Definition' of one of these imports and be taken to the src of that file.
For 1. I mean that if I am navigating code within package-a and I start to type a function exported by package-b, I get a suggestion that will trigger the adding of an import: `import { example } from 'package-b'.
For 2. I mean that if I alt/click on the name of a function exported by 'package-b' while navigating the file from a different package that has imported it, I am taken to '/packages/namespace/package/b/src/file-that-contains-function.js',
My (lerna) monorepo is structured as standard, for example here is a 'components' package that is published as #namespace/components.
- packages
- components
- package.json
- node_modules
- src
- index.js
- components
- Button
- index.js
- Button.js
- es
- index.js
- components
- Button
- index.js
- Button.js
Note that each component is represented by a directory so that it can contain other components if necessary. In this example, packages/components/index exports Button as a named export. Files are transpiled to the package's /es/ directory.
By default, VSCode provides autosuggestions for imports, but it is confused by this structure and, for if a different package in the monorepo needs to use Button for example, will autosuggest all of the following import paths:
packages/components/src/index.js
packages/components/src/Button/index.js
packages/components/src/Button/Button.js
packages/components/es/index.js
packages/components/es/Button/index.js
packages/components/es/Button/Button.js
However none of these are the appropriate, because they will be rendered as relative paths from the importing file to the imported file. In this case, the following import is the correct import:
import { Button } from '#namespace/components'
Adding excludes to the project's jsconfig.json has no effect on the suggested paths, and doesn't even remove the suggestions at /es/*:
{
"compilerOptions": {
"target": "es6",
},
"exclude": [
"**/dist/*",
"**/coverage/*",
"**/lib/*",
"**/public/*",
"**/es/*"
]
}
Explicitly adding paths using the "compilerOptions" also fails to set up the correct relationship between the files:
{
"compilerOptions": {
"target": "es6",
"baseUrl": ".",
"paths": {
"#namespace/components/*": [
"./packages/namespace-components/src/*.js"
]
}
},
}
At present Cmd/Clicking on an import from a different package fails to open anything (no definition is found).
How should I configure VSCode so that:
VSCode autosuggests imports from other packages in the monorepo using the namespaced package as the import value.
Using 'Open Definition' takes me to the src of that file.
As requested, I have a single babel config in the root:
const { extendBabelConfig } = require(`./packages/example/src`)
const config = extendBabelConfig({
// Allow local .babelrc.js files to be loaded first as overrides
babelrcRoots: [`packages/*`],
})
module.exports = config
Which extends:
const presets = [
[
`#babel/preset-env`,
{
loose: true,
modules: false,
useBuiltIns: `entry`,
shippedProposals: true,
targets: {
browsers: [`>0.25%`, `not dead`],
},
},
],
[
`#babel/preset-react`,
{
useBuiltIns: true,
modules: false,
pragma: `React.createElement`,
},
],
]
const plugins = [
`#babel/plugin-transform-object-assign`,
[
`babel-plugin-styled-components`,
{
displayName: true,
},
],
[
`#babel/plugin-proposal-class-properties`,
{
loose: true,
},
],
`#babel/plugin-syntax-dynamic-import`,
[
`#babel/plugin-transform-runtime`,
{
helpers: true,
regenerator: true,
},
],
]
// By default we build without transpiling modules so that Webpack can perform
// tree shaking. However Jest cannot handle ES6 imports becuase it runs on
// babel, so we need to transpile imports when running with jest.
if (process.env.UNDER_TEST === `1`) {
// eslint-disable-next-line no-console
console.log(`Running under test, so transpiling imports`)
plugins.push(`#babel/plugin-transform-modules-commonjs`)
}
const config = {
presets,
plugins,
}
module.exports = config
In your case, I would make use of lerna in combination with yarn workspaces.
When running yarn install, all your packages are linked under your #namespace in a global node_modules folder. With that, you get IntelliSense.
I've set up an example repository here: https://github.com/flolude/stackoverflow-lerna-monorepo-vscode-intellisense
You just need to add "useWorkspaces": "true" to your lerna.json
lerna.json
{
"packages": ["packages/*"],
"version": "0.0.0",
"useWorkspaces": "true"
}
And the rest is just propper naming:
global package.json
{
"name": "namespace",
// ...
}
package.json of your component package
{
"name": "#namespace/components",
"main": "src/index.js",
// ...
}
package.json of the package that imports the components
{
"name": "#namespace/components",
"main": "src/index.js",
"dependencies": {
"#namespace/components":"0.0.0"
}
// ...
}
Then you can do the following:
import { Component1 } from '#namespace/components';
// your logic
Automatically Importing from #namespace
Unfortunately, I couldn't find a way to make this work in VSCode with a Javascript Monorepo. But there are some things you can do:
Use Typescript (tutorial, other tutorial)
Use module-alias
Add import {} from '#namespace/components' to the top of your file
Use Auto Import Extension
Edit: This is broken with the latest version of VSCode.
I finally managed to get this working reliably. You need to create a separate jsconfig.js for every package in your monorepo, for example:
{monorepo root}/packages/some-package/jsconfig.json:
{
"compilerOptions": {
"target": "es6",
"jsx": "preserve",
"module": "commonjs"
},
"include": ["src/**/*.js"],
"exclude": ["src/index.js"]
}
Note that I've excluded the src/index.js file so it doesn't get offered as an import suggestion from within that package.
This setup appears to achieve:
Intellisense import suggestions from packages instead of using relative paths.
Go to definition to source of other packages in the monorepo.
VSCode has been pretty flaky of late, but it seems to be working.
Note this is working for a JavaScript-only monorepo (not Typescript).

How can I organize my Angular app folders like a Java package?

How to organize Angular 2 app folder structure like Java packages?
Consider the following project layout:
app
|_model
|_component
|_service
I would like to import foo.service.ts from service to bar.component.ts in component. But as far as I know, Angular 2 import supports only relative paths like /../service/, which seems very clunky solution.
Is there a way to refer folders with absolute bath from root folder, like with Java packages?
UPDATE 2016-06-01
using npm install typescript#next you can already use this function
I assume that your tree looks like this:
node_modules
|_#angular
|_rxjs
app
|_model
|_component
|_service
package.json
tsconfig.json
You should add in your tsconfig.json the following lines:
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"*": [
"app/*",
"node_modules/*"
]
}
}
}
then you can reference your modules like you do with regular #angular/rxjs modules
import { MyService } from 'service/MyService';
import { Component } from '#angular/core';
import { Observable } from 'rxjs';
Note: webpack needs also the following lines in webpack.config.js
resolve: {
modulesDirectories: [
'node_modules',
'app'
]
}
Not yet, it should be present soon with Typescript 2.0
Look here
https://github.com/Microsoft/TypeScript/issues/5039

Categories

Resources