diff options
author | 2022-03-07 15:36:22 -0600 | |
---|---|---|
committer | 2022-03-07 15:36:22 -0600 | |
commit | f18ee36dc0abdc5c8ec87734de7962966d16fe65 (patch) | |
tree | c01a7034186cb0bbe5e1d042f4a5dd09bad21ed5 /packages/webapi/run/build.js | |
parent | 10a9c3412b4f6e8607687a74eafdb150d3222047 (diff) | |
download | astro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.tar.gz astro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.tar.zst astro-f18ee36dc0abdc5c8ec87734de7962966d16fe65.zip |
Add `@astrojs/webapi` package (#2729)@astrojs/webapi@0.11.0
* chore: add @astrojs/webapi
* chore: update package.json
* fix: update file case
* fix: remove lowercase file
* chore: update tests to use mocha
* chore: update LICENSE
Diffstat (limited to 'packages/webapi/run/build.js')
-rw-r--r-- | packages/webapi/run/build.js | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/packages/webapi/run/build.js b/packages/webapi/run/build.js new file mode 100644 index 000000000..dd7687392 --- /dev/null +++ b/packages/webapi/run/build.js @@ -0,0 +1,190 @@ +import { rollup } from 'rollup' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import { posix as path } from 'node:path' +import { createRequire } from 'node:module' +import { readFile as nodeReadFile, rename, rm, writeFile } from 'node:fs/promises' +import { default as MagicString } from 'magic-string' +import { default as alias } from '@rollup/plugin-alias' +import { default as inject } from '@rollup/plugin-inject' +import { default as typescript } from '@rollup/plugin-typescript' + +const readFileCache = Object.create(null) +const require = createRequire(import.meta.url) + +const readFile = (/** @type {string} */ id) => readFileCache[id] || (readFileCache[id] = nodeReadFile(id, 'utf8')) + +const pathToDOMException = path.resolve('src', 'lib', 'DOMException.js') +const pathToEventTargetShim = path.join('..', '..', 'node_modules', 'event-target-shim', 'index.mjs') +const pathToStructuredClone = path.join('..', '..', 'node_modules', '@ungap', 'structured-clone', 'esm', 'index.js') + +const plugins = [ + typescript({ + tsconfig: './tsconfig.json', + }), + alias({ + entries: [ + { find: '@ungap/structured-clone', replacement: pathToStructuredClone }, + { find: 'event-target-shim', replacement: pathToEventTargetShim }, + { find: 'event-target-shim/dist/event-target-shim.js', replacement: pathToEventTargetShim }, + { find: 'event-target-shim/dist/event-target-shim.umd.js', replacement: pathToEventTargetShim }, + { find: 'node-domexception', replacement: pathToDOMException }, + ], + }), + nodeResolve({ + dedupe: [ + 'net', + 'node:net' + ] + }), + inject({ + // import { Promise as P } from 'es6-promise' + // P: [ 'es6-promise', 'Promise' ], + + 'AbortController': [ 'abort-controller/dist/abort-controller.mjs', 'AbortController' ], + 'Blob': [ 'fetch-blob/from.js', 'Blob' ], + 'DOMException': [pathToDOMException, 'DOMException'], + 'Document': [ './Document', 'Document' ], + 'Element': [ './Element', 'Element' ], + 'Event': [ 'event-target-shim', 'Event' ], + 'EventTarget': [ 'event-target-shim', 'EventTarget' ], + 'defineEventAttribute': [ 'event-target-shim', 'defineEventAttribute' ], + 'HTMLElement': ['./Element', 'HTMLElement'], + 'HTMLImageElement': ['./Element', 'HTMLImageElement'], + 'HTMLUnknownElement': ['./Element', 'HTMLUnknownElement'], + 'MediaQueryList': [ './MediaQueryList', 'MediaQueryList' ], + 'Node': [ './Node', 'Node' ], + 'ReadableStream': [ 'web-streams-polyfill/dist/ponyfill.es6.mjs', 'ReadableStream' ], + 'ShadowRoot': [ './Node', 'ShadowRoot' ], + 'Window': [ './Window', 'Window' ], + 'globalThis.ReadableStream': [ 'web-streams-polyfill/dist/ponyfill.es6.mjs', 'ReadableStream' ], + }), + { + async load(id) { + const pathToEsm = id + const pathToMap = `${pathToEsm}.map` + + const code = await readFile(pathToEsm, 'utf8') + + const indexes = [] + + const replacements = [ + // remove unused imports + [ /(^|\n)import\s+[^']+'node:(buffer|fs|path|worker_threads)'/g, `` ], + [ /const \{ stat \} = fs/g, `` ], + + // remove unused polyfill utils + [ /\nif \(\s*typeof Global[\W\w]+?\n\}/g, `` ], + [ /\nif \(\s*typeof window[\W\w]+?\n\}/g, `` ], + [ /\nif \(!globalThis\.ReadableStream\) \{[\W\w]+?\n\}/g, `` ], + [ /\nif \(typeof SymbolPolyfill[\W\w]+?\n\}/g, `` ], + + // remove unused polyfills + [ /\nconst globals = getGlobals\(\);/g, `` ], + [ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\);/g, ``], + [ /\nconst NativeDOMException =[^;]+;/g, `` ], + [ /\nconst SymbolPolyfill\s*=[^;]+;/g, '\nconst SymbolPolyfill = Symbol;'], + [ /\n(const|let) DOMException[^;]*;/g, `let DOMException$1=DOMException` ], + [ /\nconst DOMException = globalThis.DOMException[\W\w]+?\}\)\(\)/g, `` ], + [ /\nimport DOMException from 'node-domexception'/g, `` ], + + // use shared AbortController methods + [ / new DOMException\$1/g, `new DOMException` ], + [ / from 'net'/g, `from 'node:net'` ], + [ / throw createInvalidStateError/g, `throw new DOMException` ], + [ /= createAbortController/g, `= new AbortController` ], + [ /\nconst queueMicrotask = [\W\w]+?\n\}\)\(\)\;/g, `` ], + + // remove Body.prototype.buffer deprecation notice + [ /\nBody\.prototype\.buffer[^\n]+/g, `` ], + + // remove Body.prototype.data deprecation notice + [ /\n data: \{get: deprecate[\W\w]+?\)\}/g, `` ], + ] + + for (const [replacee, replacer] of replacements) { + replacee.index = 0 + + let replaced = null + + while ((replaced = replacee.exec(code)) !== null) { + const leadIndex = replaced.index + const tailIndex = replaced.index + replaced[0].length + + indexes.unshift([ leadIndex, tailIndex, replacer ]) + } + } + + if (indexes.length) { + const magicString = new MagicString(code) + + indexes.sort( + ([leadOfA], [leadOfB]) => leadOfA - leadOfB + ) + + for (const [leadIndex, tailindex, replacer] of indexes) { + magicString.overwrite(leadIndex, tailindex, replacer) + } + + const magicMap = magicString.generateMap({ source: pathToEsm, file: pathToMap, includeContent: true }) + + const modifiedEsm = magicString.toString() + const modifiedMap = magicMap.toString() + + return { code: modifiedEsm, map: modifiedMap } + } + }, + }, +] + +async function build() { + const configs = [ + { + inputOptions: { + input: 'src/polyfill.ts', + plugins: plugins, + onwarn(warning, warn) { + if (warning.code !== 'UNRESOLVED_IMPORT') warn(warning) + }, + }, + outputOptions: { + inlineDynamicImports: true, + file: 'mod.js', + format: 'esm', + sourcemap: true, + }, + }, + ] + + for (const config of configs) { + const bundle = await rollup(config.inputOptions) + + // or write the bundle to disk + await bundle.write(config.outputOptions) + + // closes the bundle + await bundle.close() + + // delete the lib directory + await rm('lib', { force: true, recursive: true }) + await rm('exclusions.d.ts', { force: true, recursive: true }) + await rm('exclusions.d.ts.map', { force: true, recursive: true }) + await rm('inheritence.d.ts', { force: true, recursive: true }) + await rm('inheritence.d.ts.map', { force: true, recursive: true }) + await rm('polyfill.d.ts.map', { force: true, recursive: true }) + await rm('polyfill.js.map', { force: true, recursive: true }) + await rm('polyfill.js', { force: true, recursive: true }) + await rm('ponyfill.d.ts', { force: true, recursive: true }) + await rm('ponyfill.d.ts.map', { force: true, recursive: true }) + await rm('ponyfill.js.map', { force: true, recursive: true }) + await rm('ponyfill.js', { force: true, recursive: true }) + + await rename('polyfill.d.ts', 'mod.d.ts') + + const modDTS = await readFile('./mod.d.ts') + + writeFile('mod.d.ts', modDTS.replace('\n//# sourceMappingURL=polyfill.d.ts.map', '').replace('ponyfill.js', 'mod.js')) + writeFile('apply.js', `import { polyfill } from './mod.js'\n\nexport * from './mod.js'\n\npolyfill(globalThis)\n`) + } +} + +build() |