Skip to content

Commit

Permalink
build: split vendor chunk (#856)
Browse files Browse the repository at this point in the history
* build: split vendor chunk

* build: enhance dts gen

* ci: use Node.js 22 as builder
  • Loading branch information
antongolub authored Jun 20, 2024
1 parent d6f5493 commit e45ae8d
Show file tree
Hide file tree
Showing 12 changed files with 197 additions and 137 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- run: npm ci
- run: npm test
env:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
node-version: 22
- run: npm ci
- run: npm test
env:
Expand Down
12 changes: 7 additions & 5 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20.x
- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 20.x
node-version: 22.x
- run: npm ci
- run: npm run build
- run: |
npm run build
cd build && ls -l
- uses: actions/upload-artifact@v4
with:
name: build
Expand Down Expand Up @@ -126,10 +128,10 @@ jobs:
ts: [4, 5]
steps:
- uses: actions/checkout@v4
- name: Use Node.js 20.x
- name: Use Node.js 22.x
uses: actions/setup-node@v4
with:
node-version: 20.x
node-version: 22.x
- name: Install deps
run: npm ci
- name: Install TypeScript ${{ matrix.ts }}
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
"build": "npm run build:js && npm run build:dts",
"build:check": "tsc",
"build:js": "node scripts/build-js.mjs --format=cjs --hybrid --entry=src/*.ts && npm run build:vendor",
"build:vendor": "node scripts/build-js.mjs --format=cjs --entry=src/vendor.ts --bundle=all",
"build:vendor": "node scripts/build-js.mjs --format=cjs --entry=src/vendor-*.ts --bundle=all",
"build:dts": "tsc --project tsconfig.prod.json && node scripts/build-dts.mjs",
"pretest": "npm run build",
"test": "npm run test:unit && npm run test:types && npm run test:license",
Expand All @@ -81,7 +81,7 @@
"test:smoke:cjs": "node ./test/smoke/node.test.cjs",
"test:smoke:mjs": "node ./test/smoke/node.test.mjs",
"test:smoke:deno": "deno test ./test/smoke/deno.test.js --allow-read --allow-sys --allow-env --allow-run",
"coverage": "c8 -x build/deno.js -x build/vendor.cjs -x build/esblib.cjs -x 'test/**' -x scripts --check-coverage npm test",
"coverage": "c8 -x build/deno.js -x build/vendor-extra.cjs -x build/vendor-core.cjs -x build/esblib.cjs -x 'test/**' -x scripts --check-coverage npm test",
"version": "cat package.json | fx .version"
},
"optionalDependencies": {
Expand Down
106 changes: 67 additions & 39 deletions scripts/build-dts.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -18,45 +18,62 @@ import fs from 'fs/promises'
import { generateDtsBundle } from 'dts-bundle-generator'
import glob from 'fast-glob'

const entry = {
filePath: './src/vendor.ts',
outFile: './build/vendor.d.ts',
libraries: {
allowedTypesLibraries: ['node'], // args['external-types'],
inlinedLibraries: [
'@nodelib/fs.stat',
'@nodelib/fs.scandir',
'@nodelib/fs.walk',
'fast-glob',
'@types/jsonfile',
'node-fetch-native',
'chalk',
'globby',
'@types/minimist',
'@types/which',
'zurk',
'@webpod/ps',
'@webpod/ingrid',
'depseek',
], // args['external-inlines'],
const output = {
inlineDeclareExternals: true,
inlineDeclareGlobals: true,
sortNodes: false,
exportReferencedTypes: false, //args['export-referenced-types'],
}
const entries = [
{
filePath: './src/vendor-extra.ts',
outFile: './build/vendor-extra.d.ts',
libraries: {
allowedTypesLibraries: ['node'], // args['external-types'],
inlinedLibraries: [
'@nodelib/fs.stat',
'@nodelib/fs.scandir',
'@nodelib/fs.walk',
'fast-glob',
'@types/jsonfile',
'node-fetch-native',
// 'chalk',
'globby',
// '@types/minimist',
// '@types/which',
// 'zurk',
// '@webpod/ps',
'@webpod/ingrid',
'depseek',
], // args['external-inlines'],
},
output,
},
output: {
inlineDeclareExternals: true,
inlineDeclareGlobals: true,
sortNodes: false,
exportReferencedTypes: false, //args['export-referenced-types'],
{
filePath: './src/vendor-core.ts',
outFile: './build/vendor-core.d.ts',
libraries: {
allowedTypesLibraries: ['node'], // args['external-types'],
inlinedLibraries: [
'@types/which',
'@webpod/ps',
'@webpod/ingrid',
'chalk',
'zurk',
], // args['external-inlines'],
},
output,
},
}
]

const compilationOptions = {
preferredConfigPath: './tsconfig.prod.json', // args.project,
followSymlinks: true,
}

let [result] = generateDtsBundle([entry], compilationOptions)

// generateDtsBundle cannot handle the circular refs on types inlining, so we need to help it manually:
/*
const results = generateDtsBundle(entries, compilationOptions)
// generateDtsBundle cannot handle the circular refs on types inlining, so we need to help it manually:
/*
build/vendor.d.ts(163,7): error TS2456: Type alias 'Options' circularly references itself.
build/vendor.d.ts(164,7): error TS2456: Type alias 'Entry' circularly references itself.
build/vendor.d.ts(165,7): error TS2456: Type alias 'Task' circularly references itself.
Expand All @@ -65,17 +82,28 @@ build/vendor.d.ts(167,7): error TS2456: Type alias 'FileSystemAdapter' circularl
build/vendor.d.ts(197,48): error TS2694: Namespace 'FastGlob' has no exported member 'FastGlobOptions
*/

result = result
.replace('type Options = Options;', 'export {Options};')
.replace('type Task = Task;', 'export {Task};')
.replace('type Pattern = Pattern;', 'export {Pattern};')
.replace('FastGlob.FastGlobOptions', 'FastGlob.Options')
.replace('type Entry =', 'export type Entry =')
.map((r) =>
r
.replace('type Options = Options;', 'export {Options};')
.replace('type Task = Task;', 'export {Task};')
.replace('type Pattern = Pattern;', 'export {Pattern};')
.replace('FastGlob.FastGlobOptions', 'FastGlob.Options')
.replace('type Entry =', 'export type Entry =')
)

await fs.writeFile(entry.outFile, result, 'utf8')
for (const i in results) {
const entry = entries[i]
const result = results[i]

await fs.writeFile(entry.outFile, result, 'utf8')
}

// Replaces redundant triple-slash directives
for (const dts of await glob(['build/**/*.d.ts', '!build/vendor.d.ts'])) {
for (const dts of await glob([
'build/**/*.d.ts',
'!build/vendor.d.ts',
'!build/core-vendor.d.ts',
])) {
const contents = (await fs.readFile(dts, 'utf8'))
.split('\n')
.filter((line) => !line.startsWith('/// <reference types'))
Expand Down
2 changes: 1 addition & 1 deletion scripts/build-js.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ const {
const formats = format.split(',')
const plugins = []
const cwd = Array.isArray(_cwd) ? _cwd[_cwd.length - 1] : _cwd
const entries = entry.split(/,\s?/)
const entries = entry.split(/:\s?/)
const entryPoints = entry.includes('*')
? await glob(entries, { absolute: false, onlyFiles: true, cwd, root: cwd })
: entries.map((p) => path.relative(cwd, path.resolve(cwd, p)))
Expand Down
2 changes: 1 addition & 1 deletion src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
type RequestInfo,
type RequestInit,
type TSpawnStore,
} from './vendor.js'
} from './vendor-core.js'
import {
type Duration,
errnoMessage,
Expand Down
35 changes: 18 additions & 17 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@

import os from 'node:os'
import path from 'node:path'
import { chalk, parseLine, fs } from './vendor.js'
import fs from 'node:fs'
import { chalk } from './vendor-core.js'

export function tempdir(prefix = `zx-${randomId()}`) {
const dirpath = path.join(os.tmpdir(), prefix)
Expand Down Expand Up @@ -68,22 +69,22 @@ export function preferNmBin(
}
}

export function normalizeMultilinePieces(
pieces: TemplateStringsArray
): TemplateStringsArray {
return Object.assign(
pieces.map((p, i) =>
p.trim()
? pad(p[0]) +
parseLine(p)
.words.map(({ w }) => (w === '\\' ? '' : w.trim()))
.join(' ') +
pad(p[p.length - 1])
: pieces[i]
),
{ raw: pieces.raw }
)
}
// export function normalizeMultilinePieces(
// pieces: TemplateStringsArray
// ): TemplateStringsArray {
// return Object.assign(
// pieces.map((p, i) =>
// p.trim()
// ? pad(p[0]) +
// parseLine(p)
// .words.map(({ w }) => (w === '\\' ? '' : w.trim()))
// .join(' ') +
// pad(p[p.length - 1])
// : pieces[i]
// ),
// { raw: pieces.raw }
// )
// }

export function quote(arg: string) {
if (/^[a-z0-9/_.\-@:=]+$/i.test(arg) || arg === '') {
Expand Down
22 changes: 22 additions & 0 deletions src/vendor-core.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

export { exec, buildCmd, type TSpawnStore } from 'zurk/spawn'

export type RequestInfo = Parameters<typeof fetch>[0]
export type RequestInit = Parameters<typeof fetch>[1]

export { default as chalk, type ChalkInstance } from 'chalk'
export { default as which } from 'which'
export { default as ps } from '@webpod/ps'
68 changes: 68 additions & 0 deletions src/vendor-extra.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import { URL } from 'node:url'
import {
convertPathToPattern,
globby,
globbySync,
globbyStream,
generateGlobTasksSync,
generateGlobTasks,
isGitIgnoredSync,
isGitIgnored,
isDynamicPattern,
type Options as GlobbyOptions,
} from 'globby'
import * as yaml from 'yaml'
import * as _fs from 'fs-extra'
import _createRequire from 'create-require'
import { type fetch, AbortController } from 'node-fetch-native'

export { fetch as nodeFetch } from 'node-fetch-native'

global.AbortController = global.AbortController || AbortController

export const createRequire = _createRequire as unknown as (
filename: string | URL
) => NodeRequire

export const globbyModule = {
convertPathToPattern,
globby,
globbySync,
globbyStream,
generateGlobTasksSync,
generateGlobTasks,
isGitIgnoredSync,
isGitIgnored,
isDynamicPattern,
}

export const glob = Object.assign(function globby(
patterns: string | readonly string[],
options?: GlobbyOptions
) {
return globbyModule.globby(patterns, options)
}, globbyModule) as (typeof globbyModule)['globby'] & typeof globbyModule

export const YAML: {
parse(text: string): any
stringify(object: any): string
} = yaml

export const fs: typeof import('fs-extra') = _fs

export { depseekSync as depseek } from 'depseek'
export { default as minimist } from 'minimist'
Loading

0 comments on commit e45ae8d

Please sign in to comment.