diff --git a/bin/build-lib.js b/bin/build-lib.js deleted file mode 100644 index e185ebb54e..0000000000 --- a/bin/build-lib.js +++ /dev/null @@ -1,147 +0,0 @@ -const babel = require('@babel/core') -const t = require('@babel/types') -const { promisify } = require('node:util') -const glob = promisify(require('glob')) -const fs = require('node:fs') -const path = require('node:path') - -const { mkdir, stat, writeFile } = fs.promises - -const PACKAGE_JSON_IMPORT = /^\..*\/package.json$/ -const SOURCE = 'packages/{*,@uppy/*}/src/**/*.{js,ts}?(x)' -// Files not to build (such as tests) -const IGNORE = /\.test\.jsx?$|\.test\.tsx?$|__mocks__|svelte|angular|companion\//; -// Files that should trigger a rebuild of everything on change -const META_FILES = [ - 'babel.config.js', - 'package.json', - 'package-lock.json', - 'yarn.lock', - 'bin/build-lib.js', -] - -function lastModified (file, createParentDir = false) { - return stat(file).then((s) => s.mtime, async (err) => { - if (err.code === 'ENOENT') { - if (createParentDir) { - await mkdir(path.dirname(file), { recursive: true }) - } - return 0 - } - throw err - }) -} - -const versionCache = new Map() - -async function preparePackage (file) { - const packageFolder = file.slice(0, file.indexOf('/src/')) - if (versionCache.has(packageFolder)) return - - // eslint-disable-next-line import/no-dynamic-require, global-require - const { version } = require(path.join(__dirname, '..', packageFolder, 'package.json')) - if (process.env.FRESH) { - // in case it hasn't been done before. - await mkdir(path.join(packageFolder, 'lib'), { recursive: true }) - } - versionCache.set(packageFolder, version) -} - -const nonJSImport = /^\.\.?\/.+\.([jt]sx|ts)$/ -// eslint-disable-next-line no-shadow -function rewriteNonJSImportsToJS (path) { - const match = nonJSImport.exec(path.node.source.value) - if (match) { - // eslint-disable-next-line no-param-reassign - path.node.source.value = `${match[0].slice(0, -match[1].length)}js` - } -} - -async function buildLib () { - const metaMtimes = await Promise.all(META_FILES.map((filename) => lastModified(path.join(__dirname, '..', filename)))) - const metaMtime = Math.max(...metaMtimes) - - const files = await glob(SOURCE) - /* eslint-disable no-continue */ - for (const file of files) { - if (IGNORE.test(file)) { - continue - } - await preparePackage(file) - const libFile = file.replace('/src/', '/lib/').replace(/\.[jt]sx?$/, '.js') - - // on a fresh build, rebuild everything. - if (!process.env.FRESH) { - const [srcMtime, libMtime] = await Promise.all([ - lastModified(file), - lastModified(libFile, true), - ]) - // Skip files that haven't changed - if (srcMtime < libMtime && metaMtime < libMtime) { - continue - } - } - - const plugins = [{ - visitor: { - // eslint-disable-next-line no-shadow - ImportDeclaration (path) { - rewriteNonJSImportsToJS(path) - if (PACKAGE_JSON_IMPORT.test(path.node.source.value) - && path.node.specifiers.length === 1 - && path.node.specifiers[0].type === 'ImportDefaultSpecifier') { - // Vendor-in version number from package.json files: - const version = versionCache.get(file.slice(0, file.indexOf('/src/'))) - if (version != null) { - const [{ local }] = path.node.specifiers - path.replaceWith( - t.variableDeclaration('const', [t.variableDeclarator(local, - t.objectExpression([ - t.objectProperty(t.stringLiteral('version'), t.stringLiteral(version)), - ]))]), - ) - } - } - }, - - ExportAllDeclaration: rewriteNonJSImportsToJS, - // eslint-disable-next-line no-shadow - ExportNamedDeclaration (path) { - if (path.node.source != null) { - rewriteNonJSImportsToJS(path) - } - }, - }, - }] - const isTSX = file.endsWith('.tsx') - if (isTSX || file.endsWith('.ts')) { - plugins.push(['@babel/plugin-transform-typescript', { - disallowAmbiguousJSXLike: true, - isTSX, - jsxPragma: 'h', - jsxPragmaFrag: 'Fragment', - }]) - } - - const { code, map } = await babel.transformFileAsync(file, { - sourceMaps: true, - plugins, - // no comments because https://github.com/transloadit/uppy/pull/4868#issuecomment-1897717779 - comments: !process.env.DIFF_BUILDER, - }) - const [{ default: chalk }] = await Promise.all([ - import('chalk'), - writeFile(libFile, code), - writeFile(`${libFile}.map`, JSON.stringify(map)), - ]) - console.log(chalk.green('Compiled lib:'), chalk.magenta(libFile)) - } - /* eslint-enable no-continue */ -} - -console.log('Using Babel version:', require('@babel/core/package.json').version) - -buildLib().catch((err) => { - console.error(err) - process.exit(1) -}) diff --git a/bin/build-lib.mjs b/bin/build-lib.mjs new file mode 100644 index 0000000000..51664c763d --- /dev/null +++ b/bin/build-lib.mjs @@ -0,0 +1,145 @@ +import babel from '@babel/core' +import t from '@babel/types' +import { promisify } from 'node:util' +import { fileURLToPath } from 'node:url' +import globRaw from 'glob' +import { mkdir, stat, writeFile, readFile } from 'node:fs/promises' +import path from 'node:path' + +const glob = promisify(globRaw) + + +const PACKAGE_JSON_IMPORT = /^\..*\/package.json$/ +const SOURCE = 'packages/{*,@uppy/*}/src/**/*.{js,ts}?(x)' +// Files not to build (such as tests) +const IGNORE = /\.test\.jsx?$|\.test\.tsx?$|__mocks__|svelte|angular|companion\//; +// Files that should trigger a rebuild of everything on change +const META_FILES = [ + 'babel.config.js', + 'package.json', + 'package-lock.json', + 'yarn.lock', + 'bin/build-lib.js', +] + +function lastModified (file, createParentDir = false) { + return stat(file).then((s) => s.mtime, async (err) => { + if (err.code === 'ENOENT') { + if (createParentDir) { + await mkdir(path.dirname(file), { recursive: true }) + } + return 0 + } + throw err + }) +} + +const versionCache = new Map() + +// eslint-disable-next-line no-underscore-dangle +const __dirname = path.dirname(fileURLToPath(import.meta.url)); + +async function preparePackage (file) { + const packageFolder = file.slice(0, file.indexOf('/src/')) + if (versionCache.has(packageFolder)) return + + // eslint-disable-next-line import/no-dynamic-require, global-require + const { version } = JSON.parse(await readFile(path.join(__dirname, '..', packageFolder, 'package.json'), 'utf8')) + if (process.env.FRESH) { + // in case it hasn't been done before. + await mkdir(path.join(packageFolder, 'lib'), { recursive: true }) + } + versionCache.set(packageFolder, version) +} + +const nonJSImport = /^\.\.?\/.+\.([jt]sx|ts)$/ +// eslint-disable-next-line no-shadow +function rewriteNonJSImportsToJS (path) { + const match = nonJSImport.exec(path.node.source.value) + if (match) { + // eslint-disable-next-line no-param-reassign + path.node.source.value = `${match[0].slice(0, -match[1].length)}js` + } +} + +console.log('Using Babel version:', JSON.parse(await readFile(fileURLToPath(import.meta.resolve('@babel/core/package.json')), 'utf8')).version) + +const metaMtimes = await Promise.all(META_FILES.map((filename) => lastModified(path.join(__dirname, '..', filename)))) +const metaMtime = Math.max(...metaMtimes) + +const files = await glob(SOURCE) +/* eslint-disable no-continue */ +for (const file of files) { + if (IGNORE.test(file)) { + continue + } + await preparePackage(file) + const libFile = file.replace('/src/', '/lib/').replace(/\.[jt]sx?$/, '.js') + + // on a fresh build, rebuild everything. + if (!process.env.FRESH) { + const [srcMtime, libMtime] = await Promise.all([ + lastModified(file), + lastModified(libFile, true), + ]) + // Skip files that haven't changed + if (srcMtime < libMtime && metaMtime < libMtime) { + continue + } + } + + const plugins = [{ + visitor: { + // eslint-disable-next-line no-shadow + ImportDeclaration (path) { + rewriteNonJSImportsToJS(path) + if (PACKAGE_JSON_IMPORT.test(path.node.source.value) + && path.node.specifiers.length === 1 + && path.node.specifiers[0].type === 'ImportDefaultSpecifier') { + // Vendor-in version number from package.json files: + const version = versionCache.get(file.slice(0, file.indexOf('/src/'))) + if (version != null) { + const [{ local }] = path.node.specifiers + path.replaceWith( + t.variableDeclaration('const', [t.variableDeclarator(local, + t.objectExpression([ + t.objectProperty(t.stringLiteral('version'), t.stringLiteral(version)), + ]))]), + ) + } + } + }, + + ExportAllDeclaration: rewriteNonJSImportsToJS, + // eslint-disable-next-line no-shadow + ExportNamedDeclaration (path) { + if (path.node.source != null) { + rewriteNonJSImportsToJS(path) + } + }, + }, + }] + const isTSX = file.endsWith('.tsx') + if (isTSX || file.endsWith('.ts')) { + plugins.push(['@babel/plugin-transform-typescript', { + disallowAmbiguousJSXLike: true, + isTSX, + jsxPragma: 'h', + jsxPragmaFrag: 'Fragment', + }]) + } + + const { code, map } = await babel.transformFileAsync(file, { + sourceMaps: true, + plugins, + // no comments because https://github.com/transloadit/uppy/pull/4868#issuecomment-1897717779 + comments: !process.env.DIFF_BUILDER, + }) + const [{ default: chalk }] = await Promise.all([ + import('chalk'), + writeFile(libFile, code), + writeFile(`${libFile}.map`, JSON.stringify(map)), + ]) + console.log(chalk.green('Compiled lib:'), chalk.magenta(libFile)) +} +/* eslint-enable no-continue */ diff --git a/package.json b/package.json index b1fa51fec6..786a7ad5e5 100644 --- a/package.json +++ b/package.json @@ -119,7 +119,7 @@ "build:js:typeless": "npm-run-all build:lib build:companion build:svelte", "build:js": "npm-run-all build:js:typeless build:locale-pack build:angular build:bundle", "build:ts": "yarn tsc -b && yarn workspace @uppy/svelte check", - "build:lib": "yarn node ./bin/build-lib.js", + "build:lib": "yarn node ./bin/build-lib.mjs", "build:locale-pack": "yarn workspace @uppy-dev/locale-pack build && eslint packages/@uppy/locales/src/en_US.ts --fix && yarn workspace @uppy-dev/locale-pack test unused", "build": "npm-run-all --serial build:ts --parallel build:js build:css --serial size", "contributors:save": "yarn node ./bin/update-contributors.mjs",