I'm importing an npm package into my project with a package.json
like this:
{
// ...
"browser": "dist/umd/index.js",
"main": "dist/cjs/index.js",
"module": "dist/fesm2015/index.mjs",
"esm2015": "dist/index.js",
"fesm2015": "dist/fesm2015/index.mjs",
"typings": "dist/index",
"sideEffects": false,
"exports": {
"node": {
"module": "./dist/fesm2015/index.mjs",
"require": "./dist/cjs/index.js"
},
"browser": {
"module": "./dist/fesm2015/index.mjs",
"default": "./dist/umd/index.js"
},
"default": "./dist/cjs/index.js"
},
// ...
}
(I really, really wanted to have "type": "module"
in the above package, but that creates a whole other world of pain trying to make karma and other tools happy.)
I can build and run my project that uses the above npm package just fine, and I can run mocha unit tests outside of karma without any problem. However, when running under karma, I get errors like this:
20 06 2021 10:58:05.127:INFO [Chrome 91.0.4472.106 (Mac OS 10.15.7)]: Connected on socket 9qHeabxqGGw_tCrRAAAB with id 99567255
Chrome 91.0.4472.106 (Mac OS 10.15.7) @tubular/util should blend colors correctly FAILED
TypeError: math_1.round is not a function
at colorFromRGB (src/browser-graphics-util.js:2:2895)
at Object.blendColors (src/browser-graphics-util.js:2:1803)
at Context.<anonymous> (src/index.spec.js:60:45)
Chrome 91.0.4472.106 (Mac OS 10.15.7): Executed 30 of 30 (1 FAILED) (0.818 secs / 0.789 secs)
TOTAL: 1 FAILED, 29 SUCCESS
It seems that my project code isn't correctly binding to the code in the imported npm package, and all tests that depend on code from that package fail.
If I perform a little manual surgery on the contents of my node_modules
directory, and modify the package.json
of the imported npm package by removing "typings": "dist/index"
, karma is once again happy, and all my tests succeed.
Why, why for deity-of-your-choice's sake, does the existence of typings make any difference to karma-typescript about the success or failure of binding to the code in the npm package?
I definitely want that package (which is a package I created in another project) to provide TypeScript typings, so permanently getting rid of typings is NOT an option. How do I tell karma or karma-typescript to either ignore these typings, or simply not get so confused by them?
Here is my current karma.conf.js
:
module.exports = function (config) {
config.set({
frameworks: ['chai', 'karma-typescript', 'mocha'],
files: [
'src/**/*.ts'
],
preprocessors: {
'src/**/*.ts': 'karma-typescript'
},
reporters: ['progress', 'karma-typescript'],
browsers: ['Chrome'],
karmaTypescriptConfig: {
tsconfig: './tsconfig.karma.json'
},
});
};
And tsconfig.karma.json
, which simply exists to make karma build CommonJS modules instead of ESM modules:
{
"extends": "./tsconfig.json",
"compilerOptions": {
"module": "commonjs",
"target": "ES2015"
},
"exclude": [
"dist",
"node_modules"
]
}
UPDATE:
Another bit of information on this problem. If I use an explicit import like this:
import { max, min, round } from '../node_modules/@tubular/math/dist/cjs';
...instead of:
import { max, min, round } from '@tubular/math';
...the problem goes away, which confirms that this is a module resolution problem.
So what is it about module resolution that's changed while running in karma with karma-typescript? Are there settings I can use to tweak module resolution?
I figured it out.
karma-typescript
is dependent on browser-resolve
, and my imported package.json had a "browser"
entry, but meant for a somewhat different purpose, and clearly not at all compatible with how karma-typescript
uses browser-resolve
.
As long as I take out my "browser"
field, the "typings"
field can stay, and no longer causes my tests to fail.