mirror of
https://gitee.com/nocobase/nocobase.git
synced 2024-11-29 18:58:26 +08:00
fix: improve build (#2643)
* fix: client lib require wrapper * fix: bug * fix: add tsconfig.paths.json * fix: collection dir not exists * fix: improve... * fix: update yarn.lock * fix: db.sync * fix: bugs * fix: bugs * fix: bugs * fix: bugs && allow user custom build config * docs: user custom config docs * refactor: custom user build config * fix: bugs * fix: build plugin-client bug --------- Co-authored-by: chenos <chenlinxh@gmail.com>
This commit is contained in:
parent
dbe3af26a1
commit
9e5e96b9e4
1
.gitignore
vendored
1
.gitignore
vendored
@ -30,3 +30,4 @@ storage/plugins
|
||||
storage/tar
|
||||
storage/tmp
|
||||
storage/app.watch.ts
|
||||
tsconfig.paths.json
|
||||
|
@ -12,6 +12,34 @@ An empty plugin can be created quickly with `yarn pm create my-plugin`, with the
|
||||
|- package.json # plugin package information
|
||||
|- server.d.ts
|
||||
|- server.js
|
||||
|- build.config.ts # or `build.config.js`, modify configuration
|
||||
```
|
||||
|
||||
The tutorial for `/src/server` refers to the [server](./server) section, and the tutorial for `/src/client` refers to the [client](./client) section.
|
||||
|
||||
If you want to customize the packaging configuration, you can create a `config.js` file in the root directory, with the following content:
|
||||
|
||||
```js
|
||||
import { defineConfig } from '@nocobase/build';
|
||||
|
||||
export default defineConfig({
|
||||
modifyViteConfig: (config) => {
|
||||
// vite is used to package the `src/client` side code
|
||||
|
||||
// Modify the Vite configuration, for more information, please refer to: https://vitejs.dev/guide/
|
||||
return config
|
||||
},
|
||||
modifyTsupConfig: (config) => {
|
||||
// tsup is used to package the `src/server` side code
|
||||
|
||||
// Modify the tsup configuration, for more information, please refer to: https://tsup.egoist.dev/#using-custom-configuration
|
||||
return config
|
||||
},
|
||||
beforeBuild: (log) => {
|
||||
// The callback function before the build starts, you can do some operations before the build starts
|
||||
},
|
||||
afterBuild: (log: PkgLog) => {
|
||||
// The callback function after the build is completed, you can do some operations after the build is completed
|
||||
};
|
||||
})
|
||||
```
|
||||
|
@ -12,6 +12,34 @@
|
||||
|- package.json # 插件包信息
|
||||
|- server.d.ts
|
||||
|- server.js
|
||||
|- build.config.ts # 或者 `build.config.js` ,用于修改打包配置,实现自定义逻辑
|
||||
```
|
||||
|
||||
`/src/server` 的教程参考 [服务端](./server) 章节,`/src/client` 的教程参考 [客户端](./client) 章节。
|
||||
|
||||
如果你想要自定义打包配置,可以在根目录下创建 `config.js` 文件,内容如下:
|
||||
|
||||
```js
|
||||
import { defineConfig } from '@nocobase/build';
|
||||
|
||||
export default defineConfig({
|
||||
modifyViteConfig: (config) => {
|
||||
// vite 是用来打包 `src/client` 端代码的
|
||||
|
||||
// 修改 Vite 配置,具体可参考:https://vitejs.dev/guide/
|
||||
return config
|
||||
},
|
||||
modifyTsupConfig: (config) => {
|
||||
// tsup 是用来打包 `src/server` 端代码的
|
||||
|
||||
// 修改 tsup 配置,具体可参考:https://tsup.egoist.dev/#using-custom-configuration
|
||||
return config
|
||||
},
|
||||
beforeBuild: (log) => {
|
||||
// 构建开始前的回调函数,可以在构建开始前做一些操作
|
||||
},
|
||||
afterBuild: (log: PkgLog) => {
|
||||
// 构建完成后的回调函数,可以在构建完成后做一些操作
|
||||
};
|
||||
});
|
||||
```
|
||||
|
@ -1,5 +1,5 @@
|
||||
const { pathsToModuleNameMapper } = require('ts-jest');
|
||||
const { compilerOptions } = require('./tsconfig.json');
|
||||
const { compilerOptions } = require('./tsconfig.paths.json');
|
||||
const { defaults } = require('jest-config');
|
||||
|
||||
module.exports = {
|
||||
|
@ -87,7 +87,7 @@
|
||||
"react-dom": "^18.0.0",
|
||||
"ts-jest": "^29.1.1",
|
||||
"typescript": "5.1.3",
|
||||
"vite": "^4.4.1",
|
||||
"vite": "^4.4.9",
|
||||
"vitest": "^0.34.3"
|
||||
},
|
||||
"volta": {
|
||||
|
@ -3,6 +3,7 @@
|
||||
"version": "0.14.0-alpha.3",
|
||||
"description": "Library build tool based on rollup.",
|
||||
"main": "lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"bin": {
|
||||
"nocobase-build": "./bin/nocobase-build.js"
|
||||
},
|
||||
@ -28,7 +29,8 @@
|
||||
"update-notifier": "3.0.0",
|
||||
"vite-plugin-css-injected-by-js": "^3.2.1",
|
||||
"vite-plugin-lib-inject-css": "1.2.0",
|
||||
"yargs-parser": "13.1.2"
|
||||
"yargs-parser": "13.1.2",
|
||||
"esbuild-register": "^3.4.2"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
|
@ -14,7 +14,7 @@ import { buildClient } from './buildClient';
|
||||
import { buildCjs } from './buildCjs';
|
||||
import { buildPlugin } from './buildPlugin';
|
||||
import { buildDeclaration } from './buildDeclaration';
|
||||
import { PkgLog, getPkgLog, toUnixPath, getPackageJson } from './utils';
|
||||
import { PkgLog, getPkgLog, toUnixPath, getPackageJson, getUserConfig, UserConfig } from './utils';
|
||||
import { getPackages } from './utils/getPackages';
|
||||
import { Package } from '@lerna/package';
|
||||
import { tarPlugin } from './tarPlugin'
|
||||
@ -23,6 +23,11 @@ export async function build(pkgs: string[]) {
|
||||
process.env.NODE_ENV = 'production';
|
||||
|
||||
const packages = getPackages(pkgs);
|
||||
if (packages.length === 0) {
|
||||
console.error(chalk.red(`[@nocobase/build]: '${pkgs.join(', ')}' not match any packages.`));
|
||||
return;
|
||||
}
|
||||
|
||||
const pluginPackages = getPluginPackages(packages);
|
||||
const cjsPackages = getCjsPackages(packages);
|
||||
const presetsPackages = getPresetsPackages(packages);
|
||||
@ -52,7 +57,7 @@ export async function build(pkgs: string[]) {
|
||||
export async function buildPackages(
|
||||
packages: Package[],
|
||||
targetDir: string,
|
||||
doBuildPackage: (cwd: string, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
doBuildPackage: (cwd: string, userConfig: UserConfig, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
) {
|
||||
for await (const pkg of packages) {
|
||||
await buildPackage(pkg, targetDir, doBuildPackage);
|
||||
@ -62,7 +67,7 @@ export async function buildPackages(
|
||||
export async function buildPackage(
|
||||
pkg: Package,
|
||||
targetDir: string,
|
||||
doBuildPackage: (cwd: string, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
doBuildPackage: (cwd: string, userConfig: UserConfig, sourcemap: boolean, log?: PkgLog) => Promise<any>,
|
||||
) {
|
||||
const sourcemap = process.argv.includes('--sourcemap');
|
||||
const noDeclaration = process.argv.includes('--no-dts');
|
||||
@ -79,15 +84,20 @@ export async function buildPackage(
|
||||
|
||||
log(`${chalk.bold(toUnixPath(pkg.location.replace(PACKAGES_PATH, '').slice(1)))} build start`);
|
||||
|
||||
const userConfig = getUserConfig(pkg.location);
|
||||
// prebuild
|
||||
if (packageJson?.scripts?.prebuild) {
|
||||
log('prebuild');
|
||||
await runScript(['prebuild'], pkg.location);
|
||||
await packageJson.prebuild(pkg.location);
|
||||
}
|
||||
if (userConfig.beforeBuild) {
|
||||
log('beforeBuild');
|
||||
await userConfig.beforeBuild(log);
|
||||
}
|
||||
|
||||
// build source
|
||||
await doBuildPackage(pkg.location, sourcemap, log);
|
||||
await doBuildPackage(pkg.location, userConfig, sourcemap, log);
|
||||
|
||||
// build declaration
|
||||
if (!noDeclaration) {
|
||||
@ -101,6 +111,11 @@ export async function buildPackage(
|
||||
await runScript(['postbuild'], pkg.location);
|
||||
}
|
||||
|
||||
if (userConfig.afterBuild) {
|
||||
log('afterBuild');
|
||||
await userConfig.afterBuild(log);
|
||||
}
|
||||
|
||||
// tar
|
||||
if (hasTar) {
|
||||
await tarPlugin(pkg.location, log);
|
||||
|
@ -3,9 +3,9 @@ import fg from 'fast-glob';
|
||||
import path from 'path';
|
||||
import chalk from 'chalk';
|
||||
import { globExcludeFiles, EsbuildSupportExts } from './constant';
|
||||
import { PkgLog } from './utils';
|
||||
import { PkgLog, UserConfig } from './utils';
|
||||
|
||||
export function buildCjs(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
export function buildCjs(cwd: string, userConfig: UserConfig, sourcemap: boolean = false, log: PkgLog) {
|
||||
log('build cjs');
|
||||
|
||||
const entry = fg.globSync(['src/**', ...globExcludeFiles], { cwd, absolute: true });
|
||||
@ -14,8 +14,7 @@ export function buildCjs(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
if (otherExts.length) {
|
||||
log('%s will not be processed, only be copied to the lib directory.', chalk.yellow(otherExts.join(',')));
|
||||
}
|
||||
|
||||
return build({
|
||||
return build(userConfig.modifyTsupConfig({
|
||||
entry,
|
||||
splitting: false,
|
||||
clean: true,
|
||||
@ -32,5 +31,5 @@ export function buildCjs(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
},
|
||||
format: 'cjs',
|
||||
skipNodeModulesBundle: true,
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
@ -1,26 +1,37 @@
|
||||
import path from 'path';
|
||||
import fg from 'fast-glob';
|
||||
import fs from 'fs-extra';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import { build as tsupBuild } from 'tsup';
|
||||
import { libInjectCss } from 'vite-plugin-lib-inject-css';
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { PkgLog } from './utils';
|
||||
|
||||
import { PkgLog, UserConfig } from './utils';
|
||||
import { globExcludeFiles } from './constant';
|
||||
|
||||
export async function buildClient(cwd: string, sourcemap: boolean = false, log: PkgLog) {
|
||||
|
||||
export async function buildClient(cwd: string, userConfig: UserConfig, sourcemap: boolean = false, log: PkgLog) {
|
||||
log('build client');
|
||||
|
||||
await Promise.all([buildLib(cwd, sourcemap, 'cjs'), buildLib(cwd, sourcemap, 'es')]);
|
||||
await buildLocale(cwd);
|
||||
}
|
||||
|
||||
export function buildLib(cwd: string, sourcemap: boolean, format: 'cjs' | 'es') {
|
||||
const outDir = path.resolve(cwd, format === 'cjs' ? 'lib' : 'es');
|
||||
const entry = path.join(cwd, 'src/index.ts').replaceAll(/\\/g, '/');
|
||||
const cwdWin = cwd.replaceAll(/\\/g, '/');
|
||||
const cwdUnix = cwd.replaceAll(/\//g, '\\');
|
||||
const external = function (id: string) {
|
||||
if (id.startsWith('.') || id.startsWith(cwdUnix) || id.startsWith(cwdWin)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
await buildEsm(cwd, userConfig, sourcemap, external, log);
|
||||
await buildLib(cwd, userConfig, sourcemap, external, log);
|
||||
await buildLocale(cwd, userConfig, log);
|
||||
}
|
||||
|
||||
return viteBuild({
|
||||
type External = (id: string) => boolean;
|
||||
|
||||
export function buildEsm(cwd: string, userConfig: UserConfig, sourcemap: boolean, external: External, log: PkgLog) {
|
||||
log('build client esm');
|
||||
const entry = path.join(cwd, 'src/index.ts').replaceAll(/\\/g, '/');
|
||||
const outDir = path.resolve(cwd, 'es');
|
||||
return viteBuild(userConfig.modifyViteConfig({
|
||||
mode: 'production',
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
@ -33,29 +44,63 @@ export function buildLib(cwd: string, sourcemap: boolean, format: 'cjs' | 'es')
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: [format],
|
||||
formats: ['es'],
|
||||
fileName: 'index',
|
||||
},
|
||||
target: ['es2015', 'edge88', 'firefox78', 'chrome87', 'safari14'],
|
||||
rollupOptions: {
|
||||
cache: true,
|
||||
treeshake: true,
|
||||
external(id) {
|
||||
if (id.startsWith('.') || id.startsWith(cwdUnix) || id.startsWith(cwdWin)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
external,
|
||||
},
|
||||
},
|
||||
plugins: [react(), libInjectCss()],
|
||||
}));
|
||||
}
|
||||
|
||||
export async function buildLib(cwd: string, userConfig: UserConfig, sourcemap: boolean, external: External, log: PkgLog) {
|
||||
log('build client lib');
|
||||
const outDir = path.resolve(cwd, 'lib');
|
||||
const esDir = path.resolve(cwd, 'es');
|
||||
const entry = path.join(esDir, 'index.ts')
|
||||
|
||||
fs.removeSync(entry);
|
||||
fs.linkSync(path.join(cwd, 'es/index.mjs'), entry);
|
||||
|
||||
await viteBuild(userConfig.modifyViteConfig({
|
||||
mode: 'production',
|
||||
esbuild: {
|
||||
format: 'cjs'
|
||||
},
|
||||
build: {
|
||||
outDir,
|
||||
minify: false,
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry: path.join(cwd, 'es/index.ts'),
|
||||
formats: ['cjs'],
|
||||
fileName: 'index',
|
||||
},
|
||||
rollupOptions: {
|
||||
external,
|
||||
},
|
||||
},
|
||||
}));
|
||||
|
||||
fs.removeSync(entry);
|
||||
|
||||
const css = fg.sync('*.css', { cwd: esDir, absolute: true });
|
||||
css.forEach((file) => {
|
||||
fs.copySync(file, path.join(outDir, path.basename(file)));
|
||||
});
|
||||
}
|
||||
|
||||
export function buildLocale(cwd: string) {
|
||||
export function buildLocale(cwd: string, userConfig: UserConfig, log: PkgLog) {
|
||||
log('build client locale');
|
||||
|
||||
const entry = fg.globSync(['src/locale/**', ...globExcludeFiles], { cwd, absolute: true });
|
||||
const outDir = path.resolve(cwd, 'lib', 'locale');
|
||||
return tsupBuild({
|
||||
return tsupBuild(userConfig.modifyTsupConfig({
|
||||
entry,
|
||||
splitting: false,
|
||||
clean: false,
|
||||
@ -67,5 +112,5 @@ export function buildLocale(cwd: string) {
|
||||
outDir,
|
||||
format: 'cjs',
|
||||
skipNodeModulesBundle: true,
|
||||
});
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
@ -7,7 +7,6 @@ import { build as tsupBuild } from 'tsup';
|
||||
import { build as viteBuild } from 'vite';
|
||||
import fg from 'fast-glob';
|
||||
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js';
|
||||
import { transformAsync } from '@babel/core';
|
||||
|
||||
import {
|
||||
buildCheck,
|
||||
@ -20,7 +19,7 @@ import {
|
||||
} from './utils/buildPluginUtils';
|
||||
import { getDepPkgPath, getDepsConfig } from './utils/getDepsConfig';
|
||||
import { EsbuildSupportExts, globExcludeFiles } from './constant';
|
||||
import { PkgLog, getPackageJson } from './utils';
|
||||
import { PkgLog, UserConfig, getPackageJson } from './utils';
|
||||
|
||||
const serverGlobalFiles: string[] = ['src/**', '!src/client/**', ...globExcludeFiles];
|
||||
const clientGlobalFiles: string[] = ['src/**', '!src/server/**', ...globExcludeFiles];
|
||||
@ -247,7 +246,7 @@ export async function buildServerDeps(cwd: string, serverFiles: string[], log: P
|
||||
}
|
||||
}
|
||||
|
||||
export async function buildPluginServer(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
export async function buildPluginServer(cwd: string, userConfig: UserConfig, sourcemap: boolean, log: PkgLog) {
|
||||
log('build plugin server source');
|
||||
const packageJson = getPackageJson(cwd);
|
||||
const serverFiles = fg.globSync(serverGlobalFiles, { cwd, absolute: true });
|
||||
@ -257,7 +256,7 @@ export async function buildPluginServer(cwd: string, sourcemap: boolean, log: Pk
|
||||
log('%s will not be processed, only be copied to the dist directory.', chalk.yellow(otherExts.join(',')));
|
||||
}
|
||||
|
||||
await tsupBuild({
|
||||
await tsupBuild(userConfig.modifyTsupConfig({
|
||||
entry: serverFiles,
|
||||
splitting: false,
|
||||
clean: false,
|
||||
@ -273,50 +272,12 @@ export async function buildPluginServer(cwd: string, sourcemap: boolean, log: Pk
|
||||
...otherExts.reduce((prev, cur) => ({ ...prev, [cur]: 'copy' }), {}),
|
||||
'.json': 'copy',
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
await buildServerDeps(cwd, serverFiles, log);
|
||||
}
|
||||
|
||||
export function transformClientFilesToAmd(outDir: string, outputFileName: string, packageName: string, log: PkgLog) {
|
||||
const files = fs.readdirSync(outDir);
|
||||
|
||||
return Promise.all(files.map(async file => {
|
||||
const filePath = path.join(outDir, file);
|
||||
|
||||
// 只编译 JavaScript 文件
|
||||
if (path.extname(filePath) === '.mjs' || path.extname(filePath) === '.js') {
|
||||
let fileContent = fs.readFileSync(filePath, 'utf-8');
|
||||
|
||||
// import('./dayjs.mjs') => import(window.staticBaseUrl + '/@nocobase/plugin-acl/dayjs.mjs?noExt')
|
||||
if (file === outputFileName) {
|
||||
fileContent = fileContent.replace(dynamicImportRegexp, (match, _1, dynamicImportPath) => {
|
||||
let absolutePath = path.join(outDir, dynamicImportPath).replace(outDir, '');
|
||||
if (absolutePath.startsWith(path.sep)) {
|
||||
absolutePath = absolutePath.slice(1);
|
||||
}
|
||||
return `import(window.staticBaseUrl + '/${packageName}/${absolutePath}?noExt')`;
|
||||
})
|
||||
}
|
||||
|
||||
const { code } = await transformAsync(fileContent, {
|
||||
presets: [['@babel/preset-env', {
|
||||
modules: 'amd',
|
||||
targets: {
|
||||
'edge': 88,
|
||||
'firefox': 78,
|
||||
'chrome': 87,
|
||||
'safari': 14,
|
||||
}
|
||||
}]],
|
||||
plugins: ['@babel/plugin-transform-modules-amd'],
|
||||
});
|
||||
fs.writeFileSync(filePath, code, 'utf-8');
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
export async function buildPluginClient(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
export async function buildPluginClient(cwd: string, userConfig: UserConfig, sourcemap: boolean, log: PkgLog) {
|
||||
log('build plugin client');
|
||||
const packageJson = getPackageJson(cwd);
|
||||
const clientFiles = fg.globSync(clientGlobalFiles, { cwd, absolute: true });
|
||||
@ -326,10 +287,6 @@ export async function buildPluginClient(cwd: string, sourcemap: boolean, log: Pk
|
||||
|
||||
checkRequire(clientFiles, log);
|
||||
buildCheck({ cwd, packageJson, entry: 'client', files: clientFiles, log });
|
||||
const hasDynamicImport = false;
|
||||
// const hasDynamicImport = clientFileSource.some((source) => {
|
||||
// return source.match(dynamicImportRegexp);
|
||||
// });
|
||||
const outDir = path.join(cwd, target_dir, 'client');
|
||||
|
||||
const globals = excludePackages.reduce<Record<string, string>>((prev, curr) => {
|
||||
@ -342,7 +299,8 @@ export async function buildPluginClient(cwd: string, sourcemap: boolean, log: Pk
|
||||
|
||||
const entry = fg.globSync('src/client/index.{ts,tsx,js,jsx}', { absolute: true, cwd });
|
||||
const outputFileName = 'index.js';
|
||||
await viteBuild({
|
||||
|
||||
await viteBuild(userConfig.modifyViteConfig({
|
||||
mode: 'production',
|
||||
define: {
|
||||
'process.env.NODE_ENV': JSON.stringify('production'),
|
||||
@ -356,7 +314,7 @@ export async function buildPluginClient(cwd: string, sourcemap: boolean, log: Pk
|
||||
sourcemap,
|
||||
lib: {
|
||||
entry,
|
||||
formats: [hasDynamicImport ? 'es' : 'umd'],
|
||||
formats: ['umd'],
|
||||
name: packageJson.name,
|
||||
fileName: () => outputFileName,
|
||||
},
|
||||
@ -378,26 +336,13 @@ export async function buildPluginClient(cwd: string, sourcemap: boolean, log: Pk
|
||||
react(),
|
||||
cssInjectedByJsPlugin({ styleId: packageJson.name }),
|
||||
],
|
||||
});
|
||||
}));
|
||||
|
||||
checkFileSize(outDir, log);
|
||||
|
||||
// if (hasDynamicImport) {
|
||||
// await transformClientFilesToAmd(outDir, outputFileName, packageJson.name, log);
|
||||
// }
|
||||
}
|
||||
|
||||
export async function buildPlugin(cwd: string, sourcemap: boolean, log: PkgLog) {
|
||||
await buildPluginClient(cwd, sourcemap, log);
|
||||
await buildPluginServer(cwd, sourcemap, log);
|
||||
const buildFile = path.join(cwd, 'build.js');
|
||||
if (fs.existsSync(buildFile)) {
|
||||
log('build others');
|
||||
try {
|
||||
await require(buildFile).run(log);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
export async function buildPlugin(cwd: string, userConfig: UserConfig, sourcemap: boolean, log: PkgLog) {
|
||||
await buildPluginClient(cwd, userConfig, sourcemap, log);
|
||||
await buildPluginServer(cwd, userConfig, sourcemap, log);
|
||||
writeExternalPackageVersion(cwd, log);
|
||||
}
|
||||
|
14
packages/core/build/src/index.d.ts
vendored
Normal file
14
packages/core/build/src/index.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
|
||||
import { Options as TsupConfig } from 'tsup'
|
||||
import { InlineConfig as ViteConfig } from 'vite'
|
||||
|
||||
export type PkgLog = (msg: string, ...args: any[]) => void;
|
||||
|
||||
interface UserConfig {
|
||||
modifyTsupConfig?: (config: TsupConfig) => TsupConfig;
|
||||
modifyViteConfig?: (config: ViteConfig) => ViteConfig;
|
||||
beforeBuild?: (log: PkgLog) => void | Promise<void>;
|
||||
afterBuild?: (log: PkgLog) => void | Promise<void>;
|
||||
}
|
||||
|
||||
declare const defineConfig: (config: UserConfig) => UserConfig;
|
@ -1 +1,2 @@
|
||||
export * from './build';
|
||||
export * from './utils'
|
||||
|
@ -1,5 +1,10 @@
|
||||
import chalk from 'chalk';
|
||||
import path from 'path';
|
||||
import fs from 'fs-extra';
|
||||
import fg from 'fast-glob';
|
||||
import { Options as TsupConfig } from 'tsup'
|
||||
import { InlineConfig as ViteConfig } from 'vite'
|
||||
import { register } from 'esbuild-register/dist/node';
|
||||
|
||||
let previousColor = '';
|
||||
function randomColor() {
|
||||
@ -44,3 +49,33 @@ export function toUnixPath(filepath: string) {
|
||||
export function getPackageJson(cwd: string) {
|
||||
return require(path.join(cwd, 'package.json'));
|
||||
}
|
||||
|
||||
export interface UserConfig {
|
||||
modifyTsupConfig?: (config: TsupConfig) => TsupConfig;
|
||||
modifyViteConfig?: (config: ViteConfig) => ViteConfig;
|
||||
beforeBuild?: (log: PkgLog) => void | Promise<void>;
|
||||
afterBuild?: (log: PkgLog) => void | Promise<void>;
|
||||
}
|
||||
|
||||
export function defineConfig(config: UserConfig): UserConfig {
|
||||
return config;
|
||||
}
|
||||
|
||||
export function getUserConfig(cwd: string) {
|
||||
const config = defineConfig({
|
||||
modifyTsupConfig: (config: TsupConfig) => config,
|
||||
modifyViteConfig: (config: ViteConfig) => config,
|
||||
});
|
||||
|
||||
const buildConfigs = fg.sync(['build.config.js', 'build.config.ts'], { cwd });
|
||||
if (buildConfigs.length > 1) {
|
||||
throw new Error(`Multiple build configs found: ${buildConfigs.join(', ')}`);
|
||||
}
|
||||
if (buildConfigs.length === 1) {
|
||||
const { unregister } = register({})
|
||||
const userConfig = require(path.join(cwd, buildConfigs[0]));
|
||||
unregister()
|
||||
Object.assign(config, userConfig.default || userConfig);
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
@ -9,8 +9,12 @@ export default defineConfig({
|
||||
entry,
|
||||
outDir: path.join(__dirname, 'lib'),
|
||||
splitting: false,
|
||||
silent: true,
|
||||
sourcemap: false,
|
||||
clean: true,
|
||||
bundle: false,
|
||||
loader: {
|
||||
'.d.ts': 'copy'
|
||||
},
|
||||
skipNodeModulesBundle: true,
|
||||
});
|
||||
|
@ -4,6 +4,7 @@ const dotenv = require('dotenv');
|
||||
const { resolve } = require('path');
|
||||
const { existsSync } = require('fs');
|
||||
const chalk = require('chalk');
|
||||
const { genTsConfigPaths } = require('../src/util');
|
||||
|
||||
const env = {
|
||||
APP_ENV: 'development',
|
||||
@ -29,6 +30,8 @@ if (!process.env.APP_ENV_PATH && process.argv[2] && process.argv[2] === 'test')
|
||||
}
|
||||
}
|
||||
|
||||
genTsConfigPaths();
|
||||
|
||||
dotenv.config({
|
||||
path: resolve(process.cwd(), process.env.APP_ENV_PATH || '.env'),
|
||||
});
|
||||
|
@ -24,6 +24,7 @@ module.exports = (cli) => {
|
||||
});
|
||||
if (options.watch) return;
|
||||
}
|
||||
|
||||
await run('nocobase-build', [
|
||||
...pkgs,
|
||||
options.version ? '--version' : '',
|
||||
|
@ -16,5 +16,6 @@ module.exports = (cli) => {
|
||||
}
|
||||
run('rimraf', ['-rf', './storage/app-dev']);
|
||||
run('rimraf', ['-rf', 'packages/*/*/{lib,esm,es,dist,node_modules}']);
|
||||
run('rimraf', ['-rf', 'packages/*/@*/*/{lib,esm,es,dist,node_modules}']);
|
||||
});
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
const { Command } = require('commander');
|
||||
const { nodeCheck, runAppCommand, promptForTs } = require('../util');
|
||||
const { nodeCheck, runAppCommand, promptForTs, genTsConfigPaths } = require('../util');
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -0,0 +1,5 @@
|
||||
const util = require('./util');
|
||||
|
||||
module.exports = {
|
||||
...util,
|
||||
};
|
@ -3,6 +3,7 @@ const { existsSync } = require('fs');
|
||||
const { join, resolve } = require('path');
|
||||
const { Generator } = require('@umijs/utils');
|
||||
const { readFile, writeFile } = require('fs').promises;
|
||||
const { genTsConfigPaths } = require('./util');
|
||||
|
||||
const execa = require('execa');
|
||||
|
||||
@ -46,16 +47,6 @@ class PluginGenerator extends Generator {
|
||||
};
|
||||
}
|
||||
|
||||
async addTsConfigPaths() {
|
||||
const { name } = this.context;
|
||||
if (name.startsWith('@') && name.split('/')[0] !== '@nocobase') {
|
||||
const target = resolve(process.cwd(), 'tsconfig.json');
|
||||
const content = require(target);
|
||||
content.compilerOptions.paths[name] = [`packages/plugins/${name}/src`];
|
||||
await writeFile(target, JSON.stringify(content, null, 2), 'utf-8');
|
||||
}
|
||||
}
|
||||
|
||||
async writing() {
|
||||
const { name } = this.context;
|
||||
const target = resolve(process.cwd(), 'packages/plugins/', name);
|
||||
@ -70,7 +61,7 @@ class PluginGenerator extends Generator {
|
||||
path: join(__dirname, '../templates/plugin'),
|
||||
});
|
||||
console.log('');
|
||||
await this.addTsConfigPaths();
|
||||
genTsConfigPaths();
|
||||
execa.sync('yarn', ['install'], { shell: true, stdio: 'inherit' });
|
||||
// execa.sync('yarn', ['build', `plugins/${name}`], { shell: true, stdio: 'inherit' });
|
||||
console.log(`The plugin folder is in ${chalk.green(`packages/plugins/${name}`)}`);
|
||||
|
@ -1,9 +1,10 @@
|
||||
const net = require('net');
|
||||
const chalk = require('chalk');
|
||||
const execa = require('execa');
|
||||
const { dirname, resolve } = require('path');
|
||||
const fg = require('fast-glob');
|
||||
const { dirname, join, resolve } = require('path');
|
||||
const { readFile, writeFile } = require('fs').promises;
|
||||
const { existsSync, mkdirSync, cpSync } = require('fs');
|
||||
const { existsSync, mkdirSync, cpSync, writeFileSync } = require('fs');
|
||||
|
||||
exports.isPackageValid = (package) => {
|
||||
try {
|
||||
@ -174,3 +175,32 @@ exports.generateAppDir = function generateAppDir() {
|
||||
process.env.APP_PACKAGE_ROOT = appPkgPath;
|
||||
}
|
||||
};
|
||||
|
||||
exports.genTsConfigPaths = function genTsConfigPaths() {
|
||||
const cwd = process.cwd();
|
||||
const cwdLength = cwd.length;
|
||||
const paths = {
|
||||
'@@/*': ['.dumi/tmp/*'],
|
||||
};
|
||||
const packages = fg.sync(['packages/*/*/package.json', 'packages/*/*/*/package.json'], {
|
||||
absolute: true,
|
||||
onlyFiles: true,
|
||||
});
|
||||
packages.forEach((packageFile) => {
|
||||
const packageJsonName = require(packageFile).name;
|
||||
const packageDir = dirname(packageFile);
|
||||
const relativePath = packageDir.slice(cwdLength + 1).replace(/\\/, '/');
|
||||
const hasClient = fg.sync(['client', 'client.ts', 'client.tsx', 'client.js', 'client.jsx'], {
|
||||
cwd: join(packageDir, 'src'),
|
||||
}).length;
|
||||
if (hasClient) {
|
||||
paths[`${packageJsonName}/client`] = [`${relativePath}/src/client`];
|
||||
}
|
||||
paths[packageJsonName] = [`${relativePath}/src`];
|
||||
});
|
||||
|
||||
const tsConfigJsonPath = join(cwd, './tsconfig.paths.json');
|
||||
const content = { compilerOptions: { paths } };
|
||||
writeFileSync(tsConfigJsonPath, JSON.stringify(content, null, 2), 'utf-8');
|
||||
return content;
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
const { pathsToModuleNameMapper } = require('ts-jest/utils');
|
||||
const { compilerOptions } = require('./tsconfig.json');
|
||||
const { compilerOptions } = require('./tsconfig.paths.json');
|
||||
const { resolve } = require('path');
|
||||
|
||||
module.exports = {
|
||||
|
@ -4,6 +4,9 @@
|
||||
"workspaces": [
|
||||
"packages/*/*"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"nocobase": "nocobase",
|
||||
"pm": "nocobase pm",
|
||||
|
@ -1,4 +1,5 @@
|
||||
import path from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
import { readdir } from 'fs/promises';
|
||||
import { cloneDeep, isPlainObject } from 'lodash';
|
||||
import { requireModule } from '@nocobase/utils';
|
||||
@ -20,6 +21,9 @@ export class ImporterReader {
|
||||
}
|
||||
|
||||
async read() {
|
||||
if (!existsSync(this.directory)) {
|
||||
return [];
|
||||
}
|
||||
const files = await readdir(this.directory, {
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
@ -63,7 +63,7 @@ function getNamespace() {
|
||||
}
|
||||
|
||||
function getTsconfigPaths() {
|
||||
const content = fs.readFileSync(resolve(process.cwd(), 'tsconfig.json'), 'utf-8');
|
||||
const content = fs.readFileSync(resolve(process.cwd(), 'tsconfig.paths.json'), 'utf-8');
|
||||
const json = JSON.parse(content);
|
||||
return json.compilerOptions.paths;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
"main": "./dist/server/index.js",
|
||||
"devDependencies": {
|
||||
"@types/jsonwebtoken": "^8.5.8",
|
||||
"async-mutex": "^0.4.0",
|
||||
"async-mutex": "^0.3.2",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { defineConfig } from '@nocobase/build';
|
||||
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
export default defineConfig({
|
||||
afterBuild: async (log) => {
|
||||
const dir = path.resolve(__dirname, './dist/china-division');
|
||||
if (existsSync(dir)) {
|
||||
await fs.rm(dir, { recursive: true });
|
||||
}
|
||||
|
||||
const keys = ['areas', 'cities', 'provinces'];
|
||||
for (const key of keys) {
|
||||
log(`coping ${key}.json`);
|
||||
await fs.cp(require.resolve(`china-division/dist/${key}.json`), path.resolve(dir, `${key}.json`), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
@ -1,21 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs/promises');
|
||||
const path = require('path');
|
||||
const existsSync = require('fs').existsSync;
|
||||
|
||||
exports.run = async (log) => {
|
||||
const dir = path.resolve(__dirname, './dist/china-division');
|
||||
if (existsSync(dir)) {
|
||||
await fs.rmdir(dir, { force: true, recursive: true });
|
||||
}
|
||||
|
||||
const keys = ['areas', 'cities', 'provinces'];
|
||||
for (const key of keys) {
|
||||
log(`coping ${key}.json`);
|
||||
await fs.cp(require.resolve(`china-division/dist/${key}.json`), path.resolve(dir, `${key}.json`), {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
}
|
||||
};
|
42
packages/plugins/@nocobase/plugin-client/build.config.ts
Normal file
42
packages/plugins/@nocobase/plugin-client/build.config.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import fs from 'fs/promises';
|
||||
import path from 'path';
|
||||
import { defineConfig } from '@nocobase/build';
|
||||
|
||||
const existsSync = require('fs').existsSync;
|
||||
|
||||
const client = path.dirname(require.resolve('@nocobase/client/package.json'));
|
||||
const antd = require.resolve('antd');
|
||||
|
||||
export default defineConfig({
|
||||
afterBuild: async (log) => {
|
||||
const localeDir = path.resolve(__dirname, './dist/locale');
|
||||
if (existsSync(localeDir)) {
|
||||
await fs.rm(localeDir, { recursive: true });
|
||||
}
|
||||
|
||||
log('coping client locale');
|
||||
await fs.cp(path.resolve(client, 'lib', 'locale'), localeDir, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
|
||||
log('coping antd locale');
|
||||
const files = await fs.readdir(path.resolve(path.dirname(antd), 'locale'));
|
||||
await fs.mkdir(path.resolve(localeDir, 'antd'), { recursive: true });
|
||||
for (const file of files) {
|
||||
if (path.extname(file) !== '.js') {
|
||||
continue;
|
||||
}
|
||||
const content = require(path.resolve(path.dirname(antd), 'locale', file)).default;
|
||||
try {
|
||||
await fs.writeFile(
|
||||
path.resolve(localeDir, 'antd', file),
|
||||
`module.exports = ${JSON.stringify(content)}`,
|
||||
'utf-8',
|
||||
);
|
||||
} catch (error) {
|
||||
log(`skip ${file}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const fs = require('fs/promises');
|
||||
const path = require('path');
|
||||
const existsSync = require('fs').existsSync;
|
||||
|
||||
const client = require.resolve('@nocobase/client');
|
||||
const antd = require.resolve('antd');
|
||||
|
||||
exports.run = async (log) => {
|
||||
const localeDir = path.resolve(__dirname, './dist/locale');
|
||||
if (existsSync(localeDir)) {
|
||||
await fs.rmdir(localeDir, { force: true, recursive: true });
|
||||
}
|
||||
|
||||
log('coping client locale');
|
||||
await fs.cp(path.resolve(path.dirname(client), 'locale'), localeDir, {
|
||||
recursive: true,
|
||||
force: true,
|
||||
});
|
||||
|
||||
log('coping antd locale');
|
||||
const files = await fs.readdir(path.resolve(path.dirname(antd), 'locale'));
|
||||
await fs.mkdir(path.resolve(localeDir, 'antd'), { force: true, recursive: true });
|
||||
for (const file of files) {
|
||||
if (path.extname(file) !== '.js') {
|
||||
continue;
|
||||
}
|
||||
const content = require(path.resolve(path.dirname(antd), 'locale', file)).default;
|
||||
try {
|
||||
await fs.writeFile(
|
||||
path.resolve(localeDir, 'antd', file),
|
||||
`module.exports = ${JSON.stringify(content)}`,
|
||||
'utf-8',
|
||||
{},
|
||||
);
|
||||
} catch (error) {
|
||||
log(`skip ${file}`);
|
||||
}
|
||||
}
|
||||
};
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"extends": "./tsconfig.paths.json",
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"moduleResolution": "node",
|
||||
@ -16,17 +17,7 @@
|
||||
"declaration": true,
|
||||
"experimentalDecorators": true,
|
||||
"downlevelIteration": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@nocobase/app-*": ["packages/app/*/src"],
|
||||
"@nocobase/plugin-*": ["packages/plugins/@nocobase/plugin-*/src"],
|
||||
"@nocobase/preset-*": ["packages/presets/*/src"],
|
||||
"@nocobase/evaluators/client": ["packages/core/evaluators/src/client"],
|
||||
"@nocobase/utils/plugin-symlink": ["packages/core/utils/plugin-symlink"],
|
||||
"@nocobase/utils/client": ["packages/core/utils/src/client"],
|
||||
"@nocobase/*": ["packages/core/*/src"],
|
||||
"@@/*": [".dumi/tmp/*"]
|
||||
}
|
||||
"baseUrl": "."
|
||||
},
|
||||
"ts-node": {
|
||||
"compilerOptions": {
|
||||
|
@ -1,5 +1,19 @@
|
||||
import react from '@vitejs/plugin-react';
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import tsConfigPaths from './tsconfig.paths.json';
|
||||
|
||||
const paths = tsConfigPaths.compilerOptions.paths;
|
||||
|
||||
const alias = Object.keys(paths).reduce<{ find: string; replacement: string }[]>((acc, key) => {
|
||||
if (key !== '@@/*') {
|
||||
const value = paths[key][0];
|
||||
acc.push({
|
||||
find: key,
|
||||
replacement: value,
|
||||
});
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
@ -14,15 +28,8 @@ export default defineConfig({
|
||||
threads: true,
|
||||
alias: [
|
||||
{ find: 'testUtils', replacement: 'testUtils.ts' },
|
||||
{ find: '@nocobase/evaluators/client', replacement: 'packages/core/evaluators/src/client' },
|
||||
{ find: '@nocobase/utils/client', replacement: 'packages/core/utils/src/client' },
|
||||
{ find: /^~antd\/(.*)/, replacement: 'antd/$1' },
|
||||
{ find: /^@nocobase\/app-(.*)/, replacement: 'packages/$1/src' },
|
||||
{ find: /^@nocobase\/plugin-sample-(.*)/, replacement: 'packages/samples/$1/src' },
|
||||
{ find: /^@nocobase\/plugin-pro-(.*)/, replacement: 'packages/pro-plugins/$1/src' },
|
||||
{ find: /^@nocobase\/plugin-(.*)/, replacement: 'packages/plugins/$1/src' },
|
||||
{ find: /^@nocobase\/preset-(.*)/, replacement: 'packages/presets/$1/src' },
|
||||
{ find: /^@nocobase\/(.*)/, replacement: 'packages/core/$1/src' },
|
||||
...alias,
|
||||
],
|
||||
include: ['packages/**/{dumi-theme-nocobase,sdk,client}/**/__tests__/**/*.{test,spec}.{ts,tsx}'],
|
||||
exclude: ['**/node_modules/**', '**/dist/**', '**/lib/**', '**/es/**', '**/{vitest,commitlint}.config.*'],
|
||||
|
38
yarn.lock
38
yarn.lock
@ -7569,12 +7569,6 @@ async-mutex@^0.3.2:
|
||||
dependencies:
|
||||
tslib "^2.3.1"
|
||||
|
||||
async-mutex@^0.4.0:
|
||||
version "0.4.0"
|
||||
resolved "https://registry.yarnpkg.com/async-mutex/-/async-mutex-0.4.0.tgz#ae8048cd4d04ace94347507504b3cf15e631c25f"
|
||||
dependencies:
|
||||
tslib "^2.4.0"
|
||||
|
||||
async-ratelimiter@^1.3.0:
|
||||
version "1.3.8"
|
||||
resolved "https://registry.npmmirror.com/async-ratelimiter/-/async-ratelimiter-1.3.8.tgz#05198a322543de43d98807c96295a9d712306928"
|
||||
@ -11004,6 +10998,13 @@ es6-weak-map@^2.0.1:
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.1"
|
||||
|
||||
esbuild-register@^3.4.2:
|
||||
version "3.4.2"
|
||||
resolved "https://registry.npmmirror.com/esbuild-register/-/esbuild-register-3.4.2.tgz#1e39ee0a77e8f320a9790e68c64c3559620b9175"
|
||||
integrity sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==
|
||||
dependencies:
|
||||
debug "^4.3.4"
|
||||
|
||||
esbuild@0.12.15:
|
||||
version "0.12.15"
|
||||
resolved "https://registry.npmmirror.com/esbuild/-/esbuild-0.12.15.tgz#9d99cf39aeb2188265c5983e983e236829f08af0"
|
||||
@ -18890,9 +18891,10 @@ postcss@^8.3.11, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.7:
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
postcss@^8.4.24:
|
||||
version "8.4.25"
|
||||
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.25.tgz#4a133f5e379eda7f61e906c3b1aaa9b81292726f"
|
||||
postcss@^8.4.27:
|
||||
version "8.4.29"
|
||||
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd"
|
||||
integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==
|
||||
dependencies:
|
||||
nanoid "^3.3.6"
|
||||
picocolors "^1.0.0"
|
||||
@ -20678,9 +20680,10 @@ rollup@^3.20.2, rollup@^3.21.0:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
rollup@^3.25.2:
|
||||
version "3.26.2"
|
||||
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.26.2.tgz#2e76a37606cb523fc9fef43e6f59c93f86d95e7c"
|
||||
rollup@^3.27.1:
|
||||
version "3.29.1"
|
||||
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.29.1.tgz#ba53a179d46ac3cd79e162dca6ab70d93cd26f78"
|
||||
integrity sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
@ -23314,13 +23317,14 @@ vite@4.3.1:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
vite@^4.4.1:
|
||||
version "4.4.1"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-4.4.1.tgz#cfe0baf6af4b1b9f3b37c5ebf1e012622be3da98"
|
||||
vite@^4.4.9:
|
||||
version "4.4.9"
|
||||
resolved "https://registry.npmmirror.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d"
|
||||
integrity sha512-2mbUn2LlUmNASWwSCNSJ/EG2HuSRTnVNaydp6vMCm5VIqJsjMfbIWtbH2kDuwUVW5mMUKKZvGPX/rqeqVvv1XA==
|
||||
dependencies:
|
||||
esbuild "^0.18.10"
|
||||
postcss "^8.4.24"
|
||||
rollup "^3.25.2"
|
||||
postcss "^8.4.27"
|
||||
rollup "^3.27.1"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user