grunt-contrib-coffee source map only points to joined file - node.js

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.

Related

package.json export multiple search paths

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.

Make "import/extensions" require the .js extension in a Node.js TypeScript project

First of all, some facts:
Node.js requires that all local imports include the imported module's extension (e.g. import hello from './hello.js', not import hello from './hello').
TypeScript will compile imports with or without the .js extension, which means a missing .js extension is a runtime error.
TypeScript doesn't transform imports to add the .js extension or convert .ts to .js.
In my Node.js project, I want to make missing a missing .js extension be a build-time error using the import/extensions ESLint rule. However, when I enable this rule using the following configuration:
{
"root": true,
"env": {
"node": true
},
"parser": "#typescript-eslint/parser",
"plugins": [
"#typescript-eslint"
],
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"settings": {
"import/resolver": {
"typescript": {},
"node": {
"extensions": [".js"]
}
}
},
"rules": {
"import/extensions": ["error", "ignorePackages"]
}
}
running eslint gives me the following error:
/sandbox/src/index.ts
1:19 error Missing file extension "ts" for "./hello.js" import/extensions
Source files:
// index.ts
import hello from "./hello.js";
hello();
// hello.ts
export default function hello() {
console.log("Hello");
}
CodeSandbox link: https://codesandbox.io/s/elated-germain-13glp7
I fixed this with the following config:
{
"root": true,
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:import/recommended",
"plugin:import/typescript",
"plugin:#typescript-eslint/eslint-recommended",
"plugin:#typescript-eslint/recommended"
],
"rules": {
"import/extensions": ["error", "ignorePackages"],
"import/no-unresolved": "off"
}
}
The main thing is to disable the "import/no-unresolved" rule and remove "settings"."import/resolver"."node". ("import/no-unresolved" is redundant as unresolved imports are resolved at the compilation stage.) Other items removed here were already being added as a result of extending the #typescript-eslint plugins.
I found an eslint plugin that can fix missing .js extensions for imports in .ts files, instead of just showing an error:
https://github.com/AlexSergey/eslint-plugin-file-extension-in-import-ts
https://www.npmjs.com/package/eslint-plugin-file-extension-in-import-ts
Install:
npm i -D eslint-plugin-file-extension-in-import-ts
Add to .eslintrc file:
{
"plugins": [
"file-extension-in-import-ts"
],
"rules": {
"file-extension-in-import-ts/file-extension-in-import-ts": "error"
}
}
NOTE: I ran into an issue similar to https://github.com/import-js/eslint-plugin-import/issues/1292 when using this package, and it will incorrectly try to add .js extensions on these paths when fixing automatically.
You could try ts-add-js-extension package to append .js extension to the transpiled JavaScript files. After you install you can do
ts-add-js-extension add --dir={your-transpiled-outdir}

How to add subdirectory module aliases in tsconfig?

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

Jest, Typescript, ts-jest: Coverage is slightly incorrect

I am wrtiting a project using TypeScript, Jest and the ts-jest NPM module.
When I run my test, I do get some amount of coverage, but the HTML report is not quite right:
Furthermore, some functions are being marked as untested even though they are certainly being called.
My package.json is set as follows:
{
"jest": {
"transform": {
".(ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testResultsProcessor": "<rootDir>/node_modules/ts-jest/coverageprocessor.js",
"collectCoverage": true,
"collectCoverageFrom": [
"src/**/*.{ts,tsx}"
],
"coverageReporters": [
"html",
"json"
]
}
}
Is something wrong with my configuration?
UPDATE
Starting from jest#20 you can pass mapCoverage option and use coverage/lcov-report/index.html file.
OLD
I also have been struggling with this problem, but then I notice that line.
Long story short - coverage reports goes to coverage/remapped/html/index.html file.

Does chutzpah support requirejs shims/config?

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"]
}
}
});

Resources