From 4bc94d1bc8fe00f2bd052a4e29354184cb713835 Mon Sep 17 00:00:00 2001 From: Haoqun Jiang Date: Wed, 6 Dec 2023 01:09:56 +0800 Subject: [PATCH] feat: use type=module in (most) generated projects MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit With the exception of Nighwatch templates due to https://github.com/nightwatchjs/nightwatch/issues/3959 Closes #389 Largely inspired by @cexbrayat's work in that PR. I've also made the generation of the root `tsconfig.json` programmatic because it's becoming more and more convoluted. Co-authored-by: Cédric Exbrayat --- index.ts | 43 ++++++- template/base/package.json | 1 + template/config/cypress-ct/cypress.config.js | 4 +- template/config/cypress-ct/cypress.config.ts | 15 --- template/config/cypress/cypress.config.js | 4 +- template/config/cypress/cypress.config.ts | 8 -- template/config/nightwatch/package.json | 3 +- template/config/playwright/e2e/vue.spec.js | 2 +- .../config/playwright/playwright.config.js | 13 +- .../config/playwright/playwright.config.ts | 112 ------------------ template/tsconfig/base/tsconfig.json | 11 -- template/tsconfig/cypress-ct/tsconfig.json | 14 --- template/tsconfig/nightwatch-ct/tsconfig.json | 14 --- template/tsconfig/nightwatch/tsconfig.json | 17 --- template/tsconfig/vitest/tsconfig.json | 14 --- utils/filterList.ts | 1 - 16 files changed, 54 insertions(+), 222 deletions(-) delete mode 100644 template/config/cypress-ct/cypress.config.ts delete mode 100644 template/config/cypress/cypress.config.ts delete mode 100644 template/config/playwright/playwright.config.ts delete mode 100644 template/tsconfig/base/tsconfig.json delete mode 100644 template/tsconfig/cypress-ct/tsconfig.json delete mode 100644 template/tsconfig/nightwatch-ct/tsconfig.json delete mode 100644 template/tsconfig/nightwatch/tsconfig.json delete mode 100644 template/tsconfig/vitest/tsconfig.json delete mode 100644 utils/filterList.ts diff --git a/index.ts b/index.ts index 38b9598f..b04c20e9 100755 --- a/index.ts +++ b/index.ts @@ -17,7 +17,6 @@ import generateReadme from './utils/generateReadme' import getCommand from './utils/getCommand' import getLanguage from './utils/getLanguage' import renderEslint from './utils/renderEslint' -import { FILES_TO_FILTER } from './utils/filterList' function isValidPackageName(projectName) { return /^(?:@[a-z0-9-*~][a-z0-9-*._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/.test(projectName) @@ -371,24 +370,64 @@ async function init() { // Render tsconfigs render('tsconfig/base') + // The content of the root `tsconfig.json` is a bit complicated, + // So here we are programmatically generating it. + const rootTsConfig = { + // It doesn't target any specific files because they are all configured in the referenced ones. + files: [], + // All templates contain at least a `.node` and a `.app` tsconfig. + references: [ + { + path: './tsconfig.node.json' + }, + { + path: './tsconfig.app.json' + } + ] + } if (needsCypress) { render('tsconfig/cypress') + // Cypress uses `ts-node` internally, which doesn't support solution-style tsconfig. + // So we have to set a dummy `compilerOptions` in the root tsconfig to make it work. + // I use `NodeNext` here instead of `ES2015` because that's what the actual environment is. + // (Cypress uses the ts-node/esm loader when `type: module` is specified in package.json.) + // @ts-ignore + rootTsConfig.compilerOptions = { + module: 'NodeNext' + } } if (needsCypressCT) { render('tsconfig/cypress-ct') + // Cypress Component Testing needs a standalone tsconfig. + rootTsConfig.references.push({ + path: './tsconfig.cypress-ct.json' + }) } if (needsPlaywright) { render('tsconfig/playwright') } if (needsVitest) { render('tsconfig/vitest') + // Vitest needs a standalone tsconfig. + rootTsConfig.references.push({ + path: './tsconfig.vitest.json' + }) } if (needsNightwatch) { render('tsconfig/nightwatch') + // Nightwatch needs a standalone tsconfig, but in a different folder. + rootTsConfig.references.push({ + path: './nightwatch/tsconfig.json' + }) } if (needsNightwatchCT) { render('tsconfig/nightwatch-ct') } + fs.writeFileSync( + path.resolve(root, 'tsconfig.json'), + JSON.stringify(rootTsConfig, null, 2) + '\n', + 'utf-8' + ) } // Render ESLint config @@ -456,7 +495,7 @@ async function init() { root, () => {}, (filepath) => { - if (filepath.endsWith('.js') && !FILES_TO_FILTER.includes(path.basename(filepath))) { + if (filepath.endsWith('.js')) { const tsFilePath = filepath.replace(/\.js$/, '.ts') if (fs.existsSync(tsFilePath)) { fs.unlinkSync(filepath) diff --git a/template/base/package.json b/template/base/package.json index c1005ec5..488db45a 100644 --- a/template/base/package.json +++ b/template/base/package.json @@ -1,5 +1,6 @@ { "private": true, + "type": "module", "scripts": { "dev": "vite", "build": "vite build", diff --git a/template/config/cypress-ct/cypress.config.js b/template/config/cypress-ct/cypress.config.js index c3aba743..c8fac129 100644 --- a/template/config/cypress-ct/cypress.config.js +++ b/template/config/cypress-ct/cypress.config.js @@ -1,6 +1,6 @@ -const { defineConfig } = require('cypress') +import { defineConfig } from 'cypress' -module.exports = defineConfig({ +export default defineConfig({ e2e: { specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}', baseUrl: 'http://localhost:4173' diff --git a/template/config/cypress-ct/cypress.config.ts b/template/config/cypress-ct/cypress.config.ts deleted file mode 100644 index c8fac129..00000000 --- a/template/config/cypress-ct/cypress.config.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { defineConfig } from 'cypress' - -export default defineConfig({ - e2e: { - specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}', - baseUrl: 'http://localhost:4173' - }, - component: { - specPattern: 'src/**/__tests__/*.{cy,spec}.{js,ts,jsx,tsx}', - devServer: { - framework: 'vue', - bundler: 'vite' - } - } -}) diff --git a/template/config/cypress/cypress.config.js b/template/config/cypress/cypress.config.js index 9cf6a199..0f66080f 100644 --- a/template/config/cypress/cypress.config.js +++ b/template/config/cypress/cypress.config.js @@ -1,6 +1,6 @@ -const { defineConfig } = require('cypress') +import { defineConfig } from 'cypress' -module.exports = defineConfig({ +export default defineConfig({ e2e: { specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}', baseUrl: 'http://localhost:4173' diff --git a/template/config/cypress/cypress.config.ts b/template/config/cypress/cypress.config.ts deleted file mode 100644 index 0f66080f..00000000 --- a/template/config/cypress/cypress.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { defineConfig } from 'cypress' - -export default defineConfig({ - e2e: { - specPattern: 'cypress/e2e/**/*.{cy,spec}.{js,jsx,ts,tsx}', - baseUrl: 'http://localhost:4173' - } -}) diff --git a/template/config/nightwatch/package.json b/template/config/nightwatch/package.json index 0c3b4727..0659adfd 100644 --- a/template/config/nightwatch/package.json +++ b/template/config/nightwatch/package.json @@ -1,10 +1,11 @@ { + "type": "commonjs", "scripts": { "test:e2e": "nightwatch tests/e2e/*" }, "devDependencies": { "nightwatch": "^3.3.2", - "@nightwatch/vue": "0.4.5", + "@nightwatch/vue": "^0.4.5", "@vitejs/plugin-vue": "^4.5.1", "@types/nightwatch": "^2.3.30", "geckodriver": "^4.2.1", diff --git a/template/config/playwright/e2e/vue.spec.js b/template/config/playwright/e2e/vue.spec.js index 3d62e3e5..3e5a3d02 100644 --- a/template/config/playwright/e2e/vue.spec.js +++ b/template/config/playwright/e2e/vue.spec.js @@ -1,4 +1,4 @@ -const { test, expect } = require('@playwright/test'); +import { test, expect } from '@playwright/test'; // See here how to get started: // https://playwright.dev/docs/intro diff --git a/template/config/playwright/playwright.config.js b/template/config/playwright/playwright.config.js index 1c1ea7cc..ad20dabc 100644 --- a/template/config/playwright/playwright.config.js +++ b/template/config/playwright/playwright.config.js @@ -1,5 +1,4 @@ -// @ts-check -const { devices } = require('@playwright/test') +import { defineConfig, devices } from '@playwright/test' /** * Read environment variables from file. @@ -8,10 +7,9 @@ const { devices } = require('@playwright/test') // require('dotenv').config(); /** - * @see https://playwright.dev/docs/test-configuration - * @type {import('@playwright/test').PlaywrightTestConfig} + * See https://playwright.dev/docs/test-configuration. */ -const config = { +export default defineConfig({ testDir: './e2e', /* Maximum time one test can run for. */ timeout: 30 * 1000, @@ -102,11 +100,10 @@ const config = { /** * Use the dev server by default for faster feedback loop. * Use the preview server on CI for more realistic testing. + * Playwright will re-use the local server if there is already a dev-server running. */ command: process.env.CI ? 'vite preview --port 5173' : 'vite dev', port: 5173, reuseExistingServer: !process.env.CI } -} - -module.exports = config +}) diff --git a/template/config/playwright/playwright.config.ts b/template/config/playwright/playwright.config.ts deleted file mode 100644 index 333a4dc0..00000000 --- a/template/config/playwright/playwright.config.ts +++ /dev/null @@ -1,112 +0,0 @@ -import type { PlaywrightTestConfig } from '@playwright/test' -import { devices } from '@playwright/test' - -/** - * Read environment variables from file. - * https://github.com/motdotla/dotenv - */ -// require('dotenv').config(); - -/** - * See https://playwright.dev/docs/test-configuration. - */ -const config: PlaywrightTestConfig = { - testDir: './e2e', - /* Maximum time one test can run for. */ - timeout: 30 * 1000, - expect: { - /** - * Maximum time expect() should wait for the condition to be met. - * For example in `await expect(locator).toHaveText();` - */ - timeout: 5000 - }, - /* Fail the build on CI if you accidentally left test.only in the source code. */ - forbidOnly: !!process.env.CI, - /* Retry on CI only */ - retries: process.env.CI ? 2 : 0, - /* Opt out of parallel tests on CI. */ - workers: process.env.CI ? 1 : undefined, - /* Reporter to use. See https://playwright.dev/docs/test-reporters */ - reporter: 'html', - /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ - use: { - /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */ - actionTimeout: 0, - /* Base URL to use in actions like `await page.goto('/')`. */ - baseURL: 'http://localhost:5173', - - /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ - trace: 'on-first-retry', - - /* Only on CI systems run the tests headless */ - headless: !!process.env.CI - }, - - /* Configure projects for major browsers */ - projects: [ - { - name: 'chromium', - use: { - ...devices['Desktop Chrome'] - } - }, - { - name: 'firefox', - use: { - ...devices['Desktop Firefox'] - } - }, - { - name: 'webkit', - use: { - ...devices['Desktop Safari'] - } - } - - /* Test against mobile viewports. */ - // { - // name: 'Mobile Chrome', - // use: { - // ...devices['Pixel 5'], - // }, - // }, - // { - // name: 'Mobile Safari', - // use: { - // ...devices['iPhone 12'], - // }, - // }, - - /* Test against branded browsers. */ - // { - // name: 'Microsoft Edge', - // use: { - // channel: 'msedge', - // }, - // }, - // { - // name: 'Google Chrome', - // use: { - // channel: 'chrome', - // }, - // }, - ], - - /* Folder for test artifacts such as screenshots, videos, traces, etc. */ - // outputDir: 'test-results/', - - /* Run your local dev server before starting the tests */ - webServer: { - /** - * Use the dev server by default for faster feedback loop. - * Use the preview server on CI for more realistic testing. - Playwright will re-use the local server if there is already a dev-server running. - */ - command: process.env.CI ? 'vite preview --port 5173' : 'vite dev', - port: 5173, - reuseExistingServer: !process.env.CI - } -} - -export default config diff --git a/template/tsconfig/base/tsconfig.json b/template/tsconfig/base/tsconfig.json deleted file mode 100644 index 66b5e570..00000000 --- a/template/tsconfig/base/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - } - ] -} diff --git a/template/tsconfig/cypress-ct/tsconfig.json b/template/tsconfig/cypress-ct/tsconfig.json deleted file mode 100644 index 27e23a60..00000000 --- a/template/tsconfig/cypress-ct/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.cypress-ct.json" - } - ] -} diff --git a/template/tsconfig/nightwatch-ct/tsconfig.json b/template/tsconfig/nightwatch-ct/tsconfig.json deleted file mode 100644 index 5c385ae2..00000000 --- a/template/tsconfig/nightwatch-ct/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - }, - { - "path": "./nightwatch/tsconfig.json" - } - ] -} diff --git a/template/tsconfig/nightwatch/tsconfig.json b/template/tsconfig/nightwatch/tsconfig.json deleted file mode 100644 index a5352e66..00000000 --- a/template/tsconfig/nightwatch/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.vitest.json" - }, - { - "path": "./nightwatch/tsconfig.json" - } - ] -} diff --git a/template/tsconfig/vitest/tsconfig.json b/template/tsconfig/vitest/tsconfig.json deleted file mode 100644 index 100cf6a8..00000000 --- a/template/tsconfig/vitest/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "files": [], - "references": [ - { - "path": "./tsconfig.node.json" - }, - { - "path": "./tsconfig.app.json" - }, - { - "path": "./tsconfig.vitest.json" - } - ] -} diff --git a/utils/filterList.ts b/utils/filterList.ts deleted file mode 100644 index 37780156..00000000 --- a/utils/filterList.ts +++ /dev/null @@ -1 +0,0 @@ -export const FILES_TO_FILTER = ['nightwatch.e2e.conf.js', 'nightwatch.component.conf.js'] -- 2.39.5