Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ef70de6

Browse files
authored
chore: vendor deno modules used in integration test helpers (#2883)
1 parent 17a1202 commit ef70de6

File tree

5 files changed

+98
-37
lines changed

5 files changed

+98
-37
lines changed

‎.github/workflows/run-tests.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,8 @@ jobs:
151151
run: npm ci
152152
- name: 'Build'
153153
run: npm run build
154+
- name: 'Vendor deno helpers for integration tests'
155+
run: node tools/vendor-deno-tools.js
154156
- name: Resolve Next.js version
155157
id: resolve-next-version
156158
shell: bash

‎.gitignore‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ node_modules/
22
dist/
33
.next
44
edge-runtime/vendor
5+
# deno.json is ephemeral and generated for the purpose of vendoring remote modules in CI
6+
tools/deno/deno.json
7+
tools/deno/vendor
58

69
# Local Netlify folder
710
.netlify

‎tools/build-helpers.js‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { createWriteStream } from 'node:fs'
2+
import { rm, writeFile } from 'node:fs/promises'
3+
import { join } from 'node:path'
4+
import { Readable } from 'stream'
5+
import { finished } from 'stream/promises'
6+
7+
import { execaCommand } from 'execa'
8+
9+
/**
10+
* @param {Object} options
11+
* @param {string} options.vendorSource Path to the file to vendor
12+
* @param {string} options.cwd Directory to run the command in
13+
* @param {string[]} [options.wasmFilesToDownload] List of wasm files to download
14+
* @param {boolean} [options.initEmptyDenoJson] If true, will create an empty deno.json file
15+
*/
16+
export async function vendorDeno({
17+
vendorSource,
18+
cwd,
19+
wasmFilesToDownload = [],
20+
initEmptyDenoJson = false,
21+
}) {
22+
try {
23+
await execaCommand('deno --version')
24+
} catch {
25+
throw new Error('Could not check the version of Deno. Is it installed on your system?')
26+
}
27+
28+
const vendorDest = join(cwd, 'vendor')
29+
30+
console.log(`🧹 Deleting '${vendorDest}'...`)
31+
32+
await rm(vendorDest, { force: true, recursive: true })
33+
34+
if (initEmptyDenoJson) {
35+
const denoJsonPath = join(cwd, 'deno.json')
36+
console.log(`🧹 Generating clean '${denoJsonPath}`)
37+
await writeFile(denoJsonPath, '{}')
38+
}
39+
40+
console.log(`📦 Vendoring Deno modules for '${vendorSource}' into '${vendorDest}'...`)
41+
// --output=${vendorDest}
42+
await execaCommand(`deno vendor ${vendorSource} --force`, {
43+
cwd,
44+
})
45+
46+
if (wasmFilesToDownload.length !== 0) {
47+
console.log(`⬇️ Downloading wasm files...`)
48+
49+
// deno vendor doesn't work well with wasm files
50+
// see https://github.com/denoland/deno/issues/14123
51+
// to workaround this we copy the wasm files manually
52+
// (note Deno 2 allows to vendor wasm files, but it also require modules to import them and not fetch and instantiate them
53+
// se being able to drop downloading is dependent on implementation of wasm handling in external modules as well)
54+
await Promise.all(
55+
wasmFilesToDownload.map(async (urlString) => {
56+
const url = new URL(urlString)
57+
58+
const destination = join(vendorDest, url.hostname, url.pathname)
59+
60+
const res = await fetch(url)
61+
if (!res.ok)
62+
throw new Error(`Failed to fetch .wasm file to vendor. Response status: ${res.status}`)
63+
const fileStream = createWriteStream(destination, { flags: 'wx' })
64+
await finished(Readable.fromWeb(res.body).pipe(fileStream))
65+
}),
66+
)
67+
}
68+
69+
console.log(`✅ Vendored Deno modules for '${vendorSource}' into '${vendorDest}'`)
70+
}

‎tools/build.js‎

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
1-
import { createWriteStream } from 'node:fs'
21
import { cp, readFile, rm } from 'node:fs/promises'
32
import { dirname, join, resolve } from 'node:path'
43
import { fileURLToPath } from 'node:url'
5-
import { Readable } from 'stream'
6-
import { finished } from 'stream/promises'
74

85
import { build, context } from 'esbuild'
9-
import { execaCommand } from 'execa'
106
import glob from 'fast-glob'
117

8+
import { vendorDeno } from './build-helpers.js'
9+
1210
const OUT_DIR = 'dist'
1311
await rm(OUT_DIR, { force: true, recursive: true })
1412

@@ -83,47 +81,22 @@ async function bundle(entryPoints, format, watch) {
8381
})
8482
}
8583

86-
async function vendorDeno() {
84+
async function vendorMiddlewareDenoModules() {
8785
const vendorSource = resolve('edge-runtime/vendor.ts')
88-
const vendorDest = resolve('edge-runtime/vendor')
89-
90-
try {
91-
await execaCommand('deno --version')
92-
} catch {
93-
throw new Error('Could not check the version of Deno. Is it installed on your system?')
94-
}
95-
96-
console.log(`🧹 Deleting '${vendorDest}'...`)
97-
98-
await rm(vendorDest, { force: true, recursive: true })
86+
const middlewareDir = resolve('edge-runtime')
9987

100-
console.log(`📦 Vendoring Deno modules into '${vendorDest}'...`)
101-
102-
await execaCommand(`deno vendor ${vendorSource} --output=${vendorDest} --force`)
103-
104-
// htmlrewriter contains wasm files and those don't currently work great with vendoring
105-
// see https://github.com/denoland/deno/issues/14123
106-
// to workaround this we copy the wasm files manually
107-
const filesToDownload = ['https://deno.land/x/htmlrewriter@v1.0.0/pkg/htmlrewriter_bg.wasm']
108-
await Promise.all(
109-
filesToDownload.map(async (urlString) => {
110-
const url = new URL(urlString)
111-
112-
const destination = join(vendorDest, url.hostname, url.pathname)
113-
114-
const res = await fetch(url)
115-
if (!res.ok) throw new Error('Failed to fetch .wasm file to vendor', { cause: err })
116-
const fileStream = createWriteStream(destination, { flags: 'wx' })
117-
await finished(Readable.fromWeb(res.body).pipe(fileStream))
118-
}),
119-
)
88+
await vendorDeno({
89+
vendorSource,
90+
cwd: middlewareDir,
91+
wasmFilesToDownload: ['https://deno.land/x/htmlrewriter@v1.0.0/pkg/htmlrewriter_bg.wasm'],
92+
})
12093
}
12194

12295
const args = new Set(process.argv.slice(2))
12396
const watch = args.has('--watch') || args.has('-w')
12497

12598
await Promise.all([
126-
vendorDeno(),
99+
vendorMiddlewareDenoModules(),
127100
bundle(entryPointsESM, 'esm', watch),
128101
...entryPointsCJS.map((entry) => bundle([entry], 'cjs', watch)),
129102
cp('src/build/templates', join(OUT_DIR, 'build/templates'), { recursive: true, force: true }),

‎tools/vendor-deno-tools.js‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { dirname, join } from 'node:path'
2+
import { fileURLToPath } from 'node:url'
3+
4+
import { vendorDeno } from './build-helpers.js'
5+
6+
const denoToolsDirectory = join(dirname(fileURLToPath(import.meta.url)), 'deno')
7+
8+
await vendorDeno({
9+
vendorSource: join(denoToolsDirectory, 'eszip.ts'),
10+
cwd: denoToolsDirectory,
11+
wasmFilesToDownload: ['https://deno.land/x/eszip@v0.55.4/eszip_wasm_bg.wasm'],
12+
initEmptyDenoJson: true,
13+
})

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /