I'm building some code in src to dist. I want any top-level files (dist/*.mjs) and any second-level files (dist/*/index.mjs) to be exports:
"exports": {
".": {
"import": "./dist/index.mjs",
"types": "./dist/index.d.ts"
},
"./*": {
"import": "./dist/*.mjs",
"types": "./dist/*.d.ts"
},
"./*": {
"import": "./dist/*/index.mjs",
"types": "./dist/*/index.d.ts"
},
}
The last item for obvious reasons (can't have two identical keys in JSON) does not work correctly. I can get one or the other working, but I'd like it to try one and fallback to the next.
In desperation I tried using an array there but it didn't work. Is there a strategy I can use here that will make this feasible? The build-tooling I am currently stuck with (tsup) doesn't seem to be able to build src/foo.ts into src/foo/index.mjs and I'd rather not write a post-processor to move them around, but I will if I have to.
Related
Since TypeScript 3, it is possible to use projects as references within a given project.
I was trying to use such feature on two personal projects I have but it was not working. So I decided to use a given example as a starting point: https://github.com/appzuka/project-references-example
When I launch npm run build, all projects compile successfully. I then decided to modify the tsconfig.json file of package animals to include the support of aliases. The file was modified as such:
{
"extends": "../../tsconfig-base.json",
"compilerOptions": {
"outDir": "lib",
"rootDir": ".",
"baseUrl": ".",
"paths": { "#animals/*": [ "*" ] }
},
"references": [
{ "path": "../core" }
]
}
(baseUrl and paths properties were added inside compilerOptions)
I then modified the first import of dog.tsx file this way:
import { Animal, Size } from #animals/animal;
When I try to build again the main project, it fails. The error is:
ERROR in C:\Users\User\Documents\project-references-example\packages\animals\dog.tsx
[tsl] ERROR in C:\Users\User\Documents\project-references-example\packages\animals\dog.tsx(1,30)
TS2307: Cannot find module '#animals/animal' or its corresponding type declarations.
To make it working, I need to add the alias also on the main project, like this (in tsconfig.json):
"paths": {
"#animals/*": [ "packages/animals/*" ]
}
Is there a possibility to use alias in a referenced project without having to specify such alias in the parent project?
Thank you!
I want to include the rule no-unpublished-import from eslint-plugin-node, however, it is conflicting with my current .eslintrc because I am using typescript-eslint and eslint-import-resolver-typescript.
It is my current configuration:
{
"parser": "#typescript-eslint/parser", // Specifies the ESLint parser
"extends": [
"airbnb-base",
"plugin:#typescript-eslint/recommended", // Uses the recommended rules from the #typescript-eslint/eslint-plugin
"prettier", // Enables eslint-plugin-prettier and displays prettier errors as ESLint errors. Make sure this is always the last configuration in the extends array
"prettier/#typescript-eslint" // Uses eslint-config-prettier to disable ESLint rules from #typescript-eslint/eslint-plugin that would conflict with prettier
],
"parserOptions": {
"project": "./tsconfig.json",
"ecmaVersion": 6, // Allows for the parsing of modern ECMAScript features
"sourceType": "module" // Allows for the use of imports
},
"rules": {
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".ts"]
},
// use <root>/tsconfig.json
"typescript": {
"alwaysTryTypes": true // always try to resolve types under `<root>#types` directory even it doesn't contain any source code, like `#types/unist`
}
}
},
"root": true
}
The code compiles correctly, however, if I add to the extends option the plugin:node/recommended the compilation process will fail:
1:1 error Import and export declarations are not supported yet node/no-unsupported-features/es-syntax
1:43 error "express" is not found node/no-missing-import
2:1 error Import and export declarations are not supported yet node/no-unsupported-features/es-syntax
My package.json includes the node": ">=12.0.0. Also, this rule should be ignored because I am using typescript. On the other hand, I am just exporting types from express because the module don't use it.
According to this issue the conflict should be resolved by eslint-plugin-node.
How can I accomplish the merge of both plugins? Do I have to go disabling rules one by one?
UPDATED:
It seems it was asked in this issue on the eslint-plugin-node repository. It works for no-unsupported-features and no-missing-import, however, it is still failing with the import definition of express with no-extraneous-import.
UPDATED 2:
It seems eslint-plugin-node is working on a enhancement to accomplish it. Issue here
Firstly, you have to add the option tryExtension to include TS files:
"settings": {
"node": {
"tryExtensions": [".js", ".json", ".node", ".ts", ".d.ts"]
},
To solve the no-unsupported-features/es-syntax, according to this issue about adding information to works with TypeScript, if you work with transpilers you will have to ignore it under rules:
"node/no-unsupported-features/es-syntax": ["error", { "ignores": ["modules"] }],
On the other hand, use just types and not the code is not supported yet by the eslint-plugin-node. They are working on a enhancement to solve it. However,, to solve the no-missing-import, you have to add to the resolvePath the node_modules/#types:
"node": {
"resolvePaths": ["node_modules/#types"],
"tryExtensions": [".js", ".json", ".node", ".ts", ".d.ts"]
},
Even so, it will generate a no-extraneous-import because it doesn't detect the module, because it is just a type. Meanwhile they are working on this enhancement, you can use allowModules under that rule for workaround:
"node/no-extraneous-import": ["error", {
"allowModules": ["express"]
}]
I can set module aliases with no issue:
"baseUrl": "./app",
"paths": {
"assets/*": ["assets/*"],
"components/*": ["components/*"],
...
},
This works. However, I (actually my client, who wants to extract some parts of the project as a module in the future) want to create subdirectories as aliases to different paths (assume that all the directories as values exist, and I cannot change the actual directory structure):
"paths": {
"assets/*": ["assets/*"],
"components/*": ["components/*"],
"#myapp/api/*": ["services/myapp/*"],
"#myapp/state/*": ["state/*"],
},
Putting aside whether this is a good pattern/practice or not (as I'm asked to do it this way), is this technically possible without touching the physical directory structure (and without the use of 3rd party dependencies)? (I'm using Typescript 3.4.3 and Vscode 1.33.1)
"baseUrl": "./",
"paths": {
"#myapp/environment": [ "./src/environments/environment" ],
"#myapp/extensions": [ "./src/extensions" ],
"#myapp/testing": [ "./src/testing" ],
"#myapp/constants": [ "./src/app/shared/constants" ],
"#myapp/data": [ "./src/app/data" ],
"#myapp/shared": [ "./src/app/shared" ],
"#myapp/core/*": [ "./src/app/core/*" ],
"#myapp/*": [ "./src/app/*" ]
}
this works like a charm on my project
I'm using Grunt to compile my project, and I'm very happy with it. However, when I attempt to create source maps for my CoffeeScript-files, grunt-contrib-coffee generates a map to the joined file (the concatenated result of all my CoffeeScript files), not to my actual CoffeeScript sources, and I have been unable to find a reason for this.
How do I make the compiler generate a map of my actual CoffeeScript sources, instead of the joined file?
After CoffeeScript has compiled, I use grunt-contrib-uglify to generate the actually-used JS file, and its sourceMapIn-option is working like a charm. It's the CoffeeScript compiler that generates a weird source map.
Here's my grunt-contrib-coffee-configuration. The app-files contains an array of 24 CoffeeScript files.
{
"source": {
"options": {
"bare": true,
"sourceMap": true
},
"expand": true,
"join": true,
"cwd": ".",
"ext": ".js",
"files": {
"<%= build_dir %>/public.js": [ "<%= app_files.coffee %>" ]
}
}
}
Here's the resulted source map.
{
"version": 3,
"file": "public.js",
"sourceRoot": "",
"sources": [
"public.src.coffee"
],
"names": [],
"mappings": [ ... ]
}
As you see, the only source it points to is public.src.coffee, which is the file CoffeeScript joined my files into before compiling into CS.
Thanks for your time.
I have some qunit tests setup to test my code that extensively uses requirejs. I use Chutzpah to perform the test running within VS. Everything works fine if I run the tests in the browser but not from within VS only. It seems to be ignoring my require.config call. If I change my references in my files to not point to shims but directly to files, it will work, but that breaks other things within my code.
Does anyone have this working? If so, how? I have looked at their example code but it doesn't use require.config and shims.
Start from this tutorial.
To run a config, with shims, just add a reference to your config file in chutzpah.json. Example below, slightly simplified for readability.
The chutzpah.json file
{
"Framework": "qunit",
"TestHarnessReferenceMode": "AMD",
"TestHarnessLocationMode": "SettingsFileAdjacent",
"References": [
{ "Path": "../Scripts/Components/RequireJS/require.js" },
{ "Path": "config.js" }
]
}
The config.js file
require.config({
"paths": {
"jquery": "../Scripts/jquery-2.1.4",
"jquery-linq": "../Scripts/jquery.linq",
"signalr": "../Scripts/jquery.signalR-2.2.0",
"signalrhubs": "../Scripts/mock-signalr-hubs",
"knockout": "../Scripts/knockout-3.3.0",
"constants": "../Scripts/constants",
"HomeVm": "Source/HomeVm"
},
"shim": {
"jquery.linq": {
"deps": ["jquery"]
},
"bootstrap": {
"deps": ["jquery"]
},
"signalr": {
"deps": ["jquery"]
}
}
});