mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-24 22:55:13 +00:00
test: add nitro preset tests (v2 & v3) (#104)
This commit is contained in:
parent
3f712f3d46
commit
5aa59c2ca5
49
.github/workflows/test-compat.yml
vendored
Normal file
49
.github/workflows/test-compat.yml
vendored
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
name: test-compat
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test-compat:
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
node: [14]
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/setup-node@v2
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node }}
|
||||||
|
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@master
|
||||||
|
|
||||||
|
- uses: actions/cache@v2
|
||||||
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
.yarn
|
||||||
|
test/fixtures/compat/.yarn
|
||||||
|
key: ${{ runner.os }}-yarn-compat-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-yarn-compat-
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
if: steps.cache.outputs.cache-hit != 'true'
|
||||||
|
run: yarn --immutable && cd test/fixtures/compat && yarn --immutable
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: yarn build
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: TEST_COMPAT=1 yarn jest --ci
|
||||||
|
|
||||||
|
# - name: Coverage
|
||||||
|
# uses: codecov/codecov-action@v1
|
@ -1,4 +1,4 @@
|
|||||||
name: ci
|
name: test
|
||||||
|
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
@ -9,7 +9,7 @@ on:
|
|||||||
- main
|
- main
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
ci:
|
test:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
strategy:
|
strategy:
|
||||||
@ -43,8 +43,8 @@ jobs:
|
|||||||
- name: Build
|
- name: Build
|
||||||
run: yarn build
|
run: yarn build
|
||||||
|
|
||||||
# - name: Test
|
- name: Test
|
||||||
# run: yarn jest
|
run: yarn jest --ci
|
||||||
|
|
||||||
# - name: Coverage
|
# - name: Coverage
|
||||||
# uses: codecov/codecov-action@v1
|
# uses: codecov/codecov-action@v1
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -2,9 +2,8 @@
|
|||||||
node_modules
|
node_modules
|
||||||
jspm_packages
|
jspm_packages
|
||||||
|
|
||||||
# Only keep yarn.lock in the root
|
|
||||||
package-lock.json
|
package-lock.json
|
||||||
*/**/yarn.lock
|
# */**/yarn.lock
|
||||||
|
|
||||||
# Logs
|
# Logs
|
||||||
*.log
|
*.log
|
||||||
@ -58,3 +57,6 @@ coverage
|
|||||||
Network Trash Folder
|
Network Trash Folder
|
||||||
Temporary Items
|
Temporary Items
|
||||||
.apdisk
|
.apdisk
|
||||||
|
|
||||||
|
.vercel_build_output
|
||||||
|
*.lock
|
||||||
|
10
jest.config.js
Normal file
10
jest.config.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
module.exports = {
|
||||||
|
preset: 'ts-jest',
|
||||||
|
testEnvironment: 'node',
|
||||||
|
transform: {
|
||||||
|
'\\.[jt]sx?$': 'ts-jest'
|
||||||
|
},
|
||||||
|
testPathIgnorePatterns: [
|
||||||
|
'.output/.*'
|
||||||
|
]
|
||||||
|
}
|
@ -13,6 +13,8 @@
|
|||||||
"nu": "./node_modules/.bin/nu",
|
"nu": "./node_modules/.bin/nu",
|
||||||
"play": "yarn run nu dev playground",
|
"play": "yarn run nu dev playground",
|
||||||
"lint": "eslint --ext .vue,.ts,.js .",
|
"lint": "eslint --ext .vue,.ts,.js .",
|
||||||
|
"test": "yarn lint && jest",
|
||||||
|
"test:compat": "TEST_COMPAT=1 jest",
|
||||||
"version": "yarn && git add yarn.lock"
|
"version": "yarn && git add yarn.lock"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
@ -23,11 +25,13 @@
|
|||||||
"@nuxtjs/eslint-config-typescript": "^6.0.0",
|
"@nuxtjs/eslint-config-typescript": "^6.0.0",
|
||||||
"@types/jest": "^26.0.22",
|
"@types/jest": "^26.0.22",
|
||||||
"@types/node": "^14.14.41",
|
"@types/node": "^14.14.41",
|
||||||
|
"@types/object-hash": "^2",
|
||||||
"eslint": "^7.24.0",
|
"eslint": "^7.24.0",
|
||||||
"eslint-plugin-jsdoc": "^32.3.1",
|
"eslint-plugin-jsdoc": "^32.3.1",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"jiti": "^1.9.1",
|
"jiti": "^1.9.1",
|
||||||
"lerna": "^4.0.0",
|
"lerna": "^4.0.0",
|
||||||
|
"object-hash": "^2.1.1",
|
||||||
"ts-jest": "^26.5.5",
|
"ts-jest": "^26.5.5",
|
||||||
"typescript": "^4.2.4",
|
"typescript": "^4.2.4",
|
||||||
"unbuild": "^0.2.2"
|
"unbuild": "^0.2.2"
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
"@rollup/plugin-replace": "^2.4.2",
|
"@rollup/plugin-replace": "^2.4.2",
|
||||||
"@rollup/plugin-virtual": "^2.0.3",
|
"@rollup/plugin-virtual": "^2.0.3",
|
||||||
"@rollup/pluginutils": "^4.1.0",
|
"@rollup/pluginutils": "^4.1.0",
|
||||||
|
"@types/jsdom": "^16.2.10",
|
||||||
"@vercel/nft": "^0.10.1",
|
"@vercel/nft": "^0.10.1",
|
||||||
"@vue/server-renderer": "^3.0.11",
|
"@vue/server-renderer": "^3.0.11",
|
||||||
"archiver": "^5.3.0",
|
"archiver": "^5.3.0",
|
||||||
@ -61,7 +62,7 @@
|
|||||||
"std-env": "^2.3.0",
|
"std-env": "^2.3.0",
|
||||||
"table": "^6.4.0",
|
"table": "^6.4.0",
|
||||||
"ufo": "^0.7.1",
|
"ufo": "^0.7.1",
|
||||||
"unenv": "^0.2.2",
|
"unenv": "^0.2.3",
|
||||||
"unstorage": "^0.1.5",
|
"unstorage": "^0.1.5",
|
||||||
"upath": "^2.0.1",
|
"upath": "^2.0.1",
|
||||||
"vue": "3.0.11",
|
"vue": "3.0.11",
|
||||||
|
@ -90,6 +90,7 @@ function clientPlugins (ctx: WebpackConfigContext) {
|
|||||||
if (!ctx.isDev && options.build.analyze) {
|
if (!ctx.isDev && options.build.analyze) {
|
||||||
const statsDir = path.resolve(options.buildDir, 'stats')
|
const statsDir = path.resolve(options.buildDir, 'stats')
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
config.plugins.push(new BundleAnalyzerPlugin({
|
config.plugins.push(new BundleAnalyzerPlugin({
|
||||||
analyzerMode: 'static',
|
analyzerMode: 'static',
|
||||||
defaultSizes: 'gzip',
|
defaultSizes: 'gzip',
|
||||||
|
@ -65,6 +65,7 @@ export function getWebpackConfig (ctx: WebpackConfigContext): Configuration {
|
|||||||
const builder = {}
|
const builder = {}
|
||||||
const loaders = []
|
const loaders = []
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
const { extend } = options.build
|
const { extend } = options.build
|
||||||
if (typeof extend === 'function') {
|
if (typeof extend === 'function') {
|
||||||
const extendedConfig = extend.call(
|
const extendedConfig = extend.call(
|
||||||
|
3
test/fixtures/basic/nuxt.config.ts
vendored
Normal file
3
test/fixtures/basic/nuxt.config.ts
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { defineNuxtConfig } from '@nuxt/kit'
|
||||||
|
|
||||||
|
export default defineNuxtConfig({})
|
7
test/fixtures/basic/package.json
vendored
Normal file
7
test/fixtures/basic/package.json
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "fixture-compat",
|
||||||
|
"scripts": {
|
||||||
|
"build": "nuxt build"
|
||||||
|
}
|
||||||
|
}
|
3
test/fixtures/basic/pages/index.vue
vendored
Normal file
3
test/fixtures/basic/pages/index.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div>Hello Vue</div>
|
||||||
|
</template>
|
1
test/fixtures/basic/server/api/hello.ts
vendored
Normal file
1
test/fixtures/basic/server/api/hello.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default () => 'Hello API'
|
10
test/fixtures/compat/nuxt.config.ts
vendored
Normal file
10
test/fixtures/compat/nuxt.config.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { defineNuxtConfig } from '@nuxt/kit'
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
global.__NUXT_PREPATHS__ = (global.__NUXT_PREPATHS__ || []).concat(__dirname)
|
||||||
|
|
||||||
|
export default defineNuxtConfig({
|
||||||
|
buildModules: [
|
||||||
|
'@nuxt/nitro/compat'
|
||||||
|
]
|
||||||
|
})
|
13
test/fixtures/compat/package.json
vendored
Normal file
13
test/fixtures/compat/package.json
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "fixture-basic",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "nuxt dev",
|
||||||
|
"build": "nuxt build"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"core-js": "^3",
|
||||||
|
"nuxt": "^2",
|
||||||
|
"vue": "^2"
|
||||||
|
}
|
||||||
|
}
|
3
test/fixtures/compat/pages/index.vue
vendored
Normal file
3
test/fixtures/compat/pages/index.vue
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<template>
|
||||||
|
<div>Hello Vue</div>
|
||||||
|
</template>
|
1
test/fixtures/compat/server/api/hello.ts
vendored
Normal file
1
test/fixtures/compat/server/api/hello.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export default () => 'Hello API'
|
10569
test/fixtures/compat/yarn.lock
vendored
Normal file
10569
test/fixtures/compat/yarn.lock
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
test/presets/_utils.ts
Normal file
103
test/presets/_utils.ts
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
import { RequestListener } from 'http'
|
||||||
|
import { resolve } from 'upath'
|
||||||
|
import destr from 'destr'
|
||||||
|
import consola from 'consola'
|
||||||
|
import { Listener, listen } from 'listhen'
|
||||||
|
import { $fetch } from 'ohmyfetch/node'
|
||||||
|
import createRequire from 'create-require'
|
||||||
|
import type { LoadNuxtOptions } from '@nuxt/kit'
|
||||||
|
import { fixtureDir, buildFixture, loadFixture } from '../utils'
|
||||||
|
|
||||||
|
const isCompat = Boolean(process.env.TEST_COMPAT)
|
||||||
|
|
||||||
|
export interface TestContext {
|
||||||
|
rootDir: string
|
||||||
|
outDir: string
|
||||||
|
nuxt?: any
|
||||||
|
fetch: (url: string) => Promise<any>
|
||||||
|
server?: Listener
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AbstractRequest {
|
||||||
|
url: string
|
||||||
|
headers?: any
|
||||||
|
method?: string
|
||||||
|
body?: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AbstractResponse {
|
||||||
|
data: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type AbstractHandler = (req: AbstractRequest) => Promise<AbstractResponse>
|
||||||
|
|
||||||
|
export function setupTest (): TestContext {
|
||||||
|
const fixture = isCompat ? 'compat' : 'basic'
|
||||||
|
const rootDir = fixtureDir(fixture)
|
||||||
|
const outDir = resolve(__dirname, '.output', fixture)
|
||||||
|
|
||||||
|
const ctx: TestContext = {
|
||||||
|
rootDir,
|
||||||
|
outDir,
|
||||||
|
fetch: url => $fetch<any>(url, { baseURL: ctx.server.url })
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
jest.mock('jiti', () => createRequire)
|
||||||
|
consola.wrapAll()
|
||||||
|
consola.mock(() => jest.fn())
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
if (ctx.nuxt) {
|
||||||
|
await ctx.nuxt.close()
|
||||||
|
}
|
||||||
|
if (ctx.server) {
|
||||||
|
await ctx.server.close()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
|
||||||
|
export function testNitroBuild (ctx: TestContext, preset: string) {
|
||||||
|
test('nitro build', async () => {
|
||||||
|
ctx.outDir = resolve(ctx.outDir, preset)
|
||||||
|
|
||||||
|
const loadOpts: LoadNuxtOptions = { rootDir: ctx.rootDir, dev: false, version: isCompat ? 2 : 3 }
|
||||||
|
await buildFixture(loadOpts)
|
||||||
|
const nuxt = await loadFixture(loadOpts, {
|
||||||
|
nitro: {
|
||||||
|
preset,
|
||||||
|
minify: false,
|
||||||
|
serveStatic: false,
|
||||||
|
externals: preset === 'cloudflare' ? false : { trace: false },
|
||||||
|
output: { dir: ctx.outDir }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
await nuxt.callHook('build:done', {})
|
||||||
|
ctx.nuxt = nuxt
|
||||||
|
}, 60000)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function startServer (ctx: TestContext, handle: RequestListener) {
|
||||||
|
ctx.server = await listen(handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function testNitroBehavior (_ctx: TestContext, getHandler: () => Promise<AbstractHandler>) {
|
||||||
|
let handler
|
||||||
|
|
||||||
|
test('setup handler', async () => {
|
||||||
|
handler = await getHandler()
|
||||||
|
})
|
||||||
|
|
||||||
|
test('SSR Works', async () => {
|
||||||
|
const { data } = await handler({ url: '/' })
|
||||||
|
expect(data).toMatch('Hello Vue')
|
||||||
|
}, 10000)
|
||||||
|
|
||||||
|
test('API Works', async () => {
|
||||||
|
const { data } = await handler({ url: '/api/hello' })
|
||||||
|
expect(destr(data)).toEqual('Hello API')
|
||||||
|
})
|
||||||
|
}
|
66
test/presets/cloudflare.test.ts
Normal file
66
test/presets/cloudflare.test.ts
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
import { resolve } from 'path'
|
||||||
|
import { readFile } from 'fs-extra'
|
||||||
|
import { JSDOM } from 'jsdom'
|
||||||
|
|
||||||
|
import { setupTest, testNitroBuild, testNitroBehavior } from './_utils'
|
||||||
|
|
||||||
|
// TODO: fix SyntaxError: Unexpected end of input on script executation
|
||||||
|
describe.skip('nitro:preset:cloudflare', () => {
|
||||||
|
const ctx = setupTest()
|
||||||
|
testNitroBuild(ctx, 'cloudflare')
|
||||||
|
testNitroBehavior(ctx, async () => {
|
||||||
|
const script = await readFile(resolve(ctx.outDir, 'server/index.js'), 'utf-8')
|
||||||
|
const dom = new JSDOM(
|
||||||
|
`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
global = window
|
||||||
|
window.Response = class Response {
|
||||||
|
constructor (body, { headers, status, statusText } = {}) {
|
||||||
|
this.body = body
|
||||||
|
this.status = status || 200
|
||||||
|
this.headers = headers || {}
|
||||||
|
this.statusText = statusText || ''
|
||||||
|
}
|
||||||
|
get ok() {
|
||||||
|
return this.status === 200
|
||||||
|
}
|
||||||
|
async text() {
|
||||||
|
return this.body
|
||||||
|
}
|
||||||
|
async json() {
|
||||||
|
return JSON.parse(this.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.addEventListener = (method, handler) => {
|
||||||
|
window.handleEvent = async event => {
|
||||||
|
event.respondWith = response => {
|
||||||
|
event.response = response
|
||||||
|
}
|
||||||
|
await handler(event)
|
||||||
|
return event.response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script>${script}</script>
|
||||||
|
</body>
|
||||||
|
</html>`,
|
||||||
|
{ runScripts: 'dangerously' }
|
||||||
|
)
|
||||||
|
|
||||||
|
return async ({ url, headers, method, body }) => {
|
||||||
|
const data = await dom.window.handleEvent({
|
||||||
|
request: {
|
||||||
|
url: 'http://localhost' + url,
|
||||||
|
headers: headers || {},
|
||||||
|
method: method || 'GET',
|
||||||
|
redirect: null,
|
||||||
|
body: body || null
|
||||||
|
}
|
||||||
|
}).then(r => r.text())
|
||||||
|
|
||||||
|
return { data }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
26
test/presets/lambda.test.ts
Normal file
26
test/presets/lambda.test.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
import { resolve } from 'path'
|
||||||
|
import { testNitroBuild, setupTest, testNitroBehavior } from './_utils'
|
||||||
|
|
||||||
|
describe('nitro:preset:lambda', () => {
|
||||||
|
const ctx = setupTest()
|
||||||
|
testNitroBuild(ctx, 'lambda')
|
||||||
|
testNitroBehavior(ctx, async () => {
|
||||||
|
const { handler } = await import(resolve(ctx.outDir, 'server/index.js'))
|
||||||
|
return async ({ url: rawRelativeUrl, headers, method, body }) => {
|
||||||
|
// creating new URL object to parse query easier
|
||||||
|
const url = new URL(`https://example.com${rawRelativeUrl}`)
|
||||||
|
const queryStringParameters = Object.fromEntries(url.searchParams.entries())
|
||||||
|
const event = {
|
||||||
|
path: url.pathname,
|
||||||
|
headers: headers || {},
|
||||||
|
method: method || 'GET',
|
||||||
|
queryStringParameters,
|
||||||
|
body: body || ''
|
||||||
|
}
|
||||||
|
const res = await handler(event)
|
||||||
|
return {
|
||||||
|
data: res.body
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
17
test/presets/node.test.ts
Normal file
17
test/presets/node.test.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { resolve } from 'path'
|
||||||
|
import { testNitroBuild, startServer, setupTest, testNitroBehavior } from './_utils'
|
||||||
|
|
||||||
|
describe('nitro:preset:node', () => {
|
||||||
|
const ctx = setupTest()
|
||||||
|
testNitroBuild(ctx, 'node')
|
||||||
|
testNitroBehavior(ctx, async () => {
|
||||||
|
const { handle } = await import(resolve(ctx.outDir, 'server/index.js'))
|
||||||
|
await startServer(ctx, handle)
|
||||||
|
return async ({ url }) => {
|
||||||
|
const data = await ctx.fetch(url)
|
||||||
|
return {
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
18
test/presets/vercel.test.ts
Normal file
18
test/presets/vercel.test.ts
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { resolve } from 'path'
|
||||||
|
import { testNitroBuild, setupTest, startServer, testNitroBehavior } from './_utils'
|
||||||
|
|
||||||
|
describe('nitro:preset:vercel', () => {
|
||||||
|
const ctx = setupTest()
|
||||||
|
testNitroBuild(ctx, 'vercel')
|
||||||
|
testNitroBehavior(ctx, async () => {
|
||||||
|
const handle = await import(resolve(ctx.outDir, 'functions/node/server/index.js'))
|
||||||
|
.then(r => r.default || r)
|
||||||
|
await startServer(ctx, handle)
|
||||||
|
return async ({ url }) => {
|
||||||
|
const data = await ctx.fetch(url)
|
||||||
|
return {
|
||||||
|
data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
80
test/utils.ts
Normal file
80
test/utils.ts
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
import { resolve, dirname } from 'path'
|
||||||
|
import { existsSync, readFileSync, writeFileSync, rmSync, mkdirSync } from 'fs'
|
||||||
|
import { execSync } from 'child_process'
|
||||||
|
import defu from 'defu'
|
||||||
|
import hash from 'object-hash'
|
||||||
|
import type { LoadNuxtOptions, NuxtConfig } from '@nuxt/kit'
|
||||||
|
|
||||||
|
export function fixtureDir (name: string) {
|
||||||
|
return resolve(__dirname, 'fixtures', name)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadFixture (opts: LoadNuxtOptions, unhashedConfig?: NuxtConfig) {
|
||||||
|
const buildId = hash(opts)
|
||||||
|
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
||||||
|
const { loadNuxt } = await import('@nuxt/kit')
|
||||||
|
const nuxt = await loadNuxt(defu(opts, { config: { buildDir, ...unhashedConfig } }))
|
||||||
|
return nuxt
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function buildFixture (opts: LoadNuxtOptions) {
|
||||||
|
const buildId = hash(opts)
|
||||||
|
const buildDir = resolve(opts.rootDir, '.nuxt', buildId)
|
||||||
|
|
||||||
|
const lockFile = resolve(opts.rootDir, `.build-${buildId}.lock`)
|
||||||
|
mkdirpSync(dirname(lockFile))
|
||||||
|
await waitWhile(() => isAlive(readSync(lockFile)))
|
||||||
|
writeFileSync(lockFile, process.pid + '', 'utf8')
|
||||||
|
|
||||||
|
try {
|
||||||
|
const integrity = gitHead() // TODO: Calculate hash from project source
|
||||||
|
const integrityFile = resolve(buildDir, '.integrity')
|
||||||
|
const lastBuildIntegrity = readSync(integrityFile)
|
||||||
|
if (integrity !== lastBuildIntegrity) {
|
||||||
|
const nuxt = await loadFixture(opts)
|
||||||
|
const { buildNuxt } = await import('@nuxt/kit')
|
||||||
|
await buildNuxt(nuxt)
|
||||||
|
await nuxt.close()
|
||||||
|
await writeFileSync(integrityFile, integrity)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
existsSync(lockFile) && rmSync(lockFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function mkdirpSync (dir) {
|
||||||
|
if (!existsSync(dir)) {
|
||||||
|
mkdirpSync(dirname(dir))
|
||||||
|
mkdirSync(dir)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readSync (file) {
|
||||||
|
return existsSync(file) ? readFileSync(file, 'utf8') : null
|
||||||
|
}
|
||||||
|
|
||||||
|
function isAlive (pid) {
|
||||||
|
try {
|
||||||
|
process.kill(pid, 0)
|
||||||
|
return true
|
||||||
|
} catch (e) {
|
||||||
|
return e.code === 'EPERM'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function waitWhile (check, interval = 100, timeout = 30000) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const t = setTimeout(() => reject(new Error('Timeout')), timeout)
|
||||||
|
const i = setInterval(() => {
|
||||||
|
if (!check()) {
|
||||||
|
clearTimeout(t)
|
||||||
|
clearInterval(i)
|
||||||
|
resolve(true)
|
||||||
|
}
|
||||||
|
}, interval)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function gitHead (): string {
|
||||||
|
return execSync('git rev-parse HEAD').toString('utf8').trim()
|
||||||
|
}
|
52
yarn.lock
52
yarn.lock
@ -1662,6 +1662,7 @@ __metadata:
|
|||||||
"@types/debounce": ^1.2.0
|
"@types/debounce": ^1.2.0
|
||||||
"@types/fs-extra": ^9.0.11
|
"@types/fs-extra": ^9.0.11
|
||||||
"@types/http-proxy": ^1.17.5
|
"@types/http-proxy": ^1.17.5
|
||||||
|
"@types/jsdom": ^16.2.10
|
||||||
"@types/node-fetch": ^2.5.10
|
"@types/node-fetch": ^2.5.10
|
||||||
"@types/serve-static": ^1.13.9
|
"@types/serve-static": ^1.13.9
|
||||||
"@vercel/nft": ^0.10.1
|
"@vercel/nft": ^0.10.1
|
||||||
@ -1701,7 +1702,7 @@ __metadata:
|
|||||||
table: ^6.4.0
|
table: ^6.4.0
|
||||||
ufo: ^0.7.1
|
ufo: ^0.7.1
|
||||||
unbuild: ^0.2.2
|
unbuild: ^0.2.2
|
||||||
unenv: ^0.2.2
|
unenv: ^0.2.3
|
||||||
unstorage: ^0.1.5
|
unstorage: ^0.1.5
|
||||||
upath: ^2.0.1
|
upath: ^2.0.1
|
||||||
vue: 3.0.11
|
vue: 3.0.11
|
||||||
@ -2281,6 +2282,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/jsdom@npm:^16.2.10":
|
||||||
|
version: 16.2.10
|
||||||
|
resolution: "@types/jsdom@npm:16.2.10"
|
||||||
|
dependencies:
|
||||||
|
"@types/node": "*"
|
||||||
|
"@types/parse5": "*"
|
||||||
|
"@types/tough-cookie": "*"
|
||||||
|
checksum: 9e39f1d2d00e7373222da490a78f11e66a8ea19e3b08ed9b223bcd8da0ce6eb15aabd670d36996a727291d4a917366a8340353a5adef83b4c714fed6e61e786f
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.3, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6":
|
"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.3, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.6":
|
||||||
version: 7.0.7
|
version: 7.0.7
|
||||||
resolution: "@types/json-schema@npm:7.0.7"
|
resolution: "@types/json-schema@npm:7.0.7"
|
||||||
@ -2370,6 +2382,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/object-hash@npm:^2":
|
||||||
|
version: 2.1.0
|
||||||
|
resolution: "@types/object-hash@npm:2.1.0"
|
||||||
|
checksum: 276948b96fff4f3ddbb37a566401fbdcd68ffac16267e464bf73b3448d3a7f8b2876be39c8a731478710d5b5a01dc4a61d927b12babfbf02e4acba6a3d8a0a42
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/parse-json@npm:^4.0.0":
|
"@types/parse-json@npm:^4.0.0":
|
||||||
version: 4.0.0
|
version: 4.0.0
|
||||||
resolution: "@types/parse-json@npm:4.0.0"
|
resolution: "@types/parse-json@npm:4.0.0"
|
||||||
@ -2377,6 +2396,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/parse5@npm:*":
|
||||||
|
version: 6.0.0
|
||||||
|
resolution: "@types/parse5@npm:6.0.0"
|
||||||
|
checksum: 356652dc0b341dcc8f93c4b4b59e163efe9b4ccc993e15aa9d96b7b96776eef629939d6c597d79c0abb8adcee9068f590e4bb1102deb770b993d37a24fdac8b8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/parse5@npm:^5.0.0":
|
"@types/parse5@npm:^5.0.0":
|
||||||
version: 5.0.3
|
version: 5.0.3
|
||||||
resolution: "@types/parse5@npm:5.0.3"
|
resolution: "@types/parse5@npm:5.0.3"
|
||||||
@ -2448,6 +2474,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@types/tough-cookie@npm:*":
|
||||||
|
version: 4.0.0
|
||||||
|
resolution: "@types/tough-cookie@npm:4.0.0"
|
||||||
|
checksum: 5a0cccc6d073b84dbb48d603e692b55ac30cea1653a7fc813e97a3bcaa9edd97c703c15727378d632e416a90178e6da657151eba8175cbb201a9a98de22ac3a8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@types/uglify-js@npm:*":
|
"@types/uglify-js@npm:*":
|
||||||
version: 3.13.0
|
version: 3.13.0
|
||||||
resolution: "@types/uglify-js@npm:3.13.0"
|
resolution: "@types/uglify-js@npm:3.13.0"
|
||||||
@ -10487,11 +10520,13 @@ __metadata:
|
|||||||
"@nuxtjs/eslint-config-typescript": ^6.0.0
|
"@nuxtjs/eslint-config-typescript": ^6.0.0
|
||||||
"@types/jest": ^26.0.22
|
"@types/jest": ^26.0.22
|
||||||
"@types/node": ^14.14.41
|
"@types/node": ^14.14.41
|
||||||
|
"@types/object-hash": ^2
|
||||||
eslint: ^7.24.0
|
eslint: ^7.24.0
|
||||||
eslint-plugin-jsdoc: ^32.3.1
|
eslint-plugin-jsdoc: ^32.3.1
|
||||||
jest: ^26.6.3
|
jest: ^26.6.3
|
||||||
jiti: ^1.9.1
|
jiti: ^1.9.1
|
||||||
lerna: ^4.0.0
|
lerna: ^4.0.0
|
||||||
|
object-hash: ^2.1.1
|
||||||
ts-jest: ^26.5.5
|
ts-jest: ^26.5.5
|
||||||
typescript: ^4.2.4
|
typescript: ^4.2.4
|
||||||
unbuild: ^0.2.2
|
unbuild: ^0.2.2
|
||||||
@ -10563,6 +10598,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"object-hash@npm:^2.1.1":
|
||||||
|
version: 2.1.1
|
||||||
|
resolution: "object-hash@npm:2.1.1"
|
||||||
|
checksum: fe49a0864cba7ac4055c604295692ae75f5f4d22ba929aaaa987469809d17ab030d1111e8f0d425a070fa4a78b8021b55260e26e98b66b59e0f7be2bd9069fb8
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"object-inspect@npm:^1.9.0":
|
"object-inspect@npm:^1.9.0":
|
||||||
version: 1.10.2
|
version: 1.10.2
|
||||||
resolution: "object-inspect@npm:1.10.2"
|
resolution: "object-inspect@npm:1.10.2"
|
||||||
@ -14322,9 +14364,9 @@ typescript@^4.2.4:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"unenv@npm:^0.2.2":
|
"unenv@npm:^0.2.3":
|
||||||
version: 0.2.2
|
version: 0.2.3
|
||||||
resolution: "unenv@npm:0.2.2"
|
resolution: "unenv@npm:0.2.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
buffer: ^6.0.2
|
buffer: ^6.0.2
|
||||||
defu: ^3.2.2
|
defu: ^3.2.2
|
||||||
@ -14335,7 +14377,7 @@ typescript@^4.2.4:
|
|||||||
process: ^0.11.10
|
process: ^0.11.10
|
||||||
upath: ^2.0.1
|
upath: ^2.0.1
|
||||||
util: ^0.12.3
|
util: ^0.12.3
|
||||||
checksum: 64597e78d6b660223381fbd3686752a3cfae65cc0c8a89cee241c6617d26b73e734d5dd1c0b6acdbfebc79024d96cdc9177dece6ed9475865dfe9143e4299427
|
checksum: 75fe628ffca2694106baac8be25122bd6a159eb712f4ae89d9c53f5c6bf77ccac30fa5f2a6a2ee2bc372d55a3f97cddbd7c597396a47fa56b088fc8b7d30c96a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user