From 37a6aa644c1572320c0d65b00bfa59f3935e87ab Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Fri, 5 Nov 2021 16:04:50 +0100 Subject: [PATCH 1/2] Scripts: Add TypeScript for builds and tests --- package-lock.json | 115 ++++++++++++++++++-- package.json | 2 +- packages/create-block/package.json | 2 +- packages/jest-preset-default/README.md | 2 +- packages/jest-preset-default/jest-preset.js | 8 +- packages/scripts/config/jest-e2e.config.js | 4 +- packages/scripts/config/jest-unit.config.js | 2 +- packages/scripts/config/webpack.config.js | 28 +++-- packages/scripts/package.json | 1 + 9 files changed, 129 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 72fb571fa2214..f3642bb61faa3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18954,7 +18954,7 @@ "check-node-version": "^4.1.0", "commander": "^4.1.0", "execa": "^4.0.2", - "fast-glob": "^2.2.7", + "fast-glob": "^3.2.7", "inquirer": "^7.1.0", "lodash": "^4.17.21", "make-dir": "^3.0.0", @@ -19719,6 +19719,7 @@ "eslint": "^7.17.0", "eslint-plugin-markdown": "^2.2.0", "expect-puppeteer": "^4.4.0", + "fast-glob": "^3.2.7", "filenamify": "^4.2.0", "jest": "^26.6.3", "jest-circus": "^26.6.3", @@ -37050,17 +37051,97 @@ "dev": true }, "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.7.tgz", + "integrity": "sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==", "dev": true, "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.4" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "micromatch": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", + "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "dev": true, + "requires": { + "braces": "^3.0.1", + "picomatch": "^2.2.3" + } + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } } }, "fast-json-parse": { @@ -38806,6 +38887,20 @@ "path-type": "^3.0.0" } }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, "glob": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.5.tgz", diff --git a/package.json b/package.json index 6678a8451516b..9e377c74de44a 100644 --- a/package.json +++ b/package.json @@ -169,7 +169,7 @@ "eslint-plugin-eslint-comments": "3.1.2", "eslint-plugin-import": "2.23.4", "execa": "4.0.2", - "fast-glob": "2.2.7", + "fast-glob": "3.2.7", "glob": "7.1.2", "husky": "7.0.0", "inquirer": "7.1.0", diff --git a/packages/create-block/package.json b/packages/create-block/package.json index 4115fbf5d5a9e..fb549db04e688 100644 --- a/packages/create-block/package.json +++ b/packages/create-block/package.json @@ -36,7 +36,7 @@ "check-node-version": "^4.1.0", "commander": "^4.1.0", "execa": "^4.0.2", - "fast-glob": "^2.2.7", + "fast-glob": "^3.2.7", "inquirer": "^7.1.0", "lodash": "^4.17.21", "make-dir": "^3.0.0", diff --git a/packages/jest-preset-default/README.md b/packages/jest-preset-default/README.md index 245734b913657..fc1e7a024fdb8 100644 --- a/packages/jest-preset-default/README.md +++ b/packages/jest-preset-default/README.md @@ -31,7 +31,7 @@ npm install @wordpress/jest-preset-default --save-dev - `setupFiles` - runs code before each test which sets up global variables required in the testing environment. - `setupFilesAfterEnv` - runs code which adds improved support for `Console` object and `React` components to the testing framework before each test. - `snapshotSerializers` - makes it possible to use snapshot tests on `Enzyme` wrappers. -- `testMatch`- includes `/test/` subfolder in addition to the glob patterns Jest uses to detect test files. It detects only test files containing `.js` (or `.ts`) suffix. It doesn't match files with `.spec.js` suffix. +- `testMatch`- includes `/test/` subfolder in addition to the glob patterns Jest uses to detect test files. It detects only test files containing `.js`, `.jsx`, `.ts` and `.tsx` suffix. It doesn't match files with `.spec.js` suffix. - `timers` - use of [fake timers](https://jestjs.io/docs/en/timer-mocks.html) for functions such as `setTimeout` is enabled. - `transform` - keeps the default [babel-jest](https://github.com/facebook/jest/tree/HEAD/packages/babel-jest) transformer. - `verbose` - each individual test won't be reported during the run. diff --git a/packages/jest-preset-default/jest-preset.js b/packages/jest-preset-default/jest-preset.js index 5dc0277f2d88e..cdf8a1bcc170f 100644 --- a/packages/jest-preset-default/jest-preset.js +++ b/packages/jest-preset-default/jest-preset.js @@ -17,13 +17,13 @@ module.exports = { ], snapshotSerializers: [ require.resolve( 'enzyme-to-json/serializer.js' ) ], testMatch: [ - '**/__tests__/**/*.[jt]s', - '**/test/*.[jt]s', - '**/?(*.)test.[jt]s', + '**/__tests__/**/*.[jt]s?(x)', + '**/test/*.[jt]s?(x)', + '**/?(*.)test.[jt]s?(x)', ], testPathIgnorePatterns: [ '/node_modules/', '/vendor/' ], timers: 'fake', transform: { - '^.+\\.[jt]sx?$': require.resolve( 'babel-jest' ), + '\\.[jt]sx?$': require.resolve( 'babel-jest' ), }, }; diff --git a/packages/scripts/config/jest-e2e.config.js b/packages/scripts/config/jest-e2e.config.js index 93f2f712b4019..8d87faa553b29 100644 --- a/packages/scripts/config/jest-e2e.config.js +++ b/packages/scripts/config/jest-e2e.config.js @@ -21,7 +21,7 @@ const jestE2EConfig = { ], setupFilesAfterEnv: [ 'expect-puppeteer' ], testEnvironment: path.join( __dirname, 'jest-environment-puppeteer' ), - testMatch: [ '**/specs/**/*.[jt]s', '**/?(*.)spec.[jt]s' ], + testMatch: [ '**/specs/**/*.[jt]s?(x)', '**/?(*.)spec.[jt]s?(x)' ], testPathIgnorePatterns: [ '/node_modules/' ], testRunner: 'jest-circus/runner', testTimeout: 30000, @@ -29,7 +29,7 @@ const jestE2EConfig = { if ( ! hasBabelConfig() ) { jestE2EConfig.transform = { - '^.+\\.[jt]sx?$': path.join( __dirname, 'babel-transform' ), + '\\.[jt]sx?$': path.join( __dirname, 'babel-transform' ), }; } diff --git a/packages/scripts/config/jest-unit.config.js b/packages/scripts/config/jest-unit.config.js index a6228f60b02d5..22be3e4a39e02 100644 --- a/packages/scripts/config/jest-unit.config.js +++ b/packages/scripts/config/jest-unit.config.js @@ -19,7 +19,7 @@ const jestUnitConfig = { if ( ! hasBabelConfig() ) { jestUnitConfig.transform = { - '^.+\\.[jt]sx?$': path.join( __dirname, 'babel-transform' ), + '\\.[jt]sx?$': path.join( __dirname, 'babel-transform' ), }; } diff --git a/packages/scripts/config/webpack.config.js b/packages/scripts/config/webpack.config.js index d4f7730ba7cb2..d745b874f936a 100644 --- a/packages/scripts/config/webpack.config.js +++ b/packages/scripts/config/webpack.config.js @@ -7,7 +7,7 @@ const MiniCSSExtractPlugin = require( 'mini-css-extract-plugin' ); const TerserPlugin = require( 'terser-webpack-plugin' ); const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' ); const browserslist = require( 'browserslist' ); -const fs = require( 'fs' ); +const { sync: glob } = require( 'fast-glob' ); const path = require( 'path' ); /** @@ -36,17 +36,14 @@ let entry = {}; if ( process.env.WP_ENTRY ) { entry = JSON.parse( process.env.WP_ENTRY ); } else { - // By default the script checks if `src/index.js` exists and sets it as an entry point. - // In the future we should add similar handling for `src/script.js` and `src/view.js`. - [ 'index' ].forEach( ( entryName ) => { - const filepath = path.resolve( - process.cwd(), - 'src', - `${ entryName }.js` - ); - if ( fs.existsSync( filepath ) ) { - entry[ entryName ] = filepath; - } + // The script checks whether standard file names can be detected in the `src` folder, + // and converts all found files to entry points. + const entryFiles = glob( 'src/index.[jt]s?(x)', { + absolute: true, + } ); + entryFiles.forEach( ( filepath ) => { + const [ entryName ] = path.basename( filepath ).split( '.' ); + entry[ entryName ] = filepath; } ); } @@ -115,6 +112,7 @@ const config = { alias: { 'lodash-es': 'lodash', }, + extensions: [ '.ts', '.tsx', '...' ], }, optimization: { // Only concatenate modules in production, when not analyzing bundles. @@ -155,7 +153,7 @@ const config = { module: { rules: [ { - test: /\.jsx?$/, + test: /\.(j|t)sx?$/, exclude: /node_modules/, use: [ { @@ -200,7 +198,7 @@ const config = { }, { test: /\.svg$/, - issuer: /\.jsx?$/, + issuer: /\.(j|t)sx?$/, use: [ '@svgr/webpack', 'url-loader' ], type: 'javascript/auto', }, @@ -259,7 +257,7 @@ if ( ! isProduction ) { // See: https://webpack.js.org/configuration/devtool/#devtool. config.devtool = process.env.WP_DEVTOOL || 'source-map'; config.module.rules.unshift( { - test: /\.js$/, + test: /\.(j|t)sx?$/, exclude: [ /node_modules/ ], use: require.resolve( 'source-map-loader' ), enforce: 'pre', diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 5214f7f3dc93a..8e21b5fae4ac2 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -56,6 +56,7 @@ "eslint": "^7.17.0", "eslint-plugin-markdown": "^2.2.0", "expect-puppeteer": "^4.4.0", + "fast-glob": "^3.2.7", "filenamify": "^4.2.0", "jest": "^26.6.3", "jest-circus": "^26.6.3", From 57753fc143fe494edab1075205ba3d4cf3a36c77 Mon Sep 17 00:00:00 2001 From: Grzegorz Ziolkowski Date: Mon, 8 Nov 2021 15:37:42 +0100 Subject: [PATCH 2/2] Scripts: Add documentation for improved TS support --- packages/jest-preset-default/CHANGELOG.md | 4 ++++ packages/scripts/CHANGELOG.md | 4 ++++ packages/scripts/README.md | 22 +++++++++++----------- 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/packages/jest-preset-default/CHANGELOG.md b/packages/jest-preset-default/CHANGELOG.md index 5d68d2b9d3f1b..29df66d9ef3df 100644 --- a/packages/jest-preset-default/CHANGELOG.md +++ b/packages/jest-preset-default/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Bug Fix + +- Improve support for test files with `.jsx` and `.tsx` extensions ([#36260](https://github.com/WordPress/gutenberg/pull/36260)). + ## 7.1.2 (2021-10-22) ### Bug Fix diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index 779c931df5171..35a90f37b9a92 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -14,6 +14,10 @@ - The webpack config was updated to no longer include the polyfill by default when creating the `assets.php` file. If your usage requires the `wp-polyfill`, you must explicitly set it as a dependency ([#34536](https://github.com/WordPress/gutenberg/pull/35436)]. +### New Features + +- Add basic support for TypeScript in `build`, `start`, `test-e2e` and `test-unit-js` commands ([#36260](https://github.com/WordPress/gutenberg/pull/36260)). + ### Enhancements - Allow customization of the `ARTIFACTS_PATH` in the `jest-environment-puppeteer` failed test reporter via the `WP_ARTIFACTS_PATH` environment variable ([#35371](https://github.com/WordPress/gutenberg/pull/35371)). diff --git a/packages/scripts/README.md b/packages/scripts/README.md index 39fe366e8c97f..67fa682186d1e 100644 --- a/packages/scripts/README.md +++ b/packages/scripts/README.md @@ -58,7 +58,7 @@ We commit to keeping the breaking changes minimal so you can upgrade `@wordpress ### `build` -Transforms your code according the configuration provided so it’s ready for production and optimized for the best performance. The entry point for your project’s code should be located in `src/index.js`. The output generated will be written to `build/index.js`. This script exits after producing a single build. For incremental builds, better suited for development, see the [start](#start) script. +Transforms your code according the configuration provided so it’s ready for production and optimized for the best performance. The entry point for your project’s code should be located in `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`). The output generated will be written to `build/index.js`. This script exits after producing a single build. For incremental builds, better suited for development, see the [start](#start) script. _Example:_ @@ -154,7 +154,7 @@ By default, files located in `build`, `node_modules`, and `vendor` folders are i ### `lint-js` -Helps enforce coding style guidelines for your JavaScript files. +Helps enforce coding style guidelines for your JavaScript and TypeScript files. _Example:_ @@ -169,8 +169,8 @@ _Example:_ This is how you execute the script with presented setup: -- `npm run lint:js` - lints JavaScript files in the entire project’s directories. -- `npm run lint:js:src` - lints JavaScript files in the project’s `src` subfolder’s directories. +- `npm run lint:js` - lints JavaScript and TypeScript files in the entire project’s directories. +- `npm run lint:js:src` - lints JavaScript and TypeScript files in the project’s `src` subfolder’s directories. When you run commands similar to the `npm run lint:js:src` example above, you can provide a file, a directory, or `glob` syntax or any combination of them. See [more examples](https://eslint.org/docs/user-guide/command-line-interface). @@ -305,7 +305,7 @@ The command checks which packages whose name starts with `@wordpress/` are used ### `start` -Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console. The entry point for your project’s code should be located in `src/index.js`. The output generated will be written to `build/index.js`. For single builds, better suited for production, see the [build](#build) script. +Transforms your code according the configuration provided so it’s ready for development. The script will automatically rebuild if you make changes to the code, and you will see the build errors in the console. The entry point for your project’s code should be located in `src/index.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`). The output generated will be written to `build/index.js`. For single builds, better suited for production, see the [build](#build) script. _Example:_ @@ -364,8 +364,8 @@ This is how you execute those scripts using the presented setup: Jest will look for test files with any of the following popular naming conventions: -- Files with `.js` (or `.ts`) suffix at any level of depth in `spec` folders. -- Files with `.spec.js` (or `.spec.ts`) suffix. +- Files with `.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) suffix at any level of depth in `spec` folders. +- Files with `.spec.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) suffix. This script automatically detects the best config to start Puppeteer but sometimes you may need to specify custom options: @@ -417,9 +417,9 @@ This is how you execute those scripts using the presented setup: Jest will look for test files with any of the following popular naming conventions: -- Files with `.js` (or `.ts`) suffix located at any level of depth in `__tests__` folders. -- Files with `.js` (or `.ts`) suffix directly located in `test` folders. -- Files with `.test.js` (or `.test.ts`) suffix. +- Files with `.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) suffix located at any level of depth in `__tests__` folders. +- Files with `.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) suffix directly located in `test` folders. +- Files with `.test.js` (other supported extensions: `.jsx`, `.ts`, and `.tsx`) suffix. #### Advanced information @@ -498,7 +498,7 @@ The `build` and `start` commands use [webpack](https://webpack.js.org/) behind t - [Entry](https://webpack.js.org/configuration/entry-context/#entry): `src/index.js` - [Output](https://webpack.js.org/configuration/output): `build/index.js` - [Loaders](https://webpack.js.org/loaders/): - - [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) allows transpiling JavaScript files using Babel and webpack. + - [`babel-loader`](https://webpack.js.org/loaders/babel-loader/) allows transpiling JavaScript and TypeScript files using Babel and webpack. - [`@svgr/webpack`](https://www.npmjs.com/package/@svgr/webpack) and [`url-loader`](https://webpack.js.org/loaders/url-loader/) makes it possible to handle SVG files in JavaScript code. - [`css-loader`](https://webpack.js.org/loaders/css-loader/) chained with [`postcss-loader`](https://webpack.js.org/loaders/postcss-loader/) and [sass-loader](https://webpack.js.org/loaders/sass-loader/) let webpack process CSS, SASS or SCSS files referenced in JavaScript files. - [Plugins](https://webpack.js.org/configuration/plugins) (among others):