babel - Using Jest with Typescript + preact -
problem transpiling jsx h() in tests. config files similar create-react-app, exclude changes typescript , preact
i create app via create-react-app my-app --script=react-scripts-ts - typescript project. eject , change react preact (don't use preact-compat).
for migrating preact i'm add package.json babel.plugins section new plugin ["babel-plugin-transform-react-jsx", { pragma: "h"}] - transpiling <jsx /> h(jsx) function calls, instead default react.createelement(jsx) (migration guide https://preactjs.com/guide/switching-to-preact).
and works fine.
but test has different configuration of transpiling <jsx />: it's transpile react.createelement(jsx) default. , in test take error referenceerror: react not defined @ object.<anonymous> (src/linkify/linkify.test.tsx:39:21). if manually change <jsx /> h(somecomponent) in test , tested file - work.
how transpile <jsx /> h(jsx) tests?
// typescripttransform.js // copyright 2004-present facebook. rights reserved. 'use strict'; const fs = require('fs'); const crypto = require('crypto'); const tsc = require('typescript'); const tsconfigpath = require('app-root-path').resolve('/tsconfig.json'); const this_file = fs.readfilesync(__filename); let compilerconfig = { module: tsc.modulekind.commonjs, jsx: tsc.jsxemit.react, }; if (fs.existssync(tsconfigpath)) { try { const tsconfig = tsc.readconfigfile(tsconfigpath).config; if (tsconfig && tsconfig.compileroptions) { compilerconfig = tsconfig.compileroptions; } } catch (e) { /* nothing - default set */ } } module.exports = { process(src, path, config, options) { if (path.endswith('.ts') || path.endswith('.tsx')) { let compileroptions = compilerconfig; if (options.instrument) { // inline source source map remapping coverage compileroptions = object.assign({}, compilerconfig); delete compileroptions.sourcemap; compileroptions.inlinesourcemap = true; compileroptions.inlinesources = true; // fix broken paths in coverage report if `.outdir` set delete compileroptions.outdir; } const tstranspiled = tsc.transpilemodule(src, { compileroptions: compileroptions, filename: path, }); return tstranspiled.outputtext; } return src; }, getcachekey(filedata, filepath, configstr, options) { return crypto .createhash('md5') .update(this_file) .update('\0', 'utf8') .update(filedata) .update('\0', 'utf8') .update(filepath) .update('\0', 'utf8') .update(configstr) .update('\0', 'utf8') .update(json.stringify(compilerconfig)) .update('\0', 'utf8') .update(options.instrument ? 'instrument' : '') .digest('hex'); }, }; test sample:
import { h, render } 'preact'; import linkify './linkify'; it('renders without crashing', () => { const div = document.createelement('div'); render(<linkify children={'text'} />, div); });
i found solution.
i wrong in babel.plugins section new plugin ["babel-plugin-transform-react-jsx", { pragma: "h"}] - it's not using. pragma uses tsconfig.json - "jsxfactory": "h"
however directive don't uses in typescripttransform.js.
i'm extend compiler options
let compilerconfig = { module: tsc.modulekind.commonjs, jsx: tsc.jsxemit.react, jsxfactory: "h" // <-- duplicate option in jest transform config file }; hope useful.
Comments
Post a Comment