I have a very small project that I am trying to set up unit tests for. The project compiles fine when using tsc
directly, however, I am getting the following Typescript compilation errors when attempting to execute tests which use the karma-typescript framework:
ERRORS:
ERROR [compiler.karma-typescript]: src/drawing/canvas.model.ts(1,23): error TS2307: Cannot find module 'utils'.
ERROR [compiler.karma-typescript]: src/models/grid.model.ts(1,23): error TS2307: Cannot find module 'utils'.
ERROR [compiler.karma-typescript]: src/utils/specs/obj.utils.spec.ts(1,23): error TS2307: Cannot find module 'utils'.
PROJECT STRUCTURE: I've got a project set up that is structured as such:
|-dist/
|-node_modules/
|-src/
| |
| |-drawing/
| | |
| | |-canvas.model.ts
| | ________________________________
| | | import { Utils } from 'utils'; | Karma Fails (tsc is fine)
| | --------------------------------
| |
| |-models/
| | |
| | |-grid.model.ts
| | ________________________________
| | | import { Utils } from 'utils'; | Karma Fails (tsc is fine)
| | --------------------------------
| |
| |-utils/
| | |
| | |-index.ts
| | | _________________________
| | | | export module Utils {} |
| | | -------------------------
| | |
| | |-specs/
| | | |
| | | |-obj.utils.spec.ts
| | | ________________________________
| | | | import { Utils } from 'utils'; | Karma Fails (tsc is fine)
| | | --------------------------------
| | |
|-karma.config.js
|-tsconfig.json
|-package.json
It's clear to me that there is a discrepancy between my tsconfig.json file and the compiler settings used internally for karma-typescript. Here is how I have both of those files structured. According to the documentation for karma-typescript, there should be a couple of options that I can configure in my karma.conf file that would tell karma-typescript to respect my settings in my Typescript config file, namely the "paths"
property, which is where I have specified to Typescript where to look for my utils
module.
KARMA.CONF.JS
// Karma configuration
// Generated on Fri Mar 31 2017 16:42:11 GMT-0700 (PDT)
module.exports = function(config) {
config.set({
// base path that will be used to resolve all patterns (eg. files, exclude)
basePath: '',
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine', 'karma-typescript'],
// Plugins
plugins: [
'karma-spec-reporter',
'karma-jasmine',
'karma-chrome-launcher',
'karma-jasmine-html-reporter',
'karma-typescript'
],
// list of files / patterns to load in the browser
files: [{
pattern: "./src/**/*.ts"
}],
// list of files to exclude
exclude: ['**/*.spec.js'],
// Karma Typescript compiler options
karmaTypescriptConfig: {
bundlerOptions: {
resolve: {
directories: ["src", "node_modules", "src/utils"]
}
}
},
compilerOptions: {
module: 'commonjs',
moduleResolution: 'node',
paths: {
'utils': ['./src/utils'], 'utils/*': ['./src/utils/*']
}
},
tsconfig: './tsconfig.json',
// preprocess matching files before serving them to the browser
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
preprocessors: {
"**/*.ts": ["karma-typescript"]
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['progress', 'kjhtml', 'spec', "karma-typescript"],
// web server port
port: 9876,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity
})
}
Here is my Typescript config file. Note that I am registering the "utils"
in the "paths"
portion of the tsconfig file, which assists in the Typescript compiler's module resolution process. This works fine with normal Typescript compilation, but that is probably because my Typescript compiler is actually respecting the settings in my tsconfig file. I am using Typescript 2.0.10. But it appears that karma-typescript is using Typescript 2.2.2, which could be the potential source of the error. I'll have to run my compiler against that version to see if I can generate the same error.
TSCONFIG.JSON
{
"compileOnSave": true,
"compilerOptions": {
"baseUrl": ".",
"outDir": "./dist",
"paths": {
"utils/*": ["./src/utils/*"],
"utils": ["./src/utils"]
},
"declaration": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"lib": ["es5", "dom"],
"mapRoot": "./",
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5",
"rootDirs": ["./dist", "."]
},
"exclude": ["./node_modules", "./dist", "**/*.d.ts"],
"include": ["./src/**/*.ts"]
}
Can anyone help me out with this? I'm decent with Typescript but pretty new to Karma. I've been scouring documentation for about 2 days now trying to get these simple unit tests running, but to no avail. Not with the way I've got my paths structured at least. Any help would be appreciated!
UPDATE: I tried updating my local installation of Typescript to 2.2.2, to match the Karma-Typescript's version which is also 2.2.2. Same error, same scenario - my local version compiles fine, but the Karma-Typescript version balks.
There's a tiny error in the Karma config, the compilerOptions
and tsconfig
properties should be inside the karmaTypescriptConfig
property.
Given your project structure example, here's a minimal working configuration example for both tsc
and karma-typescript
:
Karma.conf.js
module.exports = function(config) {
config.set({
frameworks: ["jasmine", "karma-typescript"],
files: [
{ pattern: "src/**/*.ts" }
],
karmaTypescriptConfig: {
compilerOptions: {
module: "commonjs"
},
tsconfig: "./tsconfig.json",
},
preprocessors: {
"**/*.ts": ["karma-typescript"]
},
reporters: ["progress", "kjhtml", "spec", "karma-typescript"],
browsers: ["Chrome"]
});
};
tsconfig.json
{
"compileOnSave": true,
"compilerOptions": {
"baseUrl": ".",
"outDir": "./dist",
"paths": {
"utils/*": ["./src/utils/*"],
"utils": ["./src/utils"]
},
"module": "es6",
"moduleResolution": "node",
"sourceMap": true,
"target": "es5"
}
}
I tested this using [email protected]
and [email protected]
.
Also, please note that karma-typescript
only has Typescript as a dev dependency, letting you use any Typescript version from 1.6.2 and up :)
I had an error Error: Unable to resolve module [...] from [...]
because of my custom module paths in tsconfig.json
. And this is my solution for that problem:
// tsconfig.json
"compilerOptions" {
...
"paths": { // My custom module path
"parchment/blot/*": ["node_modules/parchment/dist/src/blot/*"],
"parchment/attributor/*": ["node_modules/parchment/dist/src/attributor/*"]
},
...
// karma.conf.js
...
karmaTypescriptConfig: {
tsconfig: './tsconfig.json',
bundlerOptions: {
resolve: {
alias: {
'parchment/dist/src/attributor': './node_modules/parchment/dist/parchment.js',
'parchment/dist/src/blot/abstract': './node_modules/parchment/dist/parchment.js'
},
extensions: ['.js'] // Extension that causes the error
}
}
}
...
As you see, bundlerOptions.resolve
is the key to the solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With