Add E2E tests (#9309)
Try adding E2E tests when labelling the PR or merging on main branch
This commit is contained in:
141
.github/workflows/ci-e2e.yml
vendored
Normal file
141
.github/workflows/ci-e2e.yml
vendored
Normal file
@ -0,0 +1,141 @@
|
||||
name: CI E2E Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event_name == 'push' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'run-e2e'))
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
NX_REJECT_UNKNOWN_LOCAL_CACHE: 0
|
||||
# https://github.com/actions/runner-images/issues/70#issuecomment-589562148
|
||||
NODE_OPTIONS: "--max-old-space-size=10240"
|
||||
services:
|
||||
postgres:
|
||||
image: twentycrm/twenty-postgres-spilo
|
||||
env:
|
||||
PGUSER_SUPERUSER: postgres
|
||||
PGPASSWORD_SUPERUSER: postgres
|
||||
ALLOW_NOSSL: "true"
|
||||
SPILO_PROVIDER: "local"
|
||||
ports:
|
||||
- 5432:5432
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
--health-timeout 5s
|
||||
--health-retries 5
|
||||
redis:
|
||||
image: redis
|
||||
ports:
|
||||
- 6379:6379
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Check system resources
|
||||
run: |
|
||||
echo "Available memory:"
|
||||
free -h
|
||||
echo "Available disk space:"
|
||||
df -h
|
||||
echo "CPU info:"
|
||||
lscpu
|
||||
|
||||
- name: Check for changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v11
|
||||
with:
|
||||
files: |
|
||||
packages/**
|
||||
playwright.config.ts
|
||||
.github/workflows/ci-e2e.yml
|
||||
|
||||
- name: Skip if no relevant changes
|
||||
if: steps.changed-files.outputs.any_changed == 'false'
|
||||
run: echo "No relevant changes detected. Marking as valid."
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: ./.github/workflows/actions/yarn-install
|
||||
|
||||
- name: Build twenty-shared
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: npx nx build twenty-shared
|
||||
|
||||
- name: Setup environment files
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
|
||||
cp packages/twenty-front/.env.example packages/twenty-front/.env
|
||||
cp packages/twenty-e2e-testing/.env.example packages/twenty-e2e-testing/.env
|
||||
npx nx reset:env twenty-server
|
||||
|
||||
- name: Build frontend
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: NODE_ENV=production NODE_OPTIONS="--max-old-space-size=10240" npx nx build twenty-front
|
||||
|
||||
- name: Build server
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: NODE_ENV=production npx nx build twenty-server
|
||||
|
||||
- name: Create and setup database
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "default";'
|
||||
PGPASSWORD=postgres psql -h localhost -p 5432 -U postgres -d postgres -c 'CREATE DATABASE "test";'
|
||||
npx nx run twenty-server:database:reset
|
||||
|
||||
- name: Start server
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
npx nx start twenty-server &
|
||||
echo "Waiting for server to be ready..."
|
||||
timeout 60 bash -c 'until curl -s http://localhost:3000/health; do sleep 2; done'
|
||||
|
||||
- name: Start frontend
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
npm_config_yes=true npx serve -s packages/twenty-front/build -l 3001 &
|
||||
echo "Waiting for frontend to be ready..."
|
||||
timeout 60 bash -c 'until curl -s http://localhost:3001; do sleep 2; done'
|
||||
|
||||
- name: Start worker
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: |
|
||||
npx nx run twenty-server:worker:ci &
|
||||
echo "Worker started"
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: npx nx setup twenty-e2e-testing
|
||||
|
||||
- name: Run Playwright tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: npx nx test twenty-e2e-testing
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: packages/twenty-e2e-testing/run_results/
|
||||
retention-days: 30
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: packages/twenty-e2e-testing/playwright-report/
|
||||
retention-days: 30
|
||||
52
.github/workflows/ci-e2e.yml.bak
vendored
52
.github/workflows/ci-e2e.yml.bak
vendored
@ -1,52 +0,0 @@
|
||||
name: CI E2E Tests
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
test:
|
||||
timeout-minutes: 30
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Check for changed files
|
||||
id: changed-files
|
||||
uses: tj-actions/changed-files@v11
|
||||
with:
|
||||
files: |
|
||||
packages/**
|
||||
playwright.config.ts
|
||||
|
||||
- name: Skip if no relevant changes
|
||||
if: steps.changed-files.outputs.any_changed == 'false'
|
||||
run: echo "No relevant changes detected. Marking as valid."
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
uses: ./.github/workflows/actions/yarn-install
|
||||
- name: Install Playwright Browsers
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: yarn playwright install --with-deps
|
||||
- name: Run Playwright tests
|
||||
if: steps.changed-files.outputs.any_changed == 'true'
|
||||
run: yarn test:e2e companies
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: always()
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
3
.vscode/extensions.json
vendored
3
.vscode/extensions.json
vendored
@ -14,6 +14,7 @@
|
||||
"styled-components.vscode-styled-components",
|
||||
"unifiedjs.vscode-mdx",
|
||||
"xyc.vscode-mdx-preview",
|
||||
"yoavbls.pretty-ts-errors"
|
||||
"yoavbls.pretty-ts-errors",
|
||||
"ms-playwright.playwright"
|
||||
]
|
||||
}
|
||||
|
||||
23
.vscode/launch.json
vendored
23
.vscode/launch.json
vendored
@ -6,12 +6,11 @@
|
||||
"name": "twenty-server - start debug",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "yarn",
|
||||
"runtimeVersion": "18",
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": [
|
||||
"nx",
|
||||
"run",
|
||||
"twenty-server:start",
|
||||
"twenty-server:start"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
@ -22,12 +21,11 @@
|
||||
"name": "twenty-server - worker debug",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "yarn",
|
||||
"runtimeVersion": "18",
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": [
|
||||
"nx",
|
||||
"run",
|
||||
"twenty-server:worker",
|
||||
"twenty-server:worker"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
@ -45,12 +43,23 @@
|
||||
"run",
|
||||
"twenty-server:command",
|
||||
"my-command",
|
||||
"--my-parameter value",
|
||||
"--my-parameter value"
|
||||
],
|
||||
"outputCapture": "std",
|
||||
"internalConsoleOptions": "openOnSessionStart",
|
||||
"console": "internalConsole",
|
||||
"cwd": "${workspaceFolder}/packages/twenty-server/"
|
||||
},
|
||||
{
|
||||
"name": "Playwright Test current file",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "npx",
|
||||
"runtimeArgs": ["nx", "test", "twenty-e2e-testing", "${file}"],
|
||||
"console": "integratedTerminal",
|
||||
"cwd": "${workspaceFolder}",
|
||||
"internalConsoleOptions": "neverOpen",
|
||||
"envFile": "${workspaceFolder}/packages/twenty-e2e-testing/.env"
|
||||
}
|
||||
]
|
||||
}
|
||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@ -48,5 +48,5 @@
|
||||
"eslint.debug": true,
|
||||
"files.associations": {
|
||||
".cursorrules": "markdown"
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
4
.vscode/twenty.code-workspace
vendored
4
.vscode/twenty.code-workspace
vendored
@ -44,6 +44,10 @@
|
||||
"name": "tools/eslint-rules",
|
||||
"path": "../tools/eslint-rules"
|
||||
},
|
||||
{
|
||||
"name": "packages/twenty-e2e-testing",
|
||||
"path": "../packages/twenty-e2e-testing"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"editor.formatOnSave": false,
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
# Note that provide always without trailing forward slash to have expected behaviour
|
||||
FRONTEND_BASE_URL=http://app.localhost:3001
|
||||
CI_DEFAULT_BASE_URL=https://demo.twenty.com
|
||||
FRONTEND_BASE_URL=http://localhost:3001
|
||||
DEFAULT_LOGIN=tim@apple.dev
|
||||
NEW_WORKSPACE_LOGIN=test@apple.dev
|
||||
DEMO_DEFAULT_LOGIN=noah@demo.dev
|
||||
|
||||
@ -2,7 +2,13 @@ import { defineConfig, devices } from '@playwright/test';
|
||||
import { config } from 'dotenv';
|
||||
import path from 'path';
|
||||
|
||||
config();
|
||||
const envResult = config({
|
||||
path: path.resolve(__dirname, '.env'),
|
||||
});
|
||||
|
||||
if (envResult.error) {
|
||||
throw new Error('Failed to load .env file');
|
||||
}
|
||||
|
||||
/* === Run your local dev server before starting the tests === */
|
||||
|
||||
@ -19,9 +25,7 @@ export default defineConfig({
|
||||
workers: 1, // 1 worker = 1 test at the time, tests can't be parallelized
|
||||
timeout: 30 * 1000, // timeout can be changed
|
||||
use: {
|
||||
baseURL: process.env.CI
|
||||
? process.env.CI_DEFAULT_BASE_URL
|
||||
: (process.env.FRONTEND_BASE_URL ?? 'http://app.localhost:3001'),
|
||||
baseURL: process.env.FRONTEND_BASE_URL || 'http://localhost:3001',
|
||||
trace: 'retain-on-failure', // trace takes EVERYTHING from page source, records every single step, should be used only when normal debugging won't work
|
||||
screenshot: 'on', // either 'on' here or in different method in modules, if 'on' all screenshots are overwritten each time the test is run
|
||||
headless: true, // instead of changing it to false, run 'yarn test:e2e:debug' or 'yarn test:e2e:ui'
|
||||
@ -54,7 +58,7 @@ export default defineConfig({
|
||||
storageState: path.resolve(__dirname, '.auth', 'user.json'), // takes saved cookies from directory
|
||||
},
|
||||
dependencies: ['Login setup'], // forces to run login setup before running tests from this project - CASE SENSITIVE
|
||||
testMatch: /all\/.+\.spec\.ts/,
|
||||
testMatch: /all\/.+\.e2e-spec\.ts/,
|
||||
},
|
||||
{
|
||||
name: 'firefox',
|
||||
@ -63,11 +67,7 @@ export default defineConfig({
|
||||
storageState: path.resolve(__dirname, '.auth', 'user.json'),
|
||||
},
|
||||
dependencies: ['Login setup'],
|
||||
testMatch: /all\/.+\.spec\.ts/,
|
||||
},
|
||||
{
|
||||
name: 'Authentication',
|
||||
testMatch: /authentication\/.*\.spec\.ts/,
|
||||
testMatch: /all\/.+\.e2e-spec\.ts/,
|
||||
},
|
||||
|
||||
//{
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { test, expect } from '../../lib/fixtures/screenshot';
|
||||
import { expect, test } from '../../lib/fixtures/screenshot';
|
||||
|
||||
test.describe('Basic check', () => {
|
||||
test('Checking if table in Companies is visible', async ({ page }) => {
|
||||
40
packages/twenty-e2e-testing/tests/all/workspaces.e2e-spec.ts
Normal file
40
packages/twenty-e2e-testing/tests/all/workspaces.e2e-spec.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { test } from '@playwright/test';
|
||||
import { sh } from '../../drivers/shell_driver';
|
||||
|
||||
test.describe('', () => {
|
||||
test.use({ storageState: { cookies: [], origins: [] } });
|
||||
|
||||
/*
|
||||
|
||||
test('Creating new workspace', async ({ page, browserName }) => {
|
||||
// this test must use only 1 browser, otherwise it will lead to success and fail (1 workspace is created instead of x workspaces)
|
||||
if (browserName == 'chromium') {
|
||||
await sh(
|
||||
'npx nx run twenty-server:database:reset --configuration=no-seed',
|
||||
);
|
||||
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
await page.getByPlaceholder('Email').fill('test@apple.dev'); // email must be changed each time test is run
|
||||
await page.getByPlaceholder('Email').press('Enter'); // otherwise if tests fails after this step, new workspace is created
|
||||
await page.getByPlaceholder('Password').fill('Applecar2025');
|
||||
await page.getByPlaceholder('Password').press('Enter');
|
||||
await page.getByPlaceholder('Apple').fill('Test');
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await page.getByPlaceholder('Tim').click();
|
||||
await page.getByPlaceholder('Tim').fill('Test2');
|
||||
await page.getByPlaceholder('Cook').click();
|
||||
await page.getByPlaceholder('Cook').fill('Test2');
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await page.getByText('Continue without sync').click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await expect(page.locator('table')).toBeVisible({ timeout: 1000 });
|
||||
await sh('npx nx run twenty-server:database:reset');
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
test('Syncing all workspaces', async () => {
|
||||
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
|
||||
});
|
||||
});
|
||||
@ -1,66 +0,0 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { sh } from '../../drivers/shell_driver';
|
||||
|
||||
test.describe('', () => {
|
||||
test('Testing logging', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
await page.getByPlaceholder('Email').fill('tim@apple.dev');
|
||||
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
||||
await page.getByPlaceholder('Password').fill('Applecar2025');
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
||||
expect(page.url()).not.toContain('/welcome');
|
||||
await page.getByRole('link', { name: 'Opportunities' }).click();
|
||||
await expect(page.locator('tbody > tr')).toHaveCount(4);
|
||||
});
|
||||
|
||||
test('Creating new workspace', async ({ page, browserName }) => {
|
||||
// this test must use only 1 browser, otherwise it will lead to success and fail (1 workspace is created instead of x workspaces)
|
||||
if (browserName == 'chromium') {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
await page.getByPlaceholder('Email').fill('test@apple.dev'); // email must be changed each time test is run
|
||||
await page.getByPlaceholder('Email').press('Enter'); // otherwise if tests fails after this step, new workspace is created
|
||||
await page.getByPlaceholder('Password').fill('Applecar2025');
|
||||
await page.getByPlaceholder('Password').press('Enter');
|
||||
await page.getByPlaceholder('Apple').fill('Test');
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await page.getByPlaceholder('Tim').click();
|
||||
await page.getByPlaceholder('Tim').fill('Test2');
|
||||
await page.getByPlaceholder('Cook').click();
|
||||
await page.getByPlaceholder('Cook').fill('Test2');
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await page.getByText('Continue without sync').click();
|
||||
await page.getByRole('button', { name: 'Finish' }).click();
|
||||
await expect(page.locator('table')).toBeVisible({ timeout: 1000 });
|
||||
}
|
||||
});
|
||||
|
||||
test('Syncing all workspaces', async () => {
|
||||
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
|
||||
await sh('npx nx run twenty-server:command workspace:sync-metadata -f');
|
||||
});
|
||||
|
||||
test('Resetting database', async ({ page, browserName }) => {
|
||||
if (browserName === 'chromium') {
|
||||
await sh('yarn nx database:reset twenty-server'); // if this command fails for any reason, database must be restarted manually using the same command because database is in unstable state
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
await page.getByPlaceholder('Email').fill('tim@apple.dev');
|
||||
await page.getByRole('button', { name: 'Continue' }).click();
|
||||
await page.getByPlaceholder('Password').fill('Applecar2025');
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
await page.getByRole('link', { name: 'Companies' }).click();
|
||||
expect(page.url()).toContain('/companies');
|
||||
await expect(page.locator('table')).toBeVisible();
|
||||
}
|
||||
});
|
||||
|
||||
test('Seeding database', async ({ page, browserName }) => {
|
||||
if (browserName === 'chromium') {
|
||||
await sh('npx nx workspace:seed:demo');
|
||||
await page.goto('/');
|
||||
}
|
||||
});
|
||||
});
|
||||
@ -1,17 +0,0 @@
|
||||
import { test as base, expect } from '../../lib/fixtures/screenshot';
|
||||
import { LoginPage } from '../../lib/pom/loginPage';
|
||||
|
||||
// fixture
|
||||
const test = base.extend<{ loginPage: LoginPage }>({
|
||||
loginPage: async ({ page }, use) => {
|
||||
await use(new LoginPage(page));
|
||||
},
|
||||
});
|
||||
|
||||
test('Check login with email', async ({ loginPage }) => {
|
||||
await loginPage.typeEmail(process.env.DEFAULT_LOGIN);
|
||||
await loginPage.clickContinueButton();
|
||||
await loginPage.typePassword(process.env.DEFAULT_PASSWORD);
|
||||
await loginPage.clickSignInButton();
|
||||
await expect(loginPage.signInButton).not.toBeVisible();
|
||||
});
|
||||
@ -1,4 +1,4 @@
|
||||
import { test, expect } from '@playwright/test';
|
||||
import { expect, test } from '@playwright/test';
|
||||
|
||||
test('Check if demo account is working properly @demo-only', async ({
|
||||
page,
|
||||
@ -1,18 +1,38 @@
|
||||
import { test as setup, expect } from '@playwright/test';
|
||||
import { expect, test as setup } from '@playwright/test';
|
||||
import path from 'path';
|
||||
|
||||
setup('Login test', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
await page.getByPlaceholder('Email').fill(process.env.DEFAULT_LOGIN);
|
||||
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
||||
await page.getByPlaceholder('Password').fill(process.env.DEFAULT_PASSWORD);
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
||||
console.log('Starting login test');
|
||||
|
||||
// End of authentication steps.
|
||||
await page.goto('/');
|
||||
console.log('Navigated to homepage');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue With Email' }).click();
|
||||
console.log('Clicked email login button');
|
||||
|
||||
console.log('Default login', process.env.DEFAULT_LOGIN);
|
||||
await page.getByPlaceholder('Email').fill(process.env.DEFAULT_LOGIN ?? '');
|
||||
console.log('Filled email field');
|
||||
|
||||
await page.getByRole('button', { name: 'Continue', exact: true }).click();
|
||||
console.log('Clicked continue button');
|
||||
|
||||
await page
|
||||
.getByPlaceholder('Password')
|
||||
.fill(process.env.DEFAULT_PASSWORD ?? '');
|
||||
console.log('Filled password field');
|
||||
|
||||
await page.getByRole('button', { name: 'Sign in' }).click();
|
||||
console.log('Clicked sign in button');
|
||||
|
||||
await page.waitForLoadState('networkidle');
|
||||
console.log('Waited for network to be idle');
|
||||
|
||||
await expect(page.getByText('Welcome to Twenty')).not.toBeVisible();
|
||||
console.log('Verified welcome message not visible');
|
||||
|
||||
await page.context().storageState({
|
||||
path: path.resolve(__dirname, '..', '.auth', 'user.json'),
|
||||
});
|
||||
console.log('Saved auth state');
|
||||
});
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"build": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=3000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
||||
"build": "VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=4000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
||||
"build:sourcemaps": "VITE_BUILD_SOURCEMAP=true VITE_DISABLE_TYPESCRIPT_CHECKER=true VITE_DISABLE_ESLINT_CHECKER=true NODE_OPTIONS=--max-old-space-size=6000 npx vite build && sh ./scripts/inject-runtime-env.sh",
|
||||
"start:prod": "NODE_ENV=production npx vite --host",
|
||||
"tsup": "npx tsup"
|
||||
|
||||
Reference in New Issue
Block a user