This noticeably improves performance in the admin panel, for example
when there are multiple richtext editors on one page (& likely
performance in other areas too, though I mainly tested rich text).
The babel plugin currently only optimizes files with a 'use client'
directive at the top - thus we have to make sure to add use client
wherever possible, even if it's imported by a parent client component.
There's one single component that broke when it was compiled using the
React compiler (it stopped being reactive and failed one of our admin
e2e tests):
150808f608
opting out of it completely fixed that issue
Fixes https://github.com/payloadcms/payload/issues/7366
109 lines
2.9 KiB
JavaScript
109 lines
2.9 KiB
JavaScript
import * as esbuild from 'esbuild'
|
|
import fs from 'fs'
|
|
import path from 'path'
|
|
import { fileURLToPath } from 'url'
|
|
const filename = fileURLToPath(import.meta.url)
|
|
const dirname = path.dirname(filename)
|
|
import { sassPlugin } from 'esbuild-sass-plugin'
|
|
|
|
const removeCSSImports = {
|
|
name: 'remove-css-imports',
|
|
setup(build) {
|
|
build.onLoad({ filter: /.*/ }, async (args) => {
|
|
if (args.path.includes('node_modules') || !args.path.includes(dirname)) return
|
|
const contents = await fs.promises.readFile(args.path, 'utf8')
|
|
const withRemovedImports = contents.replace(/import\s+.*\.scss';?[\r\n\s]*/g, '')
|
|
return { contents: withRemovedImports, loader: 'default' }
|
|
})
|
|
},
|
|
}
|
|
|
|
async function build() {
|
|
// Bundle only the .scss files into a single css file
|
|
await esbuild.build({
|
|
entryPoints: ['src/exports/client/index.ts'],
|
|
bundle: true,
|
|
minify: true,
|
|
outdir: 'dist/bundled_scss',
|
|
loader: { '.svg': 'dataurl' },
|
|
packages: 'external',
|
|
//external: ['*.svg'],
|
|
plugins: [sassPlugin({ css: 'external' })],
|
|
})
|
|
|
|
//create empty dist/exports/client_optimized dir
|
|
fs.mkdirSync('dist/exports/client_optimized')
|
|
|
|
try {
|
|
fs.renameSync('dist/bundled_scss/index.css', 'dist/field/bundled.css')
|
|
fs.copyFileSync('dist/field/bundled.css', 'dist/exports/client_optimized/bundled.css')
|
|
fs.rmSync('dist/bundled_scss', { recursive: true })
|
|
} catch (err) {
|
|
console.error(`Error while renaming index.css: ${err}`)
|
|
throw err
|
|
}
|
|
|
|
console.log('dist/field/bundled.css bundled successfully')
|
|
|
|
// Bundle `client.ts`
|
|
const resultClient = await esbuild.build({
|
|
entryPoints: ['dist/exports/client/index.js'],
|
|
bundle: true,
|
|
platform: 'browser',
|
|
format: 'esm',
|
|
outdir: 'dist/exports/client_optimized',
|
|
//outfile: 'index.js',
|
|
// IMPORTANT: splitting the client bundle means that the `use client` directive will be lost for every chunk
|
|
splitting: true,
|
|
external: [
|
|
'*.scss',
|
|
'*.css',
|
|
'*.svg',
|
|
'qs-esm',
|
|
'@dnd-kit/core',
|
|
'@payloadcms/graphql',
|
|
'@payloadcms/translations',
|
|
'dequal',
|
|
|
|
//'side-channel',
|
|
'@payloadcms/ui',
|
|
'@payloadcms/ui/*',
|
|
'@payloadcms/ui/client',
|
|
'@payloadcms/ui/shared',
|
|
'lexical',
|
|
'lexical/*',
|
|
'@lexical',
|
|
'@lexical/*',
|
|
'@faceless-ui/*',
|
|
'bson-objectid',
|
|
'payload',
|
|
'payload/*',
|
|
'react',
|
|
'react-dom',
|
|
'next',
|
|
'react-animate-height',
|
|
'crypto',
|
|
'lodash',
|
|
'ui',
|
|
],
|
|
packages: 'external',
|
|
minify: true,
|
|
metafile: true,
|
|
treeShaking: true,
|
|
|
|
tsconfig: path.resolve(dirname, './tsconfig.json'),
|
|
plugins: [
|
|
removeCSSImports,
|
|
/*commonjs({
|
|
ignore: ['date-fns', '@floating-ui/react'],
|
|
}),*/
|
|
],
|
|
sourcemap: true,
|
|
})
|
|
console.log('client/index.ts bundled successfully')
|
|
|
|
fs.writeFileSync('meta_client.json', JSON.stringify(resultClient.metafile))
|
|
}
|
|
|
|
await build()
|