From 3daefc23de2573a74b1df016b45aae14ed22736d Mon Sep 17 00:00:00 2001 From: Vitaly Date: Mon, 4 Sep 2023 10:46:53 +0300 Subject: [PATCH] build prismarine-viewer locally which should increase install speed --- package.json | 1 - prismarine-viewer/buildWorker.mjs | 62 +++++++++++++++ prismarine-viewer/esbuild.mjs | 120 ++++++++++++++++++++++++++++++ prismarine-viewer/package.json | 3 +- scripts/build.js | 14 ++-- 5 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 prismarine-viewer/buildWorker.mjs create mode 100644 prismarine-viewer/esbuild.mjs diff --git a/package.json b/package.json index 16ade0e4..162db4d6 100644 --- a/package.json +++ b/package.json @@ -83,7 +83,6 @@ "os-browserify": "^0.3.0", "path-browserify": "^1.0.1", "prismarine-viewer": "./prismarine-viewer", - "prismarine-viewer2": "github:PrismarineJS/prismarine-viewer", "process": "github:PrismarineJS/node-process", "rimraf": "^5.0.1", "stream-browserify": "^3.0.0", diff --git a/prismarine-viewer/buildWorker.mjs b/prismarine-viewer/buildWorker.mjs new file mode 100644 index 00000000..c78a767e --- /dev/null +++ b/prismarine-viewer/buildWorker.mjs @@ -0,0 +1,62 @@ +import { context } from 'esbuild' +import { build } from 'esbuild' +import { polyfillNode } from 'esbuild-plugin-polyfill-node' +import path from 'path' +import { fileURLToPath } from 'url' + +const allowedWorkerFiles = ['blocks', 'blockCollisionShapes', 'tints', 'blockStates', + 'biomes', 'features', 'version', 'legacy', 'versions', 'version', 'protocolVersions'] + +const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url))) + +/** @type {import('esbuild').BuildOptions} */ +const buildOptions = { + bundle: true, + banner: { + js: 'globalThis.global = globalThis;process = {env: {}, versions: {}, };', + }, + platform: 'browser', + entryPoints: [path.join(__dirname, './viewer/lib/worker.js')], + outfile: path.join(__dirname, './public/worker.js'), + minify: true, + drop: [ + 'debugger' + ], + sourcemap: true, + plugins: [ + { + name: 'external-json', + setup (build) { + build.onResolve({ filter: /\.json$/ }, args => { + const fileName = args.path.split('/').pop().replace('.json', '') + if (args.resolveDir.includes('minecraft-data') && !allowedWorkerFiles.includes(fileName)) { + // console.log('skipped', fileName) + return { path: args.path, namespace: 'empty-file', } + } + }) + build.onResolve({ + filter: /^zlib$/, + }, ({ path }) => { + return { + path, + namespace: 'empty-file', + } + }) + build.onLoad({ + filter: /.*/, + namespace: 'empty-file', + }, () => { + return { contents: 'module.exports = undefined', loader: 'js' } + }) + } + }, + polyfillNode(), + ], +} + +if (process.argv.includes('-w')) { + const ctx = await context(buildOptions) + await ctx.watch() +} else { + await build(buildOptions) +} diff --git a/prismarine-viewer/esbuild.mjs b/prismarine-viewer/esbuild.mjs new file mode 100644 index 00000000..adad2955 --- /dev/null +++ b/prismarine-viewer/esbuild.mjs @@ -0,0 +1,120 @@ +import * as fs from 'fs' + +//@ts-check +import * as esbuild from 'esbuild' +import { polyfillNode } from 'esbuild-plugin-polyfill-node' +import path, { dirname, join } from 'path' +import { fileURLToPath } from 'url' + +const dev = !process.argv.includes('-p') + +const __dirname = path.dirname(fileURLToPath(new URL(import.meta.url))) + +/** @type {import('esbuild').BuildOptions} */ +const buildOptions = { + bundle: true, + // entryPoints: [join(__dirname, 'lib/index.js')], + entryPoints: [join(__dirname, './examples/schematic.js')], + // target: ['es2020'], + // logLevel: 'debug', + logLevel: 'info', + platform: 'browser', + sourcemap: dev, + outfile: join(__dirname, 'public/index.js'), + mainFields: [ + 'browser', 'module', 'main' + ], + keepNames: true, + banner: { + js: 'globalThis.global = globalThis;', + }, + alias: { + events: 'events', + buffer: 'buffer', + 'fs': 'browserfs/dist/shims/fs.js', + http: 'http-browserify', + stream: 'stream-browserify', + net: 'net-browserify', + }, + inject: [], + metafile: true, + plugins: [ + { + name: 'data-handler', + setup (build) { + const customMcDataNs = 'custom-mc' + build.onResolve({ + filter: /.*/, + }, ({ path, ...rest }) => { + if (join(rest.resolveDir, path).replaceAll('\\', '/').endsWith('minecraft-data/data.js')) { + return { + path, + namespace: customMcDataNs, + } + } + return undefined + }) + build.onLoad({ + filter: /.*/, + namespace: customMcDataNs, + }, async ({ path, ...rest }) => { + const resolvedPath = await build.resolve('minecraft-data/minecraft-data/data/dataPaths.json', { kind: 'require-call', resolveDir: process.cwd() }) + const dataPaths = JSON.parse(await fs.promises.readFile(resolvedPath.path, 'utf8')) + + // bedrock unsupported + delete dataPaths.bedrock + + const allowOnlyList = process.env.ONLY_MC_DATA?.split(',') ?? [] + + // skip data for 0.30c, snapshots and pre-releases + const includeVersions = ['1.16.4'] + + const includedVersions = [] + let contents = 'module.exports =\n{\n' + for (const platform of Object.keys(dataPaths)) { + contents += ` '${platform}': {\n` + for (const version of Object.keys(dataPaths[platform])) { + if (allowOnlyList.length && !allowOnlyList.includes(version)) continue + if (!includeVersions.includes(version)) continue + + includedVersions.push(version) + contents += ` '${version}': {\n` + for (const dataType of Object.keys(dataPaths[platform][version])) { + const loc = `minecraft-data/data/${dataPaths[platform][version][dataType]}/` + contents += ` get ${dataType} () { return require("./${loc}${dataType}.json") },\n` + } + contents += ' },\n' + } + contents += ' },\n' + } + contents += '}\n' + + return { + contents, + loader: 'js', + resolveDir: join(dirname(resolvedPath.path), '../..'), + } + }) + } + }, + polyfillNode({ + polyfills: { + fs: false, + crypto: false, + events: false, + http: false, + stream: false, + buffer: false, + perf_hooks: false, + net: false, + }, + }) + ], +} +if (process.argv.includes('-w')) { + (await esbuild.context(buildOptions)).watch() +} else { + await esbuild.build(buildOptions) +} + +// await ctx.rebuild() diff --git a/prismarine-viewer/package.json b/prismarine-viewer/package.json index 75383299..85af5c9c 100644 --- a/prismarine-viewer/package.json +++ b/prismarine-viewer/package.json @@ -7,7 +7,8 @@ "test": "jest --verbose --runInBand --forceExit", "pretest": "npm run lint", "lint": "standard", - "fix": "standard --fix" + "fix": "standard --fix", + "postinstall": "node viewer/prerender.js && node buildWorker.mjs" }, "author": "PrismarineJS", "license": "MIT", diff --git a/scripts/build.js b/scripts/build.js index e71413b0..53d669bc 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -7,14 +7,15 @@ const path = require('path') // these files need to be copied before build for now const filesAlwaysToCopy = [ - { from: './node_modules/prismarine-viewer2/public/supportedVersions.json', to: './prismarine-viewer/public/supportedVersions.json' }, + // { from: './node_modules/prismarine-viewer2/public/supportedVersions.json', to: './prismarine-viewer/public/supportedVersions.json' }, ] // these files could be copied at build time eg with copy plugin, but copy plugin slows down the config (2x in my testing, sometimes with too many open files error) is slow so we also copy them there const webpackFilesToCopy = [ - { from: './node_modules/prismarine-viewer2/public/blocksStates/', to: 'dist/blocksStates/' }, - // { from: './node_modules/prismarine-viewer2/public/textures/', to: 'dist/textures/' }, - { from: './node_modules/prismarine-viewer2/public/worker.js', to: 'dist/worker.js' }, - { from: './node_modules/prismarine-viewer2/public/supportedVersions.json', to: 'dist/supportedVersions.json' }, + { from: './prismarine-viewer/public/blocksStates/', to: 'dist/blocksStates/' }, + // { from: './prismarine-viewer/public/textures/', to: 'dist/textures/' }, + // { from: './prismarine-viewer/public/textures/1.17.1/gui', to: 'dist/gui' }, + { from: './prismarine-viewer/public/worker.js', to: 'dist/worker.js' }, + // { from: './prismarine-viewer/public/supportedVersions.json', to: 'dist/supportedVersions.json' }, { from: './assets/', to: './dist/' }, { from: './config.json', to: 'dist/config.json' } ] @@ -24,7 +25,8 @@ exports.copyFiles = (isDev = false) => { [...filesAlwaysToCopy, ...webpackFilesToCopy].forEach(file => { fsExtra.copySync(file.from, file.to) }) - const cwd = './node_modules/prismarine-viewer2/public/textures/' + // todo copy directly only needed + const cwd = './prismarine-viewer/public/textures/' const files = glob.sync('{*/entity/**,*.png}', { cwd: cwd, nodir: true, }) for (const file of files) { const copyDest = path.join('dist/textures/', file)