Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 121 additions & 7 deletions .config/vite.config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { readFileSync, readdirSync, rmSync } from 'node:fs'
import { readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs'
import { dirname, resolve } from 'node:path'
import { fileURLToPath } from 'node:url'

import { parse } from 'acorn'
import { rollup } from 'rollup'
import dts from 'rollup-plugin-dts'
import { defineConfig } from 'vite'
Expand All @@ -11,7 +12,8 @@ const packageJsonPath = process.env.npm_package_json || resolve(root, 'package.j
const packageRoot = dirname(packageJsonPath)
const pkg = JSON.parse(readFileSync(packageJsonPath).toString())
const isRootPackage = packageRoot === root
const packageName = pkg.name.split('/').at(-1)
const libraryName = toLibraryName(pkg.name)
const packageGlobals = getPackageGlobals()
const entry = isRootPackage
? resolve(root, 'src/index.js')
: resolve(packageRoot, 'index.js')
Expand Down Expand Up @@ -47,30 +49,49 @@ export default defineConfig({
}
} : {}),
plugins: [
jsCommentStripPlugin(),
declarationBundlePlugin()
],
build: {
outDir: resolve(packageRoot, 'dist'),
lib: {
entry,
formats: ['es'],
fileName: () => 'index.module.js'
name: libraryName,
formats: ['es', 'umd'],
fileName: (format) => `index.${format === 'es' ? 'module' : format}.js`
},
target: 'es2020',
minify: 'esbuild',
target: 'esnext',
minify: false,
esbuild: {
keepNames: true
},
rollupOptions: {
external: isPackageExternal,
output: {
banner,
exports: 'named'
exports: 'named',
globals: packageGlobals
}
}
}
})

function jsCommentStripPlugin() {
return {
name: 'js-comment-strip',
apply: 'build',
/**
* @param {string} code
*/
async renderChunk(code) {
const bannerPrefix = code.startsWith(banner) ? banner : ''
const body = bannerPrefix ? code.slice(bannerPrefix.length) : code

return `${bannerPrefix}${stripJsComments(body)}`
}
}
}

function declarationBundlePlugin() {
return {
name: 'declaration-bundle',
Expand Down Expand Up @@ -104,6 +125,7 @@ function declarationBundlePlugin() {
file: resolve(packageRoot, 'dist/index.d.ts'),
format: 'es'
})
stripImportJsdocComments(resolve(packageRoot, 'dist/index.d.ts'))
await bundle.close()
if (isRootPackage) {
rmSync(resolve(packageRoot, 'types'), { recursive: true, force: true })
Expand All @@ -112,6 +134,68 @@ function declarationBundlePlugin() {
}
}

/**
* Removes line and block comments from generated JavaScript chunks.
* The bundle banner is injected after renderChunk, so it stays intact.
*
* @param {string} code
* @returns {string}
*/
function stripJsComments(code) {
/** @type {{ block: boolean, start: number, end: number }[]} */
const comments = []

parse(code, {
ecmaVersion: 'latest',
onComment(block, _text, start, end) {
comments.push({ block, start, end })
},
sourceType: 'module'
})

if (!comments.length) {
return code
}

let stripped = ''
let cursor = 0

for (const comment of comments) {
stripped += code.slice(cursor, comment.start)

if (comment.block) {
const left = code[comment.start - 1]
const right = code[comment.end]

if (left && right && !/\s/.test(left) && !/\s/.test(right)) {
stripped += ' '
}
}

cursor = comment.end
}

stripped += code.slice(cursor)

return stripped
}

/**
* Removes JSDoc import-only comment blocks from generated declaration files.
*
* @param {string} filePath
*/
function stripImportJsdocComments(filePath) {
const contents = readFileSync(filePath, 'utf8')
const stripped = contents.replace(/\/\*\*[\s\S]*?\*\//g, (block) => (
block.includes('@import') ? '' : block
))

if (stripped !== contents) {
writeFileSync(filePath, stripped)
}
}

function getPackageDeclarationPaths() {
return Object.fromEntries(
readdirSync(resolve(root, 'packages'), { withFileTypes: true })
Expand All @@ -122,3 +206,33 @@ function getPackageDeclarationPaths() {
])
)
}

/**
* Returns the UMD global names for workspace packages.
*
* @returns {Record<string, string>}
*/
function getPackageGlobals() {
return Object.fromEntries(
readdirSync(resolve(root, 'packages'), { withFileTypes: true })
.filter((entry) => entry.isDirectory())
.map(({ name }) => [
`@wimaengine/${name}`,
toLibraryName(`@wimaengine/${name}`)
])
)
}

/**
* Converts a package name to a valid UMD global identifier.
*
* @param {string} name
* @returns {string}
*/
function toLibraryName(name) {
return name
.replace(/^@/, '')
.replace(/\//g, '_')
.replace(/-/g, '_')
.toUpperCase()
}
22 changes: 17 additions & 5 deletions .github/workflows/pull-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jobs:
outputs:
source: ${{ steps.filter.outputs.source }}
examples: ${{ steps.filter.outputs.examples }}
config: ${{ steps.filter.outputs.config }}
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -28,9 +29,17 @@ jobs:
- 'addons/**'
examples:
- 'examples/**'
config:
- '.config/**'
- '.github/workflows/**'
- 'package.json'
- 'package-lock.json'
- 'scripts/**'
- 'turbo.json'
- 'tsconfig.json'
lint-source:
needs: changes
if: needs.changes.outputs.source == 'true'
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.config == 'true' }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
Expand All @@ -39,18 +48,20 @@ jobs:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build
- run: npm run lint:src-dry -- --max-warnings=0
lint-examples:
needs: changes
if: needs.changes.outputs.examples == 'true'
if: ${{ needs.changes.outputs.examples == 'true' || needs.changes.outputs.config == 'true' }}
runs-on: ubuntu-latest
steps:
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build
- run: npm run lint:examples-dry -- --max-warnings=0
tests:
needs: compiles
Expand All @@ -62,6 +73,7 @@ jobs:
node-version: 24
cache: npm
- run: npm ci
- run: npm run build
- run: npm run test
builds:
needs: compiles
Expand All @@ -76,9 +88,9 @@ jobs:
- run: npm run build
compiles:
needs: changes
if: needs.changes.outputs.source == 'true'
if: ${{ needs.changes.outputs.source == 'true' || needs.changes.outputs.config == 'true' }}
runs-on: ubuntu-latest
steps:
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v6
with:
Expand Down
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@
"name": "wima",
"version": "0.3.0",
"description": "An ECS driven modular game engine.",
"homepage": "https://wimaengine.github.io/wima/",
"homepage": "https://wimaengine.org",
"bugs": {
"url": "https://github.com/wimaengine/wima/issues"
},
"type": "module",
"license": "SEE LICENSE in LICENSE.txt",
"main": "./dist/index.module.js",
"main": "./dist/index.umd.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.module.js"
"import": "./dist/index.module.js",
"require": "./dist/index.umd.js"
}
},
"author": "Wima engine contributors",
Expand All @@ -35,7 +36,7 @@
"build:docs": "npm run typedoc",
"types": "turbo run types //#types:root",
"test": "turbo run test",
"build": "npm run clean:build && turbo run build && turbo run //#build:root //#build:docs",
"build": "turbo run build && turbo run //#build:root //#build:docs",
"lint": "npm run lint:src && npm run lint:examples",
"version": "changeset version",
"check:release-version": "node scripts/check-release-version.js",
Expand All @@ -49,7 +50,7 @@
"tsc:lint": "tsc -p .config/tsc.lint.json",
"watch:src": "vite build --watch --config .config/vite.config.js",
"watch:docs": "npm run typedoc -- --watch",
"clean:build": "rm -rf dist types packages/*/types"
"clean:build": "rm -rf dist types packages/*/types packages/*/dist"
},
"keywords": [
"game",
Expand Down
14 changes: 5 additions & 9 deletions packages/animation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@
"type": "git",
"url": "https://github.com/wimaengine/wima.git"
},
"homepage": "https://wimaengine.github.io/wima/",
"homepage": "https://wimaengine.org",
"bugs": {
"url": "https://github.com/wimaengine/wima/issues"
},
"main": "./index.js",
"main": "./dist/index.umd.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./index.js"
},
"./src": {
"types": "./dist/src/index.d.ts",
"import": "./src/index.js"
"import": "./dist/index.module.js",
"require": "./dist/index.umd.js"
}
},
"files": [
"index.js",
"src"
"dist"
],
"scripts": {
"build": "vite build --config ../../.config/vite.config.js",
Expand Down
14 changes: 5 additions & 9 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@
"type": "git",
"url": "https://github.com/wimaengine/wima.git"
},
"homepage": "https://wimaengine.github.io/wima/",
"homepage": "https://wimaengine.org",
"bugs": {
"url": "https://github.com/wimaengine/wima/issues"
},
"main": "./index.js",
"main": "./dist/index.umd.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./index.js"
},
"./src": {
"types": "./dist/src/index.d.ts",
"import": "./src/index.js"
"import": "./dist/index.module.js",
"require": "./dist/index.umd.js"
}
},
"files": [
"index.js",
"src"
"dist"
],
"scripts": {
"build": "vite build --config ../../.config/vite.config.js",
Expand Down
14 changes: 5 additions & 9 deletions packages/asset/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@
"type": "git",
"url": "https://github.com/wimaengine/wima.git"
},
"homepage": "https://wimaengine.github.io/wima/",
"homepage": "https://wimaengine.org",
"bugs": {
"url": "https://github.com/wimaengine/wima/issues"
},
"main": "./index.js",
"main": "./dist/index.umd.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./index.js"
},
"./src": {
"types": "./dist/src/index.d.ts",
"import": "./src/index.js"
"import": "./dist/index.module.js",
"require": "./dist/index.umd.js"
}
},
"files": [
"index.js",
"src"
"dist"
],
"scripts": {
"build": "vite build --config ../../.config/vite.config.js",
Expand Down
Loading