Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: ability to read tests in ".jsx" and ".tsx" files #851

Merged
merged 1 commit into from
Mar 21, 2024

Conversation

DudaGod
Copy link
Member

@DudaGod DudaGod commented Feb 29, 2024

What is done

Added ability to read tests in .jsx and .tsx files. To do this, it was necessary to add a code transpiler - babel. Used in order to convert components like <h1>foo</h1> to code which can be required.

In this PR supports only commonjs because esm projects not working with Hermione at the moment.

@@ -1619,8 +1619,6 @@ Using `-r` or `--require` option you can load external modules, which exists in
- compilers such as TypeScript via [ts-node](https://www.npmjs.com/package/ts-node) (using `--require ts-node/register`) or Babel via [@babel/register](https://www.npmjs.com/package/@babel/register) (using `--require @babel/register`);
- loaders such as ECMAScript modules via [esm](https://www.npmjs.com/package/esm).

Be sure to update [fileExtensions](#fileExtensions) apropriately, if you are planning to import anything other than `.js`.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deleted because it doesn't make sense anymore

package.json Outdated
"@babel/core": "7.24.0",
"@babel/plugin-transform-modules-commonjs": "7.23.3",
"@babel/plugin-transform-react-jsx": "7.23.4",
"@babel/preset-react": "7.23.3",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used in order to correctly transpile jsx and tsx to code which can be required

package.json Outdated
@@ -66,6 +70,7 @@
"looks-same": "9.0.0",
"micromatch": "4.0.5",
"mocha": "10.2.0",
"pirates": "4.0.6",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used in order to add hook which can modify default require in order to traspile code in runtime

browserslistConfigFile: false,
babelrc: false,
configFile: false,
compact: false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order not to make unnecessary code inside babel

compact: false,
plugins: [
[
require("@babel/plugin-transform-react-jsx"),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

transform components to readable code by require or import

require("@babel/plugin-transform-react-jsx"),
{
throwIfNamespace: false,
runtime: "automatic",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adds import for react even if it doesn't specified in file with component

[
require("@babel/plugin-transform-react-jsx"),
{
throwIfNamespace: false,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

runtime: "automatic",
},
],
require("@babel/plugin-transform-modules-commonjs"),
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in order to modify imports to requires

visitor: {
ImportDeclaration(path: NodePath<ImportDeclaration>): void {
if (path.node.source.value.match(/\.(css|less|scss)$/)) {
path.remove();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In order to remove css imports. I don't find solution how to transpile them, so I remove them because we need only read tests and not execute in nodejs (will be executed in browser in next PR)

@DudaGod DudaGod force-pushed the HERMIONE-1420.read_jsx_tsx branch 3 times, most recently from 663111e to 52ae8d2 Compare February 29, 2024 13:09
@DudaGod DudaGod changed the base branch from master to component_testing March 19, 2024 11:00
@DudaGod DudaGod force-pushed the HERMIONE-1420.read_jsx_tsx branch 2 times, most recently from a3eebf6 to f06ff9c Compare March 19, 2024 16:47
@@ -8,7 +8,8 @@
"typings"
],
"scripts": {
"build": "tsc && npm run copy-static",
"build": "tsc && npm run copy-static && npm run build-bundle -- --minify",
"build-bundle": "esbuild ./src/bundle/index.ts --outdir=./build/src/bundle --bundle --format=cjs --platform=node --target=ES2021",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I build a bundle in order to not install all heavy babel deps in dependencies

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add it to the watch script as well.

In watch script, we can either build the bundle once on startup, or make 2 separate scripts like watch:bundle watch:src and unite them in watch script via concurrently (we use the same approach in html-reporter).

I'm not sure how often we'll want to change (watch) bundle contents, so it's up to you to decide.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think about it, but it seemed to me that this file would rarely change. Anyway I add it to watch script.

@@ -107,6 +115,7 @@
"jsdom": "^24.0.0",
"jsdom-global": "3.0.2",
"onchange": "7.1.0",
"pirates": "4.0.6",
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all deps installed in dev deps and used only through bundle

@@ -0,0 +1,2 @@
export const TRANSFORM_EXTENSIONS = [".jsx", ".cjsx", ".mjsx", ".tsx", ".ctsx", ".mtsx"];
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

extensions which should be transformed. I took various types of dependencies in which components can be described from this site - https://www.totaltypescript.com/concepts/mjs-cjs-mts-and-cts-extensions.

@@ -0,0 +1,2 @@
export const TRANSFORM_EXTENSIONS = [".jsx", ".cjsx", ".mjsx", ".tsx", ".ctsx", ".mtsx"];
export const JS_EXTENSION_RE = /^\.([cm]?[tj]sx?|json)$/;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

used in order to transform only javascript files and json. Omit all other extensions like .png, .woff, .css and etc.

const extname = nodePath.extname(path.node.source.value);

if (extname && !extname.match(JS_EXTENSION_RE)) {
path.remove();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here omit imports like .css and others which can be transformed

@@ -1,7 +1,7 @@
{
"extends": "./tsconfig.common.json",
"include": ["src"],
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts"],
"exclude": ["src/**/__*", "src/**/*.test.ts", "src/browser/client-scripts", "src/bundle"],
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

src/bundle should not be build by typescript. I build it using esbuild

@@ -0,0 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
export const setupTransformHook: () => VoidFunction = require("../bundle").setupTransformHook;
export const TRANSFORM_EXTENSIONS: string[] = require("../bundle").TRANSFORM_EXTENSIONS;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I use require in order to ts not understand that folder bundle should be builded. If I use import tsc build it even if exclude it in tsconfig

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding this comment to the code as well.

To me it seems like typescript's project references would allow the use of imports here, but don't include those files in build. But probably not worth spending time on this right now, maybe just leave a todo in the comment.

Copy link
Member

@shadowusr shadowusr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great additions overall! =)

@@ -8,7 +8,8 @@
"typings"
],
"scripts": {
"build": "tsc && npm run copy-static",
"build": "tsc && npm run copy-static && npm run build-bundle -- --minify",
"build-bundle": "esbuild ./src/bundle/index.ts --outdir=./build/src/bundle --bundle --format=cjs --platform=node --target=ES2021",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should add it to the watch script as well.

In watch script, we can either build the bundle once on startup, or make 2 separate scripts like watch:bundle watch:src and unite them in watch script via concurrently (we use the same approach in html-reporter).

I'm not sure how often we'll want to change (watch) bundle contents, so it's up to you to decide.

@@ -0,0 +1,3 @@
/* eslint-disable @typescript-eslint/no-var-requires */
export const setupTransformHook: () => VoidFunction = require("../bundle").setupTransformHook;
export const TRANSFORM_EXTENSIONS: string[] = require("../bundle").TRANSFORM_EXTENSIONS;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest adding this comment to the code as well.

To me it seems like typescript's project references would allow the use of imports here, but don't include those files in build. But probably not worth spending time on this right now, maybe just leave a todo in the comment.

@DudaGod DudaGod merged commit 578a599 into component_testing Mar 21, 2024
2 checks passed
@DudaGod DudaGod deleted the HERMIONE-1420.read_jsx_tsx branch March 21, 2024 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants