diff --git a/packages/core/admin/_internal/cli/index.ts b/packages/core/admin/_internal/cli/index.ts index ae78fa8e93..05e591b9b9 100644 --- a/packages/core/admin/_internal/cli/index.ts +++ b/packages/core/admin/_internal/cli/index.ts @@ -9,6 +9,7 @@ const build: StrapiCommand = ({ command, ctx }) => { command .command('build') .option('-d, --debug', 'Enable debugging mode with verbose logs', false) + .option('--ignore-prompts', 'Ignore all prompts', false) .option('--minify', 'Minify the output', true) .option('--no-optimization', '[deprecated]: use minify instead') .option('--silent', "Don't log anything", false) @@ -31,7 +32,9 @@ const develop: StrapiCommand = ({ command, ctx }) => { .alias('dev') .option('-d, --debug', 'Enable debugging mode with verbose logs', false) .option('--silent', "Don't log anything", false) + .option('--ignore-prompts', 'Ignore all prompts', false) .option('--polling', 'Watch for file changes in network directories', false) + .option('--watch-admin', 'Watch the admin panel for hot changes', false) .option( '--no-build', '[deprecated]: there is middleware for the server, it is no longer a separate process' diff --git a/packages/core/admin/_internal/node/build.ts b/packages/core/admin/_internal/node/build.ts index 37008262ed..3396dbeb42 100644 --- a/packages/core/admin/_internal/node/build.ts +++ b/packages/core/admin/_internal/node/build.ts @@ -10,6 +10,10 @@ import { getTimer } from './core/timer'; import type { CLIContext } from '@strapi/strapi'; interface BuildOptions extends CLIContext { + /** + * @default false + */ + ignorePrompts?: boolean; /** * Minify the output * @@ -31,13 +35,15 @@ interface BuildOptions extends CLIContext { * * @description Builds the admin panel of the strapi application. */ -const build = async ({ logger, cwd, tsconfig, ...options }: BuildOptions) => { +const build = async ({ logger, cwd, tsconfig, ignorePrompts, ...options }: BuildOptions) => { const timer = getTimer(); - const { didInstall } = await checkRequiredDependencies({ cwd, logger }).catch((err) => { - logger.error(err.message); - process.exit(1); - }); + const { didInstall } = await checkRequiredDependencies({ cwd, logger, ignorePrompts }).catch( + (err) => { + logger.error(err.message); + process.exit(1); + } + ); if (didInstall) { return; diff --git a/packages/core/admin/_internal/node/core/dependencies.ts b/packages/core/admin/_internal/node/core/dependencies.ts index c4e3edd6cc..5813d27572 100644 --- a/packages/core/admin/_internal/node/core/dependencies.ts +++ b/packages/core/admin/_internal/node/core/dependencies.ts @@ -15,8 +15,8 @@ import { getPackageManager } from './managers'; const PEER_DEPS = { react: '^18.0.0', 'react-dom': '^18.0.0', - 'react-router-dom': '^5.0.0', - 'styled-components': '^5.0.0', + 'react-router-dom': '^5.2.0', + 'styled-components': '^5.2.1', }; interface CheckRequiredDependenciesResult { @@ -41,7 +41,11 @@ interface DepToInstall { const checkRequiredDependencies = async ({ cwd, logger, -}: Pick): Promise => { + ignorePrompts, +}: Pick< + BuildOptions, + 'cwd' | 'logger' | 'ignorePrompts' +>): Promise => { const pkg = await readPkgUp({ cwd }); if (!pkg) { @@ -102,7 +106,7 @@ const checkRequiredDependencies = async ({ /** * temporary until V5 when we _will_ be enforcing these dependencies as required. */ - if (process.env.NODE_ENV !== 'development') { + if (process.env.NODE_ENV !== 'development' || ignorePrompts) { return { didInstall: false }; } diff --git a/packages/core/admin/_internal/node/core/plugins.ts b/packages/core/admin/_internal/node/core/plugins.ts index fa2d9584a5..f3f5003b75 100644 --- a/packages/core/admin/_internal/node/core/plugins.ts +++ b/packages/core/admin/_internal/node/core/plugins.ts @@ -5,13 +5,6 @@ import { getModule, PackageJson } from './dependencies'; import { loadFile } from './files'; import { BuildContext, CreateBuildContextArgs } from '../createBuildContext'; -const CORE_PLUGINS = [ - '@strapi/plugin-content-manager', - '@strapi/plugin-content-type-builder', - '@strapi/plugin-email', - '@strapi/plugin-upload', -]; - interface PluginMeta { name: string; pathToPlugin: string; @@ -46,24 +39,6 @@ export const getEnabledPlugins = async ({ }: Pick) => { const plugins: Record = {}; - logger.debug('Core plugins', os.EOL, CORE_PLUGINS); - - for (const plugin of CORE_PLUGINS) { - const pkg = await getModule(plugin, cwd); - - if (pkg && validatePackageIsPlugin(pkg)) { - /** - * We know there's a name because these are our packages. - */ - const name = (pkg.strapi.name || pkg.name)!; - - plugins[name] = { - name, - pathToPlugin: plugin, - }; - } - } - /** * This is the list of dependencies that are installed in the user's project. * It will include libraries like "react", so we need to collect the ones that diff --git a/packages/core/admin/_internal/node/createBuildContext.ts b/packages/core/admin/_internal/node/createBuildContext.ts index d5393ab995..959caedb1c 100644 --- a/packages/core/admin/_internal/node/createBuildContext.ts +++ b/packages/core/admin/_internal/node/createBuildContext.ts @@ -5,7 +5,6 @@ import syncFs from 'node:fs'; import camelCase from 'lodash/camelCase'; import browserslist from 'browserslist'; import strapiFactory, { CLIContext } from '@strapi/strapi'; -import type { Strapi } from '@strapi/types'; import { getConfigUrls } from '@strapi/utils'; import { getStrapiAdminEnvVars, loadEnv } from './core/env'; @@ -14,6 +13,7 @@ import { isError } from './core/errors'; import type { BuildOptions } from './build'; import { DevelopOptions } from './develop'; import { getEnabledPlugins } from './core/plugins'; +import { Strapi } from '@strapi/types'; interface BuildContext { /** @@ -75,6 +75,7 @@ interface BuildContext { } interface CreateBuildContextArgs extends CLIContext { + strapi?: Strapi; options?: BuildContext['options']; } @@ -89,16 +90,24 @@ const createBuildContext = async ({ cwd, logger, tsconfig, + strapi, options = {}, }: CreateBuildContextArgs) => { - const strapiInstance = strapiFactory({ - // Directories - appDir: cwd, - distDir: tsconfig?.config.options.outDir ?? '', - // Options - autoReload: true, - serveAdminPanel: false, - }); + /** + * If you make a new strapi instance when one already exists, + * you will overwrite the global and the app will _most likely_ + * crash and die. + */ + const strapiInstance = + strapi ?? + strapiFactory({ + // Directories + appDir: cwd, + distDir: tsconfig?.config.options.outDir ?? '', + // Options + autoReload: true, + serveAdminPanel: false, + }); const { serverUrl, adminPath } = getConfigUrls(strapiInstance.config, true); diff --git a/packages/core/admin/_internal/node/develop.ts b/packages/core/admin/_internal/node/develop.ts index 6934eab865..3d27479081 100644 --- a/packages/core/admin/_internal/node/develop.ts +++ b/packages/core/admin/_internal/node/develop.ts @@ -7,29 +7,78 @@ import cluster from 'node:cluster'; import { getTimer } from './core/timer'; import { checkRequiredDependencies } from './core/dependencies'; import { createBuildContext } from './createBuildContext'; -import { watch as watchWebpack } from './webpack/watch'; +import { WebpackWatcher, watch as watchWebpack } from './webpack/watch'; +import { build as buildWebpack } from './webpack/build'; import EE from '@strapi/strapi/dist/utils/ee'; import { writeStaticClientFiles } from './staticFiles'; +import strapiFactory from '@strapi/strapi'; interface DevelopOptions extends CLIContext { + /** + * @default false + */ + ignorePrompts?: boolean; polling?: boolean; open?: boolean; + watchAdmin?: boolean; } -const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOptions) => { +const develop = async ({ + cwd, + polling, + logger, + tsconfig, + ignorePrompts, + watchAdmin, + ...options +}: DevelopOptions) => { const timer = getTimer(); if (cluster.isPrimary) { - const { didInstall } = await checkRequiredDependencies({ cwd, logger }).catch((err) => { - logger.error(err.message); - process.exit(1); - }); + const { didInstall } = await checkRequiredDependencies({ cwd, logger, ignorePrompts }).catch( + (err) => { + logger.error(err.message); + process.exit(1); + } + ); if (didInstall) { return; } + /** + * IF we're not watching the admin we're going to build it, this makes + * sure that at least the admin is built for users & they can interact + * with the application. + */ + if (!watchAdmin) { + timer.start('createBuildContext'); + const contextSpinner = logger.spinner(`Building build context`).start(); + console.log(''); + + const ctx = await createBuildContext({ + cwd, + logger, + tsconfig, + options, + }); + const contextDuration = timer.end('createBuildContext'); + contextSpinner.text = `Building build context (${contextDuration}ms)`; + contextSpinner.succeed(); + + timer.start('creatingAdmin'); + const adminSpinner = logger.spinner(`Creating admin`).start(); + + EE.init(cwd); + await writeStaticClientFiles(ctx); + await buildWebpack(ctx); + + const adminDuration = timer.end('creatingAdmin'); + adminSpinner.text = `Creating admin (${adminDuration}ms)`; + adminSpinner.succeed(); + } + cluster.on('message', async (worker, message) => { switch (message) { case 'reload': { @@ -66,32 +115,48 @@ const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOp compilingTsSpinner.succeed(); } - timer.start('createBuildContext'); - const contextSpinner = logger.spinner(`Building build context`).start(); - console.log(''); - - const ctx = await createBuildContext({ - cwd, - logger, - tsconfig, - options, + const strapi = strapiFactory({ + appDir: cwd, + distDir: tsconfig?.config.options.outDir ?? '', + autoReload: true, + serveAdminPanel: !watchAdmin, }); - const contextDuration = timer.end('createBuildContext'); - contextSpinner.text = `Building build context (${contextDuration}ms)`; - contextSpinner.succeed(); - timer.start('creatingAdmin'); - const adminSpinner = logger.spinner(`Creating admin`).start(); + let webpackWatcher: WebpackWatcher | undefined; - EE.init(cwd); - await writeStaticClientFiles(ctx); - await watchWebpack(ctx); + /** + * If we're watching the admin panel then we're going to attach the watcher + * as a strapi middleware. + */ + if (watchAdmin) { + timer.start('createBuildContext'); + const contextSpinner = logger.spinner(`Building build context`).start(); + console.log(''); - const adminDuration = timer.end('creatingAdmin'); - adminSpinner.text = `Creating admin (${adminDuration}ms)`; - adminSpinner.succeed(); + const ctx = await createBuildContext({ + cwd, + logger, + strapi, + tsconfig, + options, + }); + const contextDuration = timer.end('createBuildContext'); + contextSpinner.text = `Building build context (${contextDuration}ms)`; + contextSpinner.succeed(); - const strapiInstance = await ctx.strapi.load(); + timer.start('creatingAdmin'); + const adminSpinner = logger.spinner(`Creating admin`).start(); + + EE.init(cwd); + await writeStaticClientFiles(ctx); + webpackWatcher = await watchWebpack(ctx); + + const adminDuration = timer.end('creatingAdmin'); + adminSpinner.text = `Creating admin (${adminDuration}ms)`; + adminSpinner.succeed(); + } + + const strapiInstance = await strapi.load(); timer.start('generatingTS'); const generatingTsSpinner = logger.spinner(`Generating types`).start(); @@ -164,7 +229,12 @@ const develop = async ({ cwd, polling, logger, tsconfig, ...options }: DevelopOp 'child process has the kill message, destroying the strapi instance and sending the killed process message' ); await watcher.close(); + await strapiInstance.destroy(); + + if (webpackWatcher) { + webpackWatcher.close(); + } process.send?.('killed'); break; } diff --git a/packages/core/admin/_internal/node/staticFiles.ts b/packages/core/admin/_internal/node/staticFiles.ts index 53f23ed82c..5ae9545c24 100644 --- a/packages/core/admin/_internal/node/staticFiles.ts +++ b/packages/core/admin/_internal/node/staticFiles.ts @@ -4,6 +4,7 @@ import outdent from 'outdent'; import { format } from 'prettier'; import { createElement } from 'react'; import { renderToStaticMarkup } from 'react-dom/server'; +import { DefaultDocument as Document } from '../../admin/src/components/DefaultDocument'; import type { BuildContext } from './createBuildContext'; @@ -26,7 +27,7 @@ const getEntryModule = ({ plugins }: EntryModuleArgs): string => { * Any modifications made will be discarded. */ ${pluginsImport} - import { renderAdmin } from "@strapi/admin/strapi-admin" + import { renderAdmin } from "@strapi/strapi/admin" renderAdmin( document.getElementById("strapi"), @@ -38,21 +39,11 @@ const getEntryModule = ({ plugins }: EntryModuleArgs): string => { `; }; -const getDefaultDocumentComponent = () => { - // eslint-disable-next-line @typescript-eslint/no-var-requires, node/no-missing-require - const { DefaultDocument } = require('@strapi/admin/strapi-admin'); - - return DefaultDocument; -}; - /** * TODO: Here in the future we could add the ability * to load a user's Document component? */ -const getDocumentHTML = ({ logger }: Pick) => { - const Document = getDefaultDocumentComponent(); - logger.debug('Got the default document'); - +const getDocumentHTML = async ({ logger }: Pick) => { const result = renderToStaticMarkup(createElement(Document)); logger.debug('Rendered the HTML'); @@ -84,7 +75,9 @@ const writeStaticClientFiles = async (ctx: BuildContext) => { await fs.mkdir(ctx.runtimeDir, { recursive: true }); ctx.logger.debug('Created the runtime directory'); - const indexHtml = decorateHTMLWithAutoGeneratedWarning(getDocumentHTML({ logger: ctx.logger })); + const indexHtml = decorateHTMLWithAutoGeneratedWarning( + await getDocumentHTML({ logger: ctx.logger }) + ); await fs.writeFile( path.join(ctx.runtimeDir, 'index.html'), diff --git a/packages/core/admin/_internal/node/webpack/config.ts b/packages/core/admin/_internal/node/webpack/config.ts index 2a1f0be1a4..8cf2ad9ab2 100644 --- a/packages/core/admin/_internal/node/webpack/config.ts +++ b/packages/core/admin/_internal/node/webpack/config.ts @@ -33,12 +33,23 @@ const resolveBaseConfig = async (ctx: BuildContext) => { module: { rules: [ { - test: /\.(t|j)sx?$/, + test: /\.(ts|tsx)$/, loader: require.resolve('esbuild-loader'), options: { loader: 'tsx', - jsx: 'automatic', target, + jsx: 'automatic', + }, + }, + { + test: /\.(js|jsx|mjs)$/, + use: { + loader: require.resolve('esbuild-loader'), + options: { + loader: 'jsx', + target, + jsx: 'automatic', + }, }, }, { diff --git a/packages/core/admin/_internal/node/webpack/watch.ts b/packages/core/admin/_internal/node/webpack/watch.ts index 838ff4f2a2..4c3528a7db 100644 --- a/packages/core/admin/_internal/node/webpack/watch.ts +++ b/packages/core/admin/_internal/node/webpack/watch.ts @@ -1,19 +1,24 @@ import os from 'node:os'; import path from 'node:path'; +import { promisify } from 'node:util'; import webpackDevMiddleware from 'webpack-dev-middleware'; import webpackHotMiddleware from 'webpack-hot-middleware'; import { webpack } from 'webpack'; import type { BuildContext } from '../createBuildContext'; import { mergeConfigWithUserConfig, resolveDevelopmentConfig } from './config'; -import { Common } from '@strapi/types'; +import { Common, Strapi } from '@strapi/types'; -const watch = async (ctx: BuildContext) => { +interface WebpackWatcher { + close(): Promise; +} + +const watch = async (ctx: BuildContext): Promise => { const config = await resolveDevelopmentConfig(ctx); const finalConfig = await mergeConfigWithUserConfig(config, ctx); ctx.logger.debug('Final webpack config:', os.EOL, finalConfig); - return new Promise((res) => { + return new Promise((res) => { const compiler = webpack(finalConfig); const devMiddleware = webpackDevMiddleware(compiler); @@ -91,9 +96,18 @@ const watch = async (ctx: BuildContext) => { ]); devMiddleware.waitUntilValid(() => { - res(true); + res({ + async close() { + await Promise.all([ + promisify(devMiddleware.close.bind(devMiddleware))(), + hotMiddleware.close(), + promisify(compiler.close.bind(compiler))(), + ]); + }, + }); }); }); }; export { watch }; +export type { WebpackWatcher }; diff --git a/packages/core/admin/package.json b/packages/core/admin/package.json index 8a3015a53a..a99e724aa9 100644 --- a/packages/core/admin/package.json +++ b/packages/core/admin/package.json @@ -75,6 +75,7 @@ "@radix-ui/react-context": "1.0.1", "@radix-ui/react-toolbar": "1.0.4", "@reduxjs/toolkit": "1.9.7", + "@strapi/data-transfer": "4.15.1", "@strapi/design-system": "1.13.0", "@strapi/helper-plugin": "4.15.1", "@strapi/icons": "1.13.0", @@ -95,6 +96,7 @@ "css-loader": "^6.8.1", "date-fns": "2.30.0", "dotenv": "14.2.0", + "esbuild": "0.19.2", "esbuild-loader": "^2.21.0", "esbuild-register": "3.5.0", "execa": "5.1.1", @@ -171,7 +173,6 @@ }, "devDependencies": { "@strapi/admin-test-utils": "4.15.1", - "@strapi/data-transfer": "4.15.1", "@strapi/pack-up": "workspace:*", "@strapi/strapi": "4.15.1", "@testing-library/dom": "9.2.0", @@ -188,7 +189,11 @@ }, "peerDependencies": { "@strapi/data-transfer": "4.15.1", - "@strapi/strapi": "^4.3.4" + "@strapi/strapi": "^4.3.4", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0", + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/core/admin/tsconfig.json b/packages/core/admin/tsconfig.json index d4bc062ea4..c63a63d751 100644 --- a/packages/core/admin/tsconfig.json +++ b/packages/core/admin/tsconfig.json @@ -1,10 +1,5 @@ { - "extends": "tsconfig/base.json", - "compilerOptions": { - "module": "ESNext", - "moduleResolution": "Bundler", - "noEmit": true - }, + "extends": "tsconfig/client.json", "include": ["_internal", "packup.config.ts"], "exclude": ["node_modules"] } diff --git a/packages/core/content-type-builder/package.json b/packages/core/content-type-builder/package.json index b8d699c211..0d40a30f4b 100644 --- a/packages/core/content-type-builder/package.json +++ b/packages/core/content-type-builder/package.json @@ -77,8 +77,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/core/data-transfer/src/commands/data-transfer.ts b/packages/core/data-transfer/src/commands/data-transfer.ts index 3639a81169..8a0d3569f7 100644 --- a/packages/core/data-transfer/src/commands/data-transfer.ts +++ b/packages/core/data-transfer/src/commands/data-transfer.ts @@ -5,7 +5,7 @@ import { configs, createLogger } from '@strapi/logger'; import strapiFactory from '@strapi/strapi'; import ora from 'ora'; import { merge } from 'lodash/fp'; -import type { LoadedStrapi } from '@strapi/types'; +import type { LoadedStrapi, Strapi } from '@strapi/types'; import { readableBytes, exitWith } from './helpers'; import { getParseListWithChoices, parseInteger, confirmMessage } from './commander'; @@ -148,7 +148,9 @@ const setSignalHandler = async ( }); }; -const createStrapiInstance = async (opts: { logLevel?: string } = {}) => { +const createStrapiInstance = async ( + opts: { logLevel?: string } = {} +): Promise> => { try { const appContext = await strapiFactory.compile(); const app = strapiFactory({ ...opts, ...appContext }); diff --git a/packages/core/email/package.json b/packages/core/email/package.json index b4bac7c6e0..4c915b55d0 100644 --- a/packages/core/email/package.json +++ b/packages/core/email/package.json @@ -81,8 +81,8 @@ "koa": "2.13.4", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/core/helper-plugin/package.json b/packages/core/helper-plugin/package.json index a2efc46f9c..a358f26ef9 100644 --- a/packages/core/helper-plugin/package.json +++ b/packages/core/helper-plugin/package.json @@ -100,8 +100,8 @@ "@strapi/icons": "1.13.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "^5.3.4", - "styled-components": "^5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/core/strapi/package.json b/packages/core/strapi/package.json index 1465197226..b12db25c8d 100644 --- a/packages/core/strapi/package.json +++ b/packages/core/strapi/package.json @@ -64,6 +64,30 @@ "url": "https://strapi.io" } ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "source": "./src/index.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js", + "default": "./dist/index.js" + }, + "./dist/utils/ee": { + "types": "./dist/utils/ee.d.ts", + "source": "./src/utils/ee.ts", + "import": "./dist/utils/ee.mjs", + "require": "./dist/utils/ee.js", + "default": "./dist/utils/ee.js" + }, + "./admin": { + "types": "./dist/admin.d.ts", + "source": "./src/admin.ts", + "import": "./dist/admin.mjs", + "require": "./dist/admin.js", + "default": "./dist/admin.js" + }, + "./package.json": "./package.json" + }, "main": "./dist/index.js", "module": "./dist/index.mjs", "source": "./src/index.ts", diff --git a/packages/core/strapi/packup.config.ts b/packages/core/strapi/packup.config.ts index e9d04140f4..05d5f09b71 100644 --- a/packages/core/strapi/packup.config.ts +++ b/packages/core/strapi/packup.config.ts @@ -4,13 +4,28 @@ import { builtinModules } from 'node:module'; export default defineConfig({ bundles: [ + { + source: './src/index.ts', + import: './dist/index.js', + require: './dist/index.js', + types: './dist/index.d.ts', + runtime: 'node', + }, { source: './src/cli.ts', require: './dist/cli.js', runtime: 'node', }, + { + source: './src/admin.ts', + import: './dist/admin.js', + require: './dist/admin.js', + types: './dist/index.d.ts', + runtime: 'web', + }, ], + exports: {}, + dist: './dist', externals: [...builtinModules], preserveModules: true, - runtime: 'node', }); diff --git a/packages/core/strapi/src/admin.ts b/packages/core/strapi/src/admin.ts new file mode 100644 index 0000000000..0502ebd0b8 --- /dev/null +++ b/packages/core/strapi/src/admin.ts @@ -0,0 +1,21 @@ +import { RenderAdminArgs, renderAdmin } from '@strapi/admin/strapi-admin'; +// @ts-expect-error – No types, yet. +import contentTypeBuilder from '@strapi/plugin-content-type-builder/strapi-admin'; +import email from '@strapi/plugin-email/strapi-admin'; +// @ts-expect-error – No types, yet. +import upload from '@strapi/plugin-upload/strapi-admin'; + +const render = (mountNode: HTMLElement | null, { plugins }: RenderAdminArgs) => { + return renderAdmin(mountNode, { + plugins: { + 'content-type-builder': contentTypeBuilder, + // @ts-expect-error – TODO: fix this + email, + upload, + ...plugins, + }, + }); +}; + +export { render as renderAdmin }; +export type { RenderAdminArgs }; diff --git a/packages/core/strapi/src/commands/actions/plugin/build-command/action.ts b/packages/core/strapi/src/commands/actions/plugin/build-command/action.ts index 99bd24cde9..f9db9da023 100644 --- a/packages/core/strapi/src/commands/actions/plugin/build-command/action.ts +++ b/packages/core/strapi/src/commands/actions/plugin/build-command/action.ts @@ -12,6 +12,10 @@ interface ActionOptions extends BuildCLIOptions { export default async ({ force, ...opts }: ActionOptions) => { const logger = createLogger({ debug: opts.debug, silent: opts.silent, timestamp: false }); try { + /** + * ALWAYS set production for using plugin build CLI. + */ + process.env.NODE_ENV = 'production'; /** * Notify users this is an experimental command and get them to approve first * this can be opted out by setting the argument --yes diff --git a/packages/core/upload/package.json b/packages/core/upload/package.json index bee3d33958..f5cb596109 100644 --- a/packages/core/upload/package.json +++ b/packages/core/upload/package.json @@ -85,8 +85,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/generators/generators/src/templates/js/plugin-package.json.hbs b/packages/generators/generators/src/templates/js/plugin-package.json.hbs index 9815e69e51..2609f63277 100644 --- a/packages/generators/generators/src/templates/js/plugin-package.json.hbs +++ b/packages/generators/generators/src/templates/js/plugin-package.json.hbs @@ -23,8 +23,8 @@ "peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "^5.3.4", - "styled-components": "^5.3.6" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "author": { "name": "A Strapi developer" diff --git a/packages/generators/generators/src/templates/ts/plugin-package.json.hbs b/packages/generators/generators/src/templates/ts/plugin-package.json.hbs index 4bf831f38f..64c7db712a 100644 --- a/packages/generators/generators/src/templates/ts/plugin-package.json.hbs +++ b/packages/generators/generators/src/templates/ts/plugin-package.json.hbs @@ -28,8 +28,8 @@ "peerDependencies": { "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "^5.3.4", - "styled-components": "^5.3.6" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "author": { "name": "A Strapi developer" diff --git a/packages/plugins/color-picker/package.json b/packages/plugins/color-picker/package.json index d997bc4143..821edd7450 100644 --- a/packages/plugins/color-picker/package.json +++ b/packages/plugins/color-picker/package.json @@ -76,8 +76,8 @@ "@strapi/strapi": "^4.4.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/plugins/documentation/package.json b/packages/plugins/documentation/package.json index a3f53a24d4..a14a6f7d21 100644 --- a/packages/plugins/documentation/package.json +++ b/packages/plugins/documentation/package.json @@ -80,8 +80,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/plugins/graphql/package.json b/packages/plugins/graphql/package.json index 79170345b6..68c97db877 100644 --- a/packages/plugins/graphql/package.json +++ b/packages/plugins/graphql/package.json @@ -73,8 +73,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/plugins/i18n/package.json b/packages/plugins/i18n/package.json index 2a2485d427..807f95230d 100644 --- a/packages/plugins/i18n/package.json +++ b/packages/plugins/i18n/package.json @@ -76,8 +76,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/plugins/sentry/package.json b/packages/plugins/sentry/package.json index 856e4b25c9..e7fe587e3a 100644 --- a/packages/plugins/sentry/package.json +++ b/packages/plugins/sentry/package.json @@ -60,8 +60,8 @@ "@strapi/strapi": "^4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/packages/plugins/users-permissions/package.json b/packages/plugins/users-permissions/package.json index 92fdc50da3..4f38c5325f 100644 --- a/packages/plugins/users-permissions/package.json +++ b/packages/plugins/users-permissions/package.json @@ -83,8 +83,8 @@ "@strapi/strapi": "4.0.0", "react": "^17.0.0 || ^18.0.0", "react-dom": "^17.0.0 || ^18.0.0", - "react-router-dom": "5.3.4", - "styled-components": "5.3.3" + "react-router-dom": "^5.2.0", + "styled-components": "^5.2.1" }, "engines": { "node": ">=18.0.0 <=20.x.x", diff --git a/yarn.lock b/yarn.lock index ed1da20bb7..836fd234d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8673,6 +8673,7 @@ __metadata: css-loader: "npm:^6.8.1" date-fns: "npm:2.30.0" dotenv: "npm:14.2.0" + esbuild: "npm:0.19.2" esbuild-loader: "npm:^2.21.0" esbuild-register: "npm:3.5.0" execa: "npm:5.1.1" @@ -8751,6 +8752,10 @@ __metadata: peerDependencies: "@strapi/data-transfer": 4.15.1 "@strapi/strapi": ^4.3.4 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -8962,8 +8967,8 @@ __metadata: "@strapi/icons": 1.13.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: ^5.3.4 - styled-components: ^5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9102,8 +9107,8 @@ __metadata: "@strapi/strapi": ^4.4.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9150,8 +9155,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9191,8 +9196,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9225,8 +9230,8 @@ __metadata: koa: 2.13.4 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9263,8 +9268,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9298,8 +9303,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9321,8 +9326,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9370,8 +9375,8 @@ __metadata: "@strapi/strapi": ^4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft @@ -9413,8 +9418,8 @@ __metadata: "@strapi/strapi": 4.0.0 react: ^17.0.0 || ^18.0.0 react-dom: ^17.0.0 || ^18.0.0 - react-router-dom: 5.3.4 - styled-components: 5.3.3 + react-router-dom: ^5.2.0 + styled-components: ^5.2.1 languageName: unknown linkType: soft