Karma plugin for running tests with es modules on a wide range of browsers.
Part of Open Web Components: guides, tools and libraries for modern web development and web components
Out the box es modules don't work with karma because they import their dependencies from the browser, while karma doesn't allow requesting any files it doesn't know about upfront.
es-dev-server takes care of loading the correct polyfills, and runs babel for older browsers if necessary. On browsers which don't support es modules, dynamic imports and/or import.meta.url, systemjs is used as a module polyfill.
See the es-dev-server docs for full details on how it works.
We recommend the testing-karma configuration for a good default karma setup which includes
karma-esm and many other good defaults.
To manually set up this plugin, add it as a karma framework:
- Install the plugin
npm i -D @open-wc/karma-esm
- Add to your karma config
moduleexports =// define where your test files are, make sure to set type to modulefiles:pattern: 'test/**/*.test.js' type: 'module'plugins:// load pluginrequire// fallback: resolve any karma- plugins'karma-*'frameworks: 'esm'esm:// if you are using 'bare module imports' you will need this optionnodeResolve: true
karma-esm can be configured with these options:
|nodeResolve||boolean||Transforms bare module imports using node resolve.|
|dedupe||boolean/array||Deduplicates all modules, or modules from specified packages if the value is an array|
|coverage||boolean||Whether to report test code coverage.|
|importMap||string||Path to import map used for testing.|
|compatibility||string||Compatibility level to run the
|coverageExclude||array||Extra glob patterns of tests to exclude from coverage.|
|babelConfig||string||Custom babel configuration file to run on served code.|
|moduleDirs||array||Directories to resolve modules from. Defaults to
|babel||boolean||Whether to pick up a babel configuration file in your project.|
|fileExtensions||array||Custom file extensions to serve as es modules.|
|polyfillsLoader||object||Configuration for the polyfills loader|
|devServerPort||number||Port of server that serves the modules. Note that this is not the karma port. Picks a random port if not set.|
Node resolve is necessary when you have 'bare imports' in your code and are not using import maps to resolve them.
import foo from 'bar' to:
import foo from './node_modules/bar/bar.js.
See the node-resolve documentation of es-dev-server for more information.
Deduplicate packages, ensuring only one version of a package is resolved.
See the dedupe documentation of es-dev-server for more information.
Due to a bug in karma, the test coverage reporter causes browser logs to appear twice which can be annoying
Allows to control the behavior of ES imports according to the (in progress) spec.
Since this feature is not enabled by default, is necessary to launch Chrome with
In karma.config.js add:
customLaunchers:ChromeHeadlessNoSandbox:base: 'ChromeHeadless'flags:'--no-sandbox' //default karma-esm configuration'--disable-setuid-sandbox' //default karma-esm configuration'--enable-experimental-web-platform-features' // necessary when using importMap option
The compatibility option makes your code compatible with older browsers. It loads polyfills and transforms modern syntax where needed.
See the compatibility documentation of es-dev-server for more information.
es-dev-server by default resolves the symlinks in the dependency directory. This can cause problem when you're using
npm link command or other tools which rely on them. This option will make
es-dev-server preserve symlinks.
Unfortunately, to make karma work with es modules regular karma preprocessors no longer work. You can, however, configure the
es-dev-server to do code transformations if needed.
Custom babel plugins
You can configure
karma-esm to pick up the babel configuration files in your project:
tsc in watch mode and include the compiled js files from your karma config.
You can also configure
Note that when compiling typescript with babel it does not do any type checking or special typescript compilation such as decorators, class fields and enums. You can configure babel to cover most of these, but not all. Read more about babel typescript here.
- Install the preset:
npm i --save-dev @babel/preset-typescript
- Add a
.babelrcto your project:
- Configure your karma config to pick up your ts files:
files:pattern: 'test/**/*.test.ts' type: 'module'esm:babel: truenodeResolve: truefileExtensions: '.ts'
To add support for experimental features that are normally handled by the typescript compiler, you can add extra plugins:
- Install the plugins:
npm i --save-dev @babel/plugin-proposal-decorators @babel/plugin-proposal-class-properties
- Update your babel configuration: