Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build lib refactor to esm #5537

Merged
merged 4 commits into from
Dec 4, 2024
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
147 changes: 0 additions & 147 deletions bin/build-lib.js

This file was deleted.

145 changes: 145 additions & 0 deletions bin/build-lib.mjs
Original file line number Diff line number Diff line change
@@ -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 */
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading