From 527fffb41488507e900d4d001f3c604c19c64488 Mon Sep 17 00:00:00 2001 From: Rico Kahler Date: Tue, 28 May 2024 13:11:36 -0500 Subject: [PATCH] feat(cli): build user peer-deps (#6742) * feat(cli): build user peer-deps * chore: remove shared-modules build * test(cli): verify build config and `exports` subpaths * text(cli): add depcheck config for fixture projects * docs: update comments and test name * feat: create import map w/ installed sanity version (#6784) * feat: create import map w/ installed sanity version * fix: use correct URL --- package.json | 2 +- .../shared-modules.bundle/.depcheckrc.json | 3 - .../@repo/shared-modules.bundle/.eslintrc.cjs | 9 - .../@repo/shared-modules.bundle/.gitignore | 2 - .../shared-modules.bundle/package.bundle.ts | 23 -- .../@repo/shared-modules.bundle/package.json | 17 -- .../prj-with-react-18/.depcheckrc.json | 3 + .../examples/prj-with-react-18/package.json | 9 + .../prj-with-react-19/.depcheckrc.json | 3 + .../examples/prj-with-react-19/package.json | 9 + .../.depcheckrc.json | 3 + .../prj-with-styled-components-5/package.json | 9 + .../cli/actions/build/buildAction.ts | 44 +-- .../__tests__/buildVendorDependencies.test.ts | 255 ++++++++++++++++++ .../cli/server/buildVendorDependencies.ts | 233 ++++++++++++++++ .../cli/server/createExternalFromImportMap.ts | 15 ++ .../src/_internal/cli/server/getViteConfig.ts | 17 +- .../cli/util/checkRequiredDependencies.ts | 22 +- pnpm-lock.yaml | 171 +++++++++++- pnpm-workspace.yaml | 1 + scripts/uploadBundles.ts | 36 --- 21 files changed, 742 insertions(+), 144 deletions(-) delete mode 100644 packages/@repo/shared-modules.bundle/.depcheckrc.json delete mode 100644 packages/@repo/shared-modules.bundle/.eslintrc.cjs delete mode 100644 packages/@repo/shared-modules.bundle/.gitignore delete mode 100644 packages/@repo/shared-modules.bundle/package.bundle.ts delete mode 100644 packages/@repo/shared-modules.bundle/package.json create mode 100644 packages/sanity/fixtures/examples/prj-with-react-18/.depcheckrc.json create mode 100644 packages/sanity/fixtures/examples/prj-with-react-18/package.json create mode 100644 packages/sanity/fixtures/examples/prj-with-react-19/.depcheckrc.json create mode 100644 packages/sanity/fixtures/examples/prj-with-react-19/package.json create mode 100644 packages/sanity/fixtures/examples/prj-with-styled-components-5/.depcheckrc.json create mode 100644 packages/sanity/fixtures/examples/prj-with-styled-components-5/package.json create mode 100644 packages/sanity/src/_internal/cli/server/__tests__/buildVendorDependencies.test.ts create mode 100644 packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts create mode 100644 packages/sanity/src/_internal/cli/server/createExternalFromImportMap.ts diff --git a/package.json b/package.json index 2ed33f9fcc82..b274ae70f170 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "scripts": { "bootstrap": "pnpm install && pnpm build:cli", "build": "turbo run build --filter='./packages/*' --filter='./packages/@sanity/*'", - "build:bundle": "turbo run build:bundle --filter='./packages/*' --filter='./packages/@sanity/*' --filter='./packages/@repo/shared-modules.bundle'", + "build:bundle": "turbo run build:bundle --filter='./packages/*' --filter='./packages/@sanity/*'", "build:clean": "lerna run clean", "build:cli": "turbo run build --filter=@sanity/cli --filter=sanity", "build:cli-only": "turbo run --filter=@sanity/cli build", diff --git a/packages/@repo/shared-modules.bundle/.depcheckrc.json b/packages/@repo/shared-modules.bundle/.depcheckrc.json deleted file mode 100644 index 4038496cf880..000000000000 --- a/packages/@repo/shared-modules.bundle/.depcheckrc.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "ignores": ["vite", "react", "react-dom", "styled-components"] -} diff --git a/packages/@repo/shared-modules.bundle/.eslintrc.cjs b/packages/@repo/shared-modules.bundle/.eslintrc.cjs deleted file mode 100644 index bdf9cc4c1b98..000000000000 --- a/packages/@repo/shared-modules.bundle/.eslintrc.cjs +++ /dev/null @@ -1,9 +0,0 @@ -const path = require('path') - -const ROOT_PATH = path.resolve(__dirname, '../../..') - -module.exports = { - rules: { - 'import/no-extraneous-dependencies': ['error', {packageDir: [ROOT_PATH, __dirname]}], - }, -} diff --git a/packages/@repo/shared-modules.bundle/.gitignore b/packages/@repo/shared-modules.bundle/.gitignore deleted file mode 100644 index 37addf50b9b7..000000000000 --- a/packages/@repo/shared-modules.bundle/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Compiled Code -/dist diff --git a/packages/@repo/shared-modules.bundle/package.bundle.ts b/packages/@repo/shared-modules.bundle/package.bundle.ts deleted file mode 100644 index 5ff43a7537e2..000000000000 --- a/packages/@repo/shared-modules.bundle/package.bundle.ts +++ /dev/null @@ -1,23 +0,0 @@ -import {defineConfig, mergeConfig} from 'vite' - -import {defaultConfig} from '../package.bundle/src/package.bundle' - -export default defineConfig(() => { - return mergeConfig(defaultConfig, { - build: { - lib: { - // NOTE: IF ANY OF THIS CHANGES MAKE SURE TO UPDATE `scripts/uploadBundles.ts` - entry: { - 'react/index': './node_modules/react/cjs/react.production.min.js', - 'react-dom/index': './node_modules/react-dom/cjs/react-dom.production.min.js', - 'react-dom/client': './node_modules/react-dom/cjs/react-dom.production.min.js', - 'react-dom/server': - './node_modules/react-dom/cjs/react-dom-server-legacy.browser.production.min.js', - 'react/jsx-runtime': './node_modules/react/cjs/react-jsx-runtime.production.min.js', - 'styled-components/index': - './node_modules/styled-components/dist/styled-components.esm.js', - }, - }, - }, - }) -}) diff --git a/packages/@repo/shared-modules.bundle/package.json b/packages/@repo/shared-modules.bundle/package.json deleted file mode 100644 index 94f620057f45..000000000000 --- a/packages/@repo/shared-modules.bundle/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "@repo/shared-modules.bundle", - "version": "3.43.0", - "private": true, - "description": "Bundle for shared deps", - "main": "./package.bundle.ts", - "types": "./package.bundle.ts", - "scripts": { - "build:bundle": "vite build --config package.bundle.ts", - "check:types": "tsc --noEmit --skipLibCheck package.bundle.ts" - }, - "dependencies": { - "react": "^18.3.1", - "react-dom": "^18.3.1", - "styled-components": "^6.1.11" - } -} diff --git a/packages/sanity/fixtures/examples/prj-with-react-18/.depcheckrc.json b/packages/sanity/fixtures/examples/prj-with-react-18/.depcheckrc.json new file mode 100644 index 000000000000..d8cab01bd64a --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-react-18/.depcheckrc.json @@ -0,0 +1,3 @@ +{ + "ignores": ["react", "react-dom", "styled-components"] +} diff --git a/packages/sanity/fixtures/examples/prj-with-react-18/package.json b/packages/sanity/fixtures/examples/prj-with-react-18/package.json new file mode 100644 index 000000000000..2fe57313b0d1 --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-react-18/package.json @@ -0,0 +1,9 @@ +{ + "name": "prj-with-react-18", + "private": true, + "dependencies": { + "react": "^18.3.0", + "react-dom": "^18.3.0", + "styled-components": "^6.1.0" + } +} diff --git a/packages/sanity/fixtures/examples/prj-with-react-19/.depcheckrc.json b/packages/sanity/fixtures/examples/prj-with-react-19/.depcheckrc.json new file mode 100644 index 000000000000..d8cab01bd64a --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-react-19/.depcheckrc.json @@ -0,0 +1,3 @@ +{ + "ignores": ["react", "react-dom", "styled-components"] +} diff --git a/packages/sanity/fixtures/examples/prj-with-react-19/package.json b/packages/sanity/fixtures/examples/prj-with-react-19/package.json new file mode 100644 index 000000000000..3e7a9bb7cd31 --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-react-19/package.json @@ -0,0 +1,9 @@ +{ + "name": "prj-with-react-19", + "private": true, + "dependencies": { + "react": "19.0.0-rc-f994737d14-20240522", + "react-dom": "19.0.0-rc-f994737d14-20240522", + "styled-components": "^6.1.0" + } +} diff --git a/packages/sanity/fixtures/examples/prj-with-styled-components-5/.depcheckrc.json b/packages/sanity/fixtures/examples/prj-with-styled-components-5/.depcheckrc.json new file mode 100644 index 000000000000..d8cab01bd64a --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-styled-components-5/.depcheckrc.json @@ -0,0 +1,3 @@ +{ + "ignores": ["react", "react-dom", "styled-components"] +} diff --git a/packages/sanity/fixtures/examples/prj-with-styled-components-5/package.json b/packages/sanity/fixtures/examples/prj-with-styled-components-5/package.json new file mode 100644 index 000000000000..25e3fce1c3d3 --- /dev/null +++ b/packages/sanity/fixtures/examples/prj-with-styled-components-5/package.json @@ -0,0 +1,9 @@ +{ + "name": "prj-with-styled-components-5", + "private": true, + "dependencies": { + "react": "^18.3.0", + "react-dom": "^18.3.0", + "styled-components": "^5.3.0" + } +} diff --git a/packages/sanity/src/_internal/cli/actions/build/buildAction.ts b/packages/sanity/src/_internal/cli/actions/build/buildAction.ts index ecc783ff9f34..3cab990f438c 100644 --- a/packages/sanity/src/_internal/cli/actions/build/buildAction.ts +++ b/packages/sanity/src/_internal/cli/actions/build/buildAction.ts @@ -14,26 +14,10 @@ import {checkStudioDependencyVersions} from '../../util/checkStudioDependencyVer import {checkRequiredDependencies} from '../../util/checkRequiredDependencies' import {getTimer} from '../../util/timing' import {BuildTrace} from './build.telemetry' +import {buildVendorDependencies} from '../../server/buildVendorDependencies' const rimraf = promisify(rimrafCallback) -// TODO: replace this with a manifest somewhere -const AUTO_UPDATES_IMPORTMAP = { - imports: { - // Shared modules - 'react': 'https://api.sanity.work/v1/modules/react/^18', - 'react/': 'https://api.sanity.work/v1/modules/react/^18/', - 'react-dom': 'https://api.sanity.work/v1/modules/react-dom/^18', - 'react-dom/': 'https://api.sanity.work/v1/modules/react-dom/^18/', - 'styled-components': 'https://api.sanity.work/v1/modules/styled-components/^6', - - // Sanity Modules - 'sanity': 'https://api.sanity.work/v1/modules/sanity/^3', - 'sanity/': 'https://api.sanity.work/v1/modules/sanity/^3/', - '@sanity/vision': 'https://api.sanity.work/v1/modules/@sanity__vision/^3 ', - }, -} - export interface BuildSanityStudioCommandFlags { 'yes'?: boolean 'y'?: boolean @@ -65,7 +49,8 @@ export default async function buildSanityStudio( // If the check resulted in a dependency install, the CLI command will be re-run, // thus we want to exit early - if ((await checkRequiredDependencies(context)).didInstall) { + const {didInstall, installedSanityVersion} = await checkRequiredDependencies(context) + if (didInstall) { return {didCompile: false} } @@ -132,6 +117,26 @@ export default async function buildSanityStudio( const trace = telemetry.trace(BuildTrace) trace.start() + + let importMap + + if (enableAutoUpdates) { + const version = encodeURIComponent(`^${installedSanityVersion}`) + const autoUpdatesImports = { + 'sanity': `https://api.sanity.work/v1/modules/sanity/default/${version}`, + 'sanity/': `https://api.sanity.work/v1/modules/sanity/default/${version}/`, + '@sanity/vision': `https://api.sanity.work/v1/modules/@sanity__vision/default/${version}`, + '@sanity/vision/': `https://api.sanity.work/v1/modules/@sanity__vision/default/${version}/`, + } + + importMap = { + imports: { + ...(await buildVendorDependencies({cwd: workDir, outputDir})), + ...autoUpdatesImports, + }, + } + } + try { timer.start('bundleStudio') @@ -142,8 +147,9 @@ export default async function buildSanityStudio( sourceMap: Boolean(flags['source-maps']), minify: Boolean(flags.minify), vite: cliConfig && 'vite' in cliConfig ? cliConfig.vite : undefined, - importMap: enableAutoUpdates ? AUTO_UPDATES_IMPORTMAP : undefined, + importMap, }) + trace.log({ outputSize: bundle.chunks .flatMap((chunk) => chunk.modules.flatMap((mod) => mod.renderedLength)) diff --git a/packages/sanity/src/_internal/cli/server/__tests__/buildVendorDependencies.test.ts b/packages/sanity/src/_internal/cli/server/__tests__/buildVendorDependencies.test.ts new file mode 100644 index 000000000000..62d852970d2e --- /dev/null +++ b/packages/sanity/src/_internal/cli/server/__tests__/buildVendorDependencies.test.ts @@ -0,0 +1,255 @@ +import fs from 'node:fs' +import path from 'node:path' + +import {beforeEach, describe, expect, it, jest} from '@jest/globals' + +import {buildVendorDependencies} from '../buildVendorDependencies' + +// Mocking the vite.build function to inspect its calls. This allows us to test +// that the function is called with the correct configuration without actually +// performing the build process. +jest.mock('vite', () => ({build: jest.fn()})) + +describe('buildVendorDependencies', () => { + const {build} = require('vite') + const packageRoot = path.resolve(__dirname, '../../../../..') + const examplesRoot = path.join(packageRoot, './fixtures/examples') + const outputDir = './output-dir' + + beforeEach(() => { + jest.resetAllMocks() + const vite = require('vite') + vite.build.mockResolvedValue({}) + }) + + it('should throw if there is no matching entry in VENDOR_IMPORTS', () => { + const cwd = path.join(examplesRoot, 'prj-with-styled-components-5') + + return expect(buildVendorDependencies({cwd, outputDir})).rejects.toThrow( + "Package 'styled-components' requires at least 6.1.0.", + ) + }) + + it('should return the expected entry points for react 18', async () => { + const cwd = path.join(examplesRoot, 'prj-with-react-18') + const imports = await buildVendorDependencies({cwd, outputDir}) + + expect(imports).toEqual({ + 'react': '/vendor/react/index.mjs', + 'react-dom': '/vendor/react-dom/index.mjs', + 'react-dom/client': '/vendor/react-dom/client.mjs', + 'react-dom/package.json': '/vendor/react-dom/package.json.mjs', + 'react-dom/server': '/vendor/react-dom/server.mjs', + 'react-dom/server.browser': '/vendor/react-dom/server.browser.mjs', + 'react/jsx-dev-runtime': '/vendor/react/jsx-dev-runtime.mjs', + 'react/jsx-runtime': '/vendor/react/jsx-runtime.mjs', + 'react/package.json': '/vendor/react/package.json.mjs', + 'styled-components': '/vendor/styled-components/index.mjs', + 'styled-components/package.json': '/vendor/styled-components/package.json.mjs', + }) + + expect(build).toHaveBeenCalledTimes(1) + const [buildConfig] = build.mock.calls[0] + + expect(buildConfig).toMatchObject({ + root: cwd, + configFile: false, + mode: 'production', + define: {'process.env.NODE_ENV': JSON.stringify('production')}, + build: { + minify: true, + emptyOutDir: false, + outDir: path.join(outputDir, 'vendor'), + lib: {formats: ['es']}, + rollupOptions: { + external: [ + 'react', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react/package.json', + 'react-dom', + 'react-dom/client', + 'react-dom/server', + 'react-dom/server.browser', + 'react-dom/package.json', + 'styled-components', + 'styled-components/package.json', + ], + output: {exports: 'named', format: 'es'}, + treeshake: {preset: 'recommended'}, + }, + }, + }) + + const entry: Record = buildConfig.build.lib.entry + const chunkNames = Object.keys(entry) + const resolvedEntries = Object.values(entry) + + const {exports: reactExports} = JSON.parse( + await fs.promises.readFile(entry['react/package.json'], 'utf-8'), + ) + const {exports: reactDomExports} = JSON.parse( + await fs.promises.readFile(entry['react-dom/package.json'], 'utf-8'), + ) + + // Verify the structure of the exports in the package.json files + // We're specifically checking the `exports` field of `react` and + // `react-dom` to see if there are any new subpath exports. Renovate + // automatically updates `react` and `react-dom`, so if a new subpath export + // is added, this test will fail. This failure acts as a signal for us to + // review and potentially add support for the new subpath if applicable. + expect(Object.keys(reactExports)).toEqual([ + '.', + './package.json', + './jsx-runtime', + './jsx-dev-runtime', + ]) + expect(Object.keys(reactDomExports)).toEqual([ + '.', + './client', + './server', + './server.browser', + './server.node', + './profiling', + './test-utils', + './package.json', + ]) + + expect(chunkNames).toEqual([ + 'react/index', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react/package.json', + 'react-dom/index', + 'react-dom/client', + 'react-dom/server', + 'react-dom/server.browser', + 'react-dom/package.json', + 'styled-components/index', + 'styled-components/package.json', + ]) + + expect(resolvedEntries).toHaveLength(chunkNames.length) + expect(resolvedEntries.every(fs.existsSync)).toBe(true) + }) + + it('should return the expected entry points for react 19', async () => { + const cwd = path.join(examplesRoot, 'prj-with-react-19') + const imports = await buildVendorDependencies({cwd, outputDir}) + + expect(imports).toEqual({ + 'react': '/vendor/react/index.mjs', + 'react-dom': '/vendor/react-dom/index.mjs', + 'react-dom/client': '/vendor/react-dom/client.mjs', + 'react-dom/package.json': '/vendor/react-dom/package.json.mjs', + 'react-dom/server': '/vendor/react-dom/server.mjs', + 'react-dom/server.browser': '/vendor/react-dom/server.browser.mjs', + 'react-dom/static': '/vendor/react-dom/static.mjs', + 'react-dom/static.browser': '/vendor/react-dom/static.browser.mjs', + 'react/compiler-runtime': '/vendor/react/compiler-runtime.mjs', + 'react/jsx-dev-runtime': '/vendor/react/jsx-dev-runtime.mjs', + 'react/jsx-runtime': '/vendor/react/jsx-runtime.mjs', + 'react/package.json': '/vendor/react/package.json.mjs', + 'styled-components': '/vendor/styled-components/index.mjs', + 'styled-components/package.json': '/vendor/styled-components/package.json.mjs', + }) + + expect(build).toHaveBeenCalledTimes(1) + const [buildConfig] = build.mock.calls[0] + + expect(buildConfig).toMatchObject({ + root: cwd, + configFile: false, + mode: 'production', + define: {'process.env.NODE_ENV': JSON.stringify('production')}, + build: { + minify: true, + emptyOutDir: false, + outDir: path.join(outputDir, 'vendor'), + lib: {formats: ['es']}, + rollupOptions: { + external: [ + 'react', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react/compiler-runtime', + 'react/package.json', + 'react-dom', + 'react-dom/client', + 'react-dom/server', + 'react-dom/server.browser', + 'react-dom/static', + 'react-dom/static.browser', + 'react-dom/package.json', + 'styled-components', + 'styled-components/package.json', + ], + output: {exports: 'named', format: 'es'}, + treeshake: {preset: 'recommended'}, + }, + }, + }) + + const entry: Record = buildConfig.build.lib.entry + const chunkNames = Object.keys(entry) + const resolvedEntries = Object.values(entry) + + // Verify the structure of the exports in the package.json files + // We're specifically checking the `exports` field of `react` and + // `react-dom` to see if there are any new subpath exports. Renovate + // automatically updates `react` and `react-dom`, so if a new subpath export + // is added, this test will fail. This failure acts as a signal for us to + // review and potentially add support for the new subpath if applicable. + const {exports: reactExports} = JSON.parse( + await fs.promises.readFile(entry['react/package.json'], 'utf-8'), + ) + const {exports: reactDomExports} = JSON.parse( + await fs.promises.readFile(entry['react-dom/package.json'], 'utf-8'), + ) + + expect(Object.keys(reactExports)).toEqual([ + '.', + './package.json', + './jsx-runtime', + './jsx-dev-runtime', + './compiler-runtime', + ]) + + expect(Object.keys(reactDomExports)).toEqual([ + '.', + './client', + './server', + './server.browser', + './server.bun', + './server.edge', + './server.node', + './static', + './static.browser', + './static.edge', + './static.node', + './profiling', + './test-utils', + './package.json', + ]) + + expect(chunkNames).toEqual([ + 'react/index', + 'react/jsx-runtime', + 'react/jsx-dev-runtime', + 'react/compiler-runtime', + 'react/package.json', + 'react-dom/index', + 'react-dom/client', + 'react-dom/server', + 'react-dom/server.browser', + 'react-dom/static', + 'react-dom/static.browser', + 'react-dom/package.json', + 'styled-components/index', + 'styled-components/package.json', + ]) + + expect(resolvedEntries).toHaveLength(chunkNames.length) + expect(resolvedEntries.every(fs.existsSync)).toBe(true) + }) +}) diff --git a/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts b/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts new file mode 100644 index 000000000000..505d5515d628 --- /dev/null +++ b/packages/sanity/src/_internal/cli/server/buildVendorDependencies.ts @@ -0,0 +1,233 @@ +import fs from 'node:fs' +import path from 'node:path' + +import resolveFrom from 'resolve-from' +import semver from 'semver' +import {build} from 'vite' + +import {createExternalFromImportMap} from './createExternalFromImportMap' + +// Directory where vendor packages will be stored +const VENDOR_DIR = 'vendor' + +/** + * A type representing the imports of vendor packages, defining specific entry + * points for various versions and subpaths of the packages. + * + * The `VendorImports` object is used to build ESM browser-compatible versions + * of the specified packages. This approach ensures that the appropriate version + * and entry points are used for each package, enabling compatibility and proper + * functionality in the browser environment. + * + * ## Rationale + * + * The rationale for this structure is to handle different versions of the + * packages carefully, especially major versions. Major version bumps often + * introduce breaking changes, so the module scheme for the package needs to be + * checked when there is a major version update. However, minor and patch + * versions are generally backward compatible, so they are handled more + * leniently. By assuming that new minor versions are compatible, we avoid + * unnecessary warnings and streamline the update process. + * + * If a new minor version introduces an additional subpath export within the + * package of this version range, the corresponding package can add a more + * specific version range that includes the new subpath. This design allows for + * flexibility and ease of maintenance, ensuring that the latest features and + * fixes are incorporated without extensive manual intervention. + * + * An additional subpath export within the package of this version range that + * could cause the build to break if that new export is used, can be treated as + * a bug fix. It might make more sense to our users that this new subpath isn't + * supported yet until we address it as a bug fix. This approach helps maintain + * stability and prevents unexpected issues during the build process. + * + * ## Structure + * The `VendorImports` type is a nested object where: + * - The keys at the first level represent the package names. + * - The keys at the second level represent the version ranges (e.g., `^19.0.0`). + * - The keys at the third level represent the subpaths within the package (e.g., `.` for the main entry point). + * - The values at the third level are the relative paths to the corresponding entry points within the package. + * + * This structure allows for precise specification of the entry points for + * different versions and subpaths, ensuring that the correct files are used + * during the build process. + */ +type VendorImports = { + [packageName: string]: { + [versionRange: string]: { + [subpath: string]: string + } + } +} + +// Define the vendor packages and their corresponding versions and entry points +const VENDOR_IMPORTS: VendorImports = { + 'react': { + '^19.0.0': { + '.': './cjs/react.production.js', + './jsx-runtime': './cjs/react-jsx-runtime.production.js', + './jsx-dev-runtime': './cjs/react-jsx-dev-runtime.production.js', + './compiler-runtime': './cjs/react-compiler-runtime.production.js', + './package.json': './package.json', + }, + '^18.0.0': { + '.': './cjs/react.production.min.js', + './jsx-runtime': './cjs/react-jsx-runtime.production.min.js', + './jsx-dev-runtime': './cjs/react-jsx-dev-runtime.production.min.js', + './package.json': './package.json', + }, + }, + 'react-dom': { + '^19.0.0': { + '.': './cjs/react-dom.production.js', + './client': './cjs/react-dom-client.production.js', + './server': './cjs/react-dom-server-legacy.browser.production.js', + './server.browser': './cjs/react-dom-server-legacy.browser.production.js', + './static': './cjs/react-dom-server.browser.production.js', + './static.browser': './cjs/react-dom-server.browser.production.js', + './package.json': './package.json', + }, + '^18.0.0': { + '.': './cjs/react-dom.production.min.js', + './client': './cjs/react-dom.production.min.js', + './server': './cjs/react-dom-server-legacy.browser.production.min.js', + './server.browser': './cjs/react-dom-server-legacy.browser.production.min.js', + './package.json': './package.json', + }, + }, + 'styled-components': { + '^6.1.0': { + '.': './dist/styled-components.esm.js', + './package.json': './package.json', + }, + }, +} + +interface VendorBuildOptions { + cwd: string + outputDir: string +} + +/** + * Builds the ESM browser compatible versions of the vendor packages + * specified in VENDOR_IMPORTS. Returns the `imports` object of an import map. + */ +export async function buildVendorDependencies({ + cwd, + outputDir, +}: VendorBuildOptions): Promise> { + // normalize the CWD to a relative dir for better error messages + const dir = path.relative(process.cwd(), path.resolve(cwd)) + const entry: Record = {} + const imports: Record = {} + + // Iterate over each package and its version ranges in VENDOR_IMPORTS + for (const [packageName, ranges] of Object.entries(VENDOR_IMPORTS)) { + const packageJsonPath = resolveFrom.silent(cwd, `./node_modules/${packageName}/package.json`) + if (!packageJsonPath) { + throw new Error( + `Could not find package.json for package '${packageName}' from directory '${dir}'. Is it installed?`, + ) + } + + let packageJson + + try { + // Read and parse the package.json file + packageJson = JSON.parse(await fs.promises.readFile(packageJsonPath, 'utf-8')) + } catch (e) { + const message = `Could not read package.json for package '${packageName}' from directory '${dir}'` + if (typeof e?.message === 'string') { + // Re-assign the error message so the stack trace is more visible + e.message = `${message}: ${e.message}` + throw e + } + + throw new Error(message, {cause: e}) + } + + // Coerce the version to a semver-compatible version + const version = semver.coerce(packageJson.version)?.version + if (!version) { + throw new Error(`Could not parse version '${packageJson.version}' from '${packageName}'`) + } + + // Sort version ranges in descending order + const sortedRanges = Object.keys(ranges).sort((range1, range2) => { + const min1 = semver.minVersion(range1) + const min2 = semver.minVersion(range2) + + if (!min1) throw new Error(`Could not parse range '${range1}'`) + if (!min2) throw new Error(`Could not parse range '${range2}'`) + + // sort them in reverse so we can rely on array `.find` below + return semver.rcompare(min1.version, min2.version) + }) + + // Find the first version range that satisfies the package version + const matchedRange = sortedRanges.find((range) => semver.satisfies(version, range)) + + if (!matchedRange) { + const min = semver.minVersion(sortedRanges[sortedRanges.length - 1]) + if (!min) { + throw new Error(`Could not find a minimum version for package '${packageName}'`) + } + + if (semver.gt(min.version, version)) { + throw new Error(`Package '${packageName}' requires at least ${min.version}.`) + } + + throw new Error(`Version '${version}' of package '${packageName}' is not supported yet.`) + } + + const subpaths = ranges[matchedRange] + + // Iterate over each subpath and its corresponding entry point + for (const [subpath, relativeEntryPoint] of Object.entries(subpaths)) { + const entryPoint = resolveFrom.silent( + cwd, + `./node_modules/${path.join(packageName, relativeEntryPoint)}`, + ) + + if (!entryPoint) { + throw new Error( + `Failed to resolve entry point '${path.join(packageName, relativeEntryPoint)}'. `, + ) + } + + const specifier = path.join(packageName, subpath) + const chunkName = path.join(packageName, path.relative(packageName, specifier) || 'index') + + entry[chunkName] = entryPoint + imports[specifier] = path.join('/', VENDOR_DIR, `${chunkName}.mjs`) + } + } + + // Use Vite to build the packages into the output directory + await build({ + // Define a custom cache directory so that sanity's vite cache + // does not conflict with any potential local vite projects + cacheDir: 'node_modules/.sanity/vite-vendor', + root: cwd, + configFile: false, + logLevel: 'silent', + + appType: 'custom', + mode: 'production', + define: {'process.env.NODE_ENV': JSON.stringify('production')}, + + build: { + minify: true, + emptyOutDir: false, // Rely on CLI to do this + outDir: path.join(outputDir, VENDOR_DIR), + lib: {entry, formats: ['es']}, + rollupOptions: { + external: createExternalFromImportMap({imports}), + output: {exports: 'named', format: 'es'}, + treeshake: {preset: 'recommended'}, + }, + }, + }) + + return imports +} diff --git a/packages/sanity/src/_internal/cli/server/createExternalFromImportMap.ts b/packages/sanity/src/_internal/cli/server/createExternalFromImportMap.ts new file mode 100644 index 000000000000..e78a5d9f05f6 --- /dev/null +++ b/packages/sanity/src/_internal/cli/server/createExternalFromImportMap.ts @@ -0,0 +1,15 @@ +import {escapeRegExp} from 'lodash' + +type ImportMap = {imports?: Record} + +/** + * Generates a Rollup `external` configuration array based on the provided + * import map. We derive externals from the import map because this ensures that + * modules listed in the import map are not bundled into the Rollup output so + * the browser can load these bare specifiers according to the import map. + */ +export function createExternalFromImportMap({imports = {}}: ImportMap = {}): (string | RegExp)[] { + return Object.keys(imports).map((specifier) => + specifier.endsWith('/') ? new RegExp(`^${escapeRegExp(specifier)}.+`) : specifier, + ) +} diff --git a/packages/sanity/src/_internal/cli/server/getViteConfig.ts b/packages/sanity/src/_internal/cli/server/getViteConfig.ts index 972315666c5a..7c8bcffe6419 100644 --- a/packages/sanity/src/_internal/cli/server/getViteConfig.ts +++ b/packages/sanity/src/_internal/cli/server/getViteConfig.ts @@ -3,11 +3,11 @@ import path from 'node:path' import {type UserViteConfig} from '@sanity/cli' import viteReact from '@vitejs/plugin-react' import debug from 'debug' -import {escapeRegExp} from 'lodash' import readPkgUp from 'read-pkg-up' import {type ConfigEnv, type InlineConfig, mergeConfig} from 'vite' import {getAliases} from './aliases' +import {createExternalFromImportMap} from './createExternalFromImportMap' import {getStudioEnvironmentVariables} from './getStudioEnvironmentVariables' import {normalizeBasePath} from './helpers' import {loadSanityMonorepo} from './sanityMonorepo' @@ -143,21 +143,6 @@ export async function getViteConfig(options: ViteOptions): Promise return viteConfig } -/** - * Generates a Rollup `external` configuration array based on the provided - * import map. We derive externals from the import map because this ensures that - * modules listed in the import map are not bundled into the Rollup output so - * the browser can load these bare specifiers according to the import map. - */ -function createExternalFromImportMap(importMap?: {imports?: Record}) { - if (!importMap) return [] - const {imports = {}} = importMap - - return Object.keys(imports).map((specifier) => - specifier.endsWith('/') ? new RegExp(`^${escapeRegExp(specifier)}.+`) : specifier, - ) -} - /** * Ensure Sanity entry chunk is always loaded * diff --git a/packages/sanity/src/_internal/cli/util/checkRequiredDependencies.ts b/packages/sanity/src/_internal/cli/util/checkRequiredDependencies.ts index 1ec2ffcaa54c..b32f3a538b85 100644 --- a/packages/sanity/src/_internal/cli/util/checkRequiredDependencies.ts +++ b/packages/sanity/src/_internal/cli/util/checkRequiredDependencies.ts @@ -16,6 +16,7 @@ const defaultStudioManifestProps: PartialPackageManifest = { interface CheckResult { didInstall: boolean + installedSanityVersion: string } /** @@ -26,16 +27,25 @@ interface CheckResult { * * If these dependencies are not installed/declared, we want to prompt the user * whether or not to add them to `package.json` and install them + * + * Additionally, returns the version of the 'sanity' dependency from the package.json. */ export async function checkRequiredDependencies(context: CliCommandContext): Promise { const {workDir: studioPath, output} = context - const [studioPackageManifest, installedStyledComponentsVersion] = await Promise.all([ - await readPackageManifest(path.join(studioPath, 'package.json'), defaultStudioManifestProps), - await readModuleVersion(studioPath, 'styled-components'), - ]) + const [studioPackageManifest, installedStyledComponentsVersion, installedSanityVersion] = + await Promise.all([ + await readPackageManifest(path.join(studioPath, 'package.json'), defaultStudioManifestProps), + await readModuleVersion(studioPath, 'styled-components'), + await readModuleVersion(studioPath, 'sanity'), + ]) const wantedStyledComponentsVersionRange = peerDependencies['styled-components'] + // Retrieve the version of the 'sanity' dependency + if (!installedSanityVersion) { + throw new Error('Failed to read the installed sanity version.') + } + // The studio _must_ now declare `styled-components` as a dependency. If it's not there, // we'll want to automatically _add it_ to the manifest and tell the user to reinstall // dependencies before running whatever command was being run @@ -50,7 +60,7 @@ export async function checkRequiredDependencies(context: CliCommandContext): Pro // broken assumptions about installation paths. This is a hack, and should be // solved properly. await execa(file, args, {cwd: studioPath, stdio: 'inherit'}) - return {didInstall: true} + return {didInstall: true, installedSanityVersion} } // Theoretically the version specified in package.json could be incorrect, eg `foo` @@ -103,7 +113,7 @@ export async function checkRequiredDependencies(context: CliCommandContext): Pro `) } - return {didInstall: false} + return {didInstall: false, installedSanityVersion} } /** diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 047acb426a89..7881f4a8a371 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -634,18 +634,6 @@ importers: packages/@repo/package.config: {} - packages/@repo/shared-modules.bundle: - dependencies: - react: - specifier: ^18.3.1 - version: 18.3.1 - react-dom: - specifier: ^18.3.1 - version: 18.3.1(react@18.3.1) - styled-components: - specifier: ^6.1.11 - version: 6.1.11(react-dom@18.3.1)(react@18.3.1) - packages/@repo/test-exports: dependencies: '@sanity/block-tools': @@ -1915,6 +1903,42 @@ importers: specifier: 2.2.5 version: 2.2.5(react@18.3.1) + packages/sanity/fixtures/examples/prj-with-react-18: + dependencies: + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) + styled-components: + specifier: ^6.1.0 + version: 6.1.11(react-dom@18.3.1)(react@18.3.1) + + packages/sanity/fixtures/examples/prj-with-react-19: + dependencies: + react: + specifier: 19.0.0-rc-f994737d14-20240522 + version: 19.0.0-rc-f994737d14-20240522 + react-dom: + specifier: 19.0.0-rc-f994737d14-20240522 + version: 19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522) + styled-components: + specifier: ^6.1.0 + version: 6.1.11(react-dom@19.0.0-rc-f994737d14-20240522)(react@19.0.0-rc-f994737d14-20240522) + + packages/sanity/fixtures/examples/prj-with-styled-components-5: + dependencies: + react: + specifier: ^18.3.0 + version: 18.3.1 + react-dom: + specifier: ^18.3.0 + version: 18.3.1(react@18.3.1) + styled-components: + specifier: ^5.3.0 + version: 5.3.11(@babel/core@7.24.5)(react-dom@18.3.1)(react-is@18.3.1)(react@18.3.1) + perf/studio: dependencies: react: @@ -3266,6 +3290,24 @@ packages: transitivePeerDependencies: - supports-color + /@babel/traverse@7.24.5(supports-color@5.5.0): + resolution: {integrity: sha512-7aaBLeDQ4zYcUFDUD41lJc1fG8+5IU9DaNSJAgal866FGvmD5EbWQgnEC6kO1gGLsX0esNkfnJSndbTXA3r7UA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.24.2 + '@babel/generator': 7.24.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.24.5 + '@babel/parser': 7.24.5 + '@babel/types': 7.24.5 + debug: 4.3.4(supports-color@5.5.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: false + /@babel/types@7.24.5: resolution: {integrity: sha512-6mQNsaLeXTw0nxYUYu+NSa4Hx4BlF1x1x8/PMFbiR+GBSr+2DkECc69b8hgy2frEodNcvPffeH8YfWd3LI6jhQ==} engines: {node: '>=6.9.0'} @@ -3459,6 +3501,14 @@ packages: /@emotion/memoize@0.8.1: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} + /@emotion/stylis@0.8.5: + resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==} + dev: false + + /@emotion/unitless@0.7.5: + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + dev: false + /@emotion/unitless@0.8.1: resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} @@ -9009,6 +9059,21 @@ packages: zod-validation-error: 2.1.0(zod@3.23.8) dev: false + /babel-plugin-styled-components@2.1.4(@babel/core@7.24.5)(styled-components@5.3.11): + resolution: {integrity: sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==} + peerDependencies: + styled-components: '>= 2' + dependencies: + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-module-imports': 7.24.3 + '@babel/plugin-syntax-jsx': 7.24.1(@babel/core@7.24.5) + lodash: 4.17.21 + picomatch: 2.3.1 + styled-components: 5.3.11(@babel/core@7.24.5)(react-dom@18.3.1)(react-is@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@babel/core' + dev: false + /babel-preset-current-node-syntax@1.0.1(@babel/core@7.24.5): resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==} peerDependencies: @@ -10306,6 +10371,19 @@ packages: dependencies: ms: 2.1.3 + /debug@4.3.4(supports-color@5.5.0): + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + supports-color: 5.5.0 + dev: false + /debug@4.3.4(supports-color@9.4.0): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -13069,6 +13147,12 @@ packages: resolution: {integrity: sha512-UppQjyvPVclg+6t2KY/Rv03h0+bA5u6zwqVoz4LAC/L0fgYmIaCD7ZCrwe8WI1Gv01be1XL0QFsRbSdIHV/Wbw==} dev: false + /hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + dependencies: + react-is: 16.13.1 + dev: false + /homedir-polyfill@1.0.3: resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} engines: {node: '>=0.10.0'} @@ -17340,6 +17424,15 @@ packages: scheduler: 0.25.0-beta-04b058868c-20240508 dev: false + /react-dom@19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522): + resolution: {integrity: sha512-J4CsfTSptPKkhaPbaR6n/KohQiHZTrRZ8GL4H8rbAqN/Qpy69g2MIoLBr5/PUX21ye6JxC1ZRWJFna7Xdg1pdA==} + peerDependencies: + react: '*' + dependencies: + react: 19.0.0-rc-f994737d14-20240522 + scheduler: 0.25.0-rc-f994737d14-20240522 + dev: false + /react-dropzone@12.1.0(react@18.3.1): resolution: {integrity: sha512-iBYHA1rbopIvtzokEX4QubO6qk5IF/x3BtKGu74rF2JkQDXnwC4uO/lHKpaw4PJIV6iIAYOlwLv2FpiGyqHNog==} engines: {node: '>= 10.13'} @@ -17475,6 +17568,11 @@ packages: engines: {node: '>=0.10.0'} dev: false + /react@19.0.0-rc-f994737d14-20240522: + resolution: {integrity: sha512-SeU2v5Xy6FotVhKz0pMS2gvYP7HlkF0qgTskj3JzA1vlxcb3dQjxlm9t0ZlJqcgoyI3VFAw7bomuDMdgy1nBuw==} + engines: {node: '>=0.10.0'} + dev: false + /read-cmd-shim@4.0.0: resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -18151,6 +18249,10 @@ packages: resolution: {integrity: sha512-9BiO+0jJiftEqYhVXGIc7MQTxbDAd7mfRMIctKsH0DxvuN8vzzaOQbG5Jy720Pz6KUAjgAAJJ/2nZW35+XwuHg==} dev: false + /scheduler@0.25.0-rc-f994737d14-20240522: + resolution: {integrity: sha512-qS+xGFF7AljP2APO2iJe8zESNsK20k25MACz+WGOXPybUsRdi1ssvaoF93im2nSX2q/XT3wKkjdz6RQfbmaxdw==} + dev: false + /scroll-into-view-if-needed@3.1.0: resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} dependencies: @@ -18955,6 +19057,31 @@ packages: resolution: {integrity: sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==} dev: false + /styled-components@5.3.11(@babel/core@7.24.5)(react-dom@18.3.1)(react-is@18.3.1)(react@18.3.1): + resolution: {integrity: sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==} + engines: {node: '>=10'} + peerDependencies: + react: '*' + react-dom: '*' + react-is: '>= 16.8.0' + dependencies: + '@babel/helper-module-imports': 7.24.3 + '@babel/traverse': 7.24.5(supports-color@5.5.0) + '@emotion/is-prop-valid': 1.2.2 + '@emotion/stylis': 0.8.5 + '@emotion/unitless': 0.7.5 + babel-plugin-styled-components: 2.1.4(@babel/core@7.24.5)(styled-components@5.3.11) + css-to-react-native: 3.2.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + shallowequal: 1.1.0 + supports-color: 5.5.0 + transitivePeerDependencies: + - '@babel/core' + dev: false + /styled-components@6.1.11(react-dom@18.3.1)(react@18.3.1): resolution: {integrity: sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==} engines: {node: '>= 16'} @@ -18994,6 +19121,26 @@ packages: tslib: 2.6.2 dev: false + /styled-components@6.1.11(react-dom@19.0.0-rc-f994737d14-20240522)(react@19.0.0-rc-f994737d14-20240522): + resolution: {integrity: sha512-Ui0jXPzbp1phYij90h12ksljKGqF8ncGx+pjrNPsSPhbUUjWT2tD1FwGo2LF6USCnbrsIhNngDfodhxbegfEOA==} + engines: {node: '>= 16'} + peerDependencies: + react: '*' + react-dom: '*' + dependencies: + '@emotion/is-prop-valid': 1.2.2 + '@emotion/unitless': 0.8.1 + '@types/stylis': 4.2.5 + css-to-react-native: 3.2.0 + csstype: 3.1.3 + postcss: 8.4.38 + react: 19.0.0-rc-f994737d14-20240522 + react-dom: 19.0.0-rc-f994737d14-20240522(react@19.0.0-rc-f994737d14-20240522) + shallowequal: 1.1.0 + stylis: 4.3.2 + tslib: 2.6.2 + dev: false + /styled-jsx@5.1.1(@babel/core@7.24.5)(react@18.3.1): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index e461cbc53b68..d7e830df4337 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -8,3 +8,4 @@ packages: - 'packages/create-sanity' - 'packages/groq' - 'packages/sanity' + - 'packages/sanity/fixtures/examples/*' diff --git a/scripts/uploadBundles.ts b/scripts/uploadBundles.ts index 16399922a99a..4a14133abb97 100644 --- a/scripts/uploadBundles.ts +++ b/scripts/uploadBundles.ts @@ -16,7 +16,6 @@ const storage = new Storage({ const bucket = storage.bucket(readEnv('GCLOUD_BUCKET')) const corePkgs = ['sanity', '@sanity/vision'] as const -const sharedPkgs = ['react', 'react-dom', 'styled-components'] as const const appVersion = 'v1' @@ -83,41 +82,6 @@ async function copyPackages() { console.log(`Completed copy for directory ${pkg}`) } - console.log('**Copying shared dependencies**') - - // Shared dependencies are in `packages/@repo/shared-modules.bundle` - // with built files in `packages/@repo/shared-modules.bundle/dist/` - for (const pkg of sharedPkgs) { - console.log(`Copying files from ${pkg}`) - - const packageJson = JSON.parse( - await readFile( - `packages/@repo/shared-modules.bundle/node_modules/${pkg}/package.json`, - 'utf8', - ), - ) - const {version} = packageJson - - packageVersions.set(pkg, version) - - for await (const filePath of getFiles(`packages/@repo/shared-modules.bundle/dist/${pkg}`)) { - try { - const fileName = path.basename(filePath) - const options: UploadOptions = { - destination: `modules/${appVersion}/${pkg}/${version}/bare/${fileName}`, - gzip: true, - contentType: 'application/javascript', - } - - await bucket.upload(filePath, options) - } catch (error) { - throw new Error(`Failed to copy files from ${pkg}`, {cause: error}) - } - } - - console.log(`Completed copy for directory ${pkg}`) - } - return packageVersions }