diff --git a/build/info.ts b/build/build-info.ts similarity index 83% rename from build/info.ts rename to build/build-info.ts index 0339d3da99..05b7190546 100644 --- a/build/info.ts +++ b/build/build-info.ts @@ -1,5 +1,6 @@ import path from 'path' import { epOutput } from './utils/paths' +import { EP_PKG } from './utils/constants' import type { ModuleFormat } from 'rollup' export const modules = ['esm', 'cjs'] as const @@ -29,7 +30,7 @@ export const buildConfig: Record = { path: path.resolve(epOutput, 'es'), }, bundle: { - path: 'element-plus/es', + path: `${EP_PKG}/es`, }, }, cjs: { @@ -40,9 +41,13 @@ export const buildConfig: Record = { path: path.resolve(epOutput, 'lib'), }, bundle: { - path: 'element-plus/lib', + path: `${EP_PKG}/lib`, }, }, } +export const buildConfigEntries = Object.entries( + buildConfig +) as BuildConfigEntries + export type BuildConfig = typeof buildConfig export type BuildConfigEntries = [Module, BuildInfo][] diff --git a/build/component.ts b/build/component.ts deleted file mode 100644 index cd7241c883..0000000000 --- a/build/component.ts +++ /dev/null @@ -1,122 +0,0 @@ -import fs from 'fs' -import path from 'path' -import { series, parallel } from 'gulp' -import { rollup } from 'rollup' -import vue from 'rollup-plugin-vue' -import css from 'rollup-plugin-css-only' -import { nodeResolve } from '@rollup/plugin-node-resolve' -import commonjs from '@rollup/plugin-commonjs' -import esbuild from 'rollup-plugin-esbuild' -import { sync as globSync } from 'fast-glob' -import filesize from 'rollup-plugin-filesize' - -import { compRoot, buildOutput } from './utils/paths' -import { - generateExternal, - rollupPathRewriter, - writeBundles, -} from './utils/rollup' -import { run } from './utils/process' -import { withTaskName } from './utils/gulp' - -import { genComponentTypes } from './component-types' -import { buildConfig } from './info' -import reporter from './size-reporter' - -import type { OutputOptions } from 'rollup' -import type { Module, BuildConfigEntries } from './info' - -const plugins = [ - css(), - vue({ - target: 'browser', - // css: false, - }), - nodeResolve(), - commonjs(), - esbuild(), -] - -async function getComponents() { - const files = globSync('*', { - cwd: compRoot, - onlyDirectories: true, - }) - return files.map((file) => ({ - path: path.resolve(compRoot, file), - name: file, - })) -} - -export async function buildEachComponent() { - const componentPaths = await getComponents() - const external = await generateExternal({ full: false }) - const pathRewriter = await rollupPathRewriter() - - const builds = componentPaths.map( - async ({ path: p, name: componentName }) => { - const entry = path.resolve(p, 'index.ts') - if (!fs.existsSync(entry)) return - - const rollupConfig = { - input: entry, - plugins, - external, - } - const opts = (Object.entries(buildConfig) as BuildConfigEntries).map( - ([module, config]): OutputOptions => ({ - format: config.format, - file: path.resolve( - config.output.path, - 'components', - componentName, - 'index.js' - ), - exports: module === 'cjs' ? 'named' : undefined, - paths: pathRewriter(module), - plugins: [filesize({ reporter })], - }) - ) - - const bundle = await rollup(rollupConfig) - await writeBundles(bundle, opts) - } - ) - await Promise.all(builds) -} - -export async function buildComponentEntry() { - const entry = path.resolve(compRoot, 'index.ts') - const config = { - input: entry, - plugins, - external: () => true, - } - const opts = Object.values(buildConfig).map( - (config): OutputOptions => ({ - format: config.format, - file: path.resolve(config.output.path, 'components/index.js'), - plugins: [filesize({ reporter })], - }) - ) - - const bundle = await rollup(config) - await writeBundles(bundle, opts) -} - -function copyTypes() { - const src = `${buildOutput}/types/components/` - const copy = (module: Module) => - withTaskName(`copyTypes:${module}`, () => - run(`rsync -a ${src} ${buildConfig[module].output.path}/components/`) - ) - - return parallel(copy('esm'), copy('cjs')) -} - -export const buildComponent = series( - parallel(genComponentTypes, buildEachComponent, buildComponentEntry), - copyTypes() -) - -export { genComponentTypes } diff --git a/build/entry-types.ts b/build/entry-types.ts deleted file mode 100644 index 27dcd3f5e3..0000000000 --- a/build/entry-types.ts +++ /dev/null @@ -1,82 +0,0 @@ -import path from 'path' -import fs from 'fs/promises' -import { bold } from 'chalk' -import glob from 'fast-glob' -import { Project, ScriptTarget, ModuleKind } from 'ts-morph' -import { parallel } from 'gulp' -import { epRoot, buildOutput, projRoot } from './utils/paths' -import { yellow, green } from './utils/log' -import { buildConfig } from './info' -import { withTaskName } from './utils/gulp' -import { run } from './utils/process' -import type { Module } from './info' - -import type { SourceFile } from 'ts-morph' - -const TSCONFIG_PATH = path.resolve(projRoot, 'tsconfig.json') - -export const genEntryTypes = async () => { - const files = await glob('*.ts', { - cwd: epRoot, - absolute: true, - onlyFiles: true, - }) - const project = new Project({ - compilerOptions: { - module: ModuleKind.ESNext, - allowJs: true, - emitDeclarationOnly: true, - noEmitOnError: false, - outDir: path.resolve(buildOutput, 'entry/types'), - target: ScriptTarget.ESNext, - rootDir: epRoot, - strict: false, - }, - skipFileDependencyResolution: true, - tsConfigFilePath: TSCONFIG_PATH, - skipAddingFilesFromTsConfig: true, - }) - const sourceFiles: SourceFile[] = [] - files.map((f) => { - const sourceFile = project.addSourceFileAtPath(f) - sourceFiles.push(sourceFile) - }) - project.addSourceFilesAtPaths(path.resolve(projRoot, 'typings', '*.d.ts')) - - const diagnostics = project.getPreEmitDiagnostics() - - console.log(project.formatDiagnosticsWithColorAndContext(diagnostics)) - - await project.emit({ - emitOnlyDtsFiles: true, - }) - - const tasks = sourceFiles.map(async (sourceFile) => { - yellow(`Emitting file: ${bold(sourceFile.getFilePath())}`) - - const emitOutput = sourceFile.getEmitOutput() - for (const outputFile of emitOutput.getOutputFiles()) { - const filepath = outputFile.getFilePath() - - await fs.mkdir(path.dirname(filepath), { recursive: true }) - await fs.writeFile( - filepath, - outputFile.getText().replaceAll('@element-plus', '.'), - 'utf8' - ) - green(`Definition for file: ${bold(sourceFile.getBaseName())} generated`) - } - }) - - await Promise.all(tasks) -} - -export const copyEntryTypes = (() => { - const src = path.resolve(buildOutput, 'entry/types') - const copy = (module: Module) => - withTaskName(`copyEntryTypes:${module}`, () => - run(`rsync -a ${src}/ ${buildConfig[module].output.path}/`) - ) - - return parallel(copy('esm'), copy('cjs')) -})() diff --git a/build/full-bundle.ts b/build/full-bundle.ts index e54cc6e8d0..0eaaccaabd 100644 --- a/build/full-bundle.ts +++ b/build/full-bundle.ts @@ -1,64 +1,39 @@ import path from 'path' -import fs from 'fs' import { nodeResolve } from '@rollup/plugin-node-resolve' import { rollup } from 'rollup' import commonjs from '@rollup/plugin-commonjs' import vue from 'rollup-plugin-vue' import esbuild from 'rollup-plugin-esbuild' import replace from '@rollup/plugin-replace' +import filesize from 'rollup-plugin-filesize' import { parallel } from 'gulp' -import { genEntryTypes } from './entry-types' -import { RollupResolveEntryPlugin } from './rollup-plugin-entry' +import { version } from '../packages/element-plus/version' +import { RollupResolveEntryPlugin } from './plugins/rollup-plugin-entry' import { epRoot, epOutput } from './utils/paths' -import { yellow, green } from './utils/log' -import { - generateExternal, - rollupPathRewriter, - writeBundles, -} from './utils/rollup' -import { buildConfig } from './info' -import { run } from './utils/process' +import { generateExternal, writeBundles } from './utils/rollup' + import { withTaskName } from './utils/gulp' -import type { BuildConfigEntries } from './info' - -import type { RollupOptions, OutputOptions, InputOptions } from 'rollup' - -const getConfig = async ( - opt: { - minify?: boolean - sourceMap?: boolean - plugins?: InputOptions['plugins'] - } = {} -): Promise => ({ - input: path.resolve(epRoot, 'index.ts'), - plugins: [ - nodeResolve(), - vue({ - target: 'browser', - // css: false, - exposeFilename: false, - }), - commonjs(), - esbuild({ - minify: opt.minify, - sourceMap: opt.sourceMap, - }), - replace({ - 'process.env.NODE_ENV': JSON.stringify('production'), - }), - ...(opt.plugins ?? []), - ], - external: await generateExternal({ full: true }), -}) export const buildFull = (minify: boolean) => async () => { - const bundle = await rollup( - await getConfig({ - plugins: [RollupResolveEntryPlugin()], - minify, - sourceMap: minify, - }) - ) + const bundle = await rollup({ + input: path.resolve(epRoot, 'index.ts'), + plugins: [ + nodeResolve(), + vue({ + target: 'browser', + exposeFilename: false, + }), + commonjs(), + esbuild({ minify, sourceMap: minify }), + replace({ + 'process.env.NODE_ENV': JSON.stringify('production'), + }), + await RollupResolveEntryPlugin(), + filesize(), + ], + external: await generateExternal({ full: true }), + }) + const banner = `/*! Element Plus v${version} */\n` await writeBundles(bundle, [ { format: 'umd', @@ -69,6 +44,7 @@ export const buildFull = (minify: boolean) => async () => { vue: 'Vue', }, sourcemap: minify, + banner, }, { format: 'esm', @@ -77,51 +53,12 @@ export const buildFull = (minify: boolean) => async () => { `dist/index.full${minify ? '.min' : ''}.mjs` ), sourcemap: minify, + banner, }, ]) } -export const buildEntry = async () => { - const entryFiles = await fs.promises.readdir(epRoot, { - withFileTypes: true, - }) - - const entryPoints = entryFiles - .filter((f) => f.isFile()) - .filter((f) => !['package.json', 'README.md'].includes(f.name)) - .map((f) => path.resolve(epRoot, f.name)) - - const bundle = await rollup({ - ...(await getConfig()), - input: entryPoints, - external: () => true, - }) - - yellow('Generating entries') - const rewriter = await rollupPathRewriter() - writeBundles( - bundle, - (Object.entries(buildConfig) as BuildConfigEntries).map( - ([module, config]): OutputOptions => ({ - format: config.format, - dir: config.output.path, - exports: config.format === 'cjs' ? 'named' : undefined, - paths: rewriter(module), - }) - ) - ) - green('entries generated') -} - -export const copyFullStyle = () => - Promise.all([ - run(`cp ${epOutput}/theme-chalk/index.css ${epOutput}/dist/index.css`), - run(`cp -R ${epOutput}/theme-chalk/fonts ${epOutput}/dist/fonts`), - ]) - export const buildFullBundle = parallel( withTaskName('buildFullMinified', buildFull(true)), - withTaskName('buildFull', buildFull(false)), - buildEntry, - genEntryTypes + withTaskName('buildFull', buildFull(false)) ) diff --git a/build/gulpfile.ts b/build/gulpfile.ts index 0853b2991d..479cf44cec 100644 --- a/build/gulpfile.ts +++ b/build/gulpfile.ts @@ -1,54 +1,66 @@ import path from 'path' import { series, parallel } from 'gulp' -import { copyStyle } from './style' -import { copyEntryTypes } from './entry-types' import { run } from './utils/process' import { withTaskName } from './utils/gulp' -import { epOutput, epPackage, projRoot } from './utils/paths' -import { copyFullStyle } from './full-bundle' +import { buildOutput, epOutput, epPackage, projRoot } from './utils/paths' +import { buildConfig } from './build-info' +import type { TaskFunction } from 'gulp' +import type { Module } from './build-info' const runTask = (name: string) => withTaskName(name, () => run(`pnpm run build ${name}`)) -export const copySourceCode = async () => { - await run(`cp -R packages ${epOutput}`) - await run(`cp ${epPackage} ${epOutput}/package.json`) +export const copyFiles = () => { + const copyTypings = async () => { + const src = path.resolve(projRoot, 'typings', 'global.d.ts') + await run(`cp ${src} ${epOutput}`) + } + + return Promise.all([ + run(`cp ${epPackage} ${path.join(epOutput, 'package.json')}`), + run(`cp README.md ${epOutput}`), + copyTypings(), + ]) } -export const copyREADME = async () => { - await run(`cp README.md ${epOutput}`) +export const copyTypesDefinitions: TaskFunction = (done) => { + const src = `${buildOutput}/types/` + const copy = (module: Module) => + withTaskName(`copyTypes:${module}`, () => + run(`rsync -a ${src} ${buildConfig[module].output.path}/`) + ) + + return parallel(copy('esm'), copy('cjs'))(done) } -export const copyDefinitions = async () => { - const files = [path.resolve(projRoot, 'typings', 'global.d.ts')] - await run(`cp ${files.join(' ')} ${epOutput}`) +export const copyFullStyle = async () => { + await run(`mkdir -p ${epOutput}/dist/fonts`) + await Promise.all([ + run(`cp ${epOutput}/theme-chalk/index.css ${epOutput}/dist/index.css`), + run(`cp -R ${epOutput}/theme-chalk/fonts ${epOutput}/dist/fonts`), + ]) } export default series( withTaskName('clean', () => run('pnpm run clean')), parallel( - runTask('buildComponent'), - runTask('buildStyle'), + runTask('buildModules'), runTask('buildFullBundle'), + runTask('generateTypesDefinitions'), runTask('buildHelper'), - withTaskName('buildEachPackages', () => - run('pnpm run --filter ./packages --parallel --stream build') + series( + withTaskName('buildThemeChalk', () => + run('pnpm run -C packages/theme-chalk build') + ), + copyFullStyle ) ), - parallel( - copyStyle(), - copyFullStyle, - copyEntryTypes, - copySourceCode, - copyREADME, - copyDefinitions - ) + parallel(copyTypesDefinitions, copyFiles) ) -export * from './component' -export * from './style' +export * from './types-definitions' +export * from './modules' export * from './full-bundle' -export * from './entry-types' export * from './helper' diff --git a/build/modules.ts b/build/modules.ts new file mode 100644 index 0000000000..bb01bdd4b3 --- /dev/null +++ b/build/modules.ts @@ -0,0 +1,54 @@ +import { rollup } from 'rollup' +import vue from 'rollup-plugin-vue' +import css from 'rollup-plugin-css-only' +import { nodeResolve } from '@rollup/plugin-node-resolve' +import commonjs from '@rollup/plugin-commonjs' +import esbuild from 'rollup-plugin-esbuild' +import filesize from 'rollup-plugin-filesize' +import glob from 'fast-glob' +import { epRoot, pkgRoot } from './utils/paths' +import { RollupResolveEntryPlugin } from './plugins/rollup-plugin-entry' +import { generateExternal, writeBundles } from './utils/rollup' +import { excludeFiles } from './utils/pkg' +import { reporter } from './plugins/size-reporter' +import { buildConfigEntries } from './build-info' +import type { OutputOptions } from 'rollup' + +export const buildModules = async () => { + const input = excludeFiles( + await glob('**/*.{js,ts,vue}', { + cwd: pkgRoot, + absolute: true, + onlyFiles: true, + }) + ) + const bundle = await rollup({ + input, + plugins: [ + await RollupResolveEntryPlugin(), + css(), + vue({ target: 'browser' }), + nodeResolve(), + commonjs(), + esbuild({ + sourceMap: true, + }), + filesize({ reporter }), + ], + external: await generateExternal({ full: false }), + treeshake: false, + }) + await writeBundles( + bundle, + buildConfigEntries.map(([module, config]): OutputOptions => { + return { + format: config.format, + dir: config.output.path, + exports: module === 'cjs' ? 'named' : undefined, + preserveModules: true, + preserveModulesRoot: epRoot, + sourcemap: true, + } + }) + ) +} diff --git a/build/packages.ts b/build/packages.ts deleted file mode 100644 index 5725e0be9f..0000000000 --- a/build/packages.ts +++ /dev/null @@ -1,54 +0,0 @@ -import path from 'path' -import ts from 'gulp-typescript' -import { src, dest, series, parallel } from 'gulp' -import { withTaskName, gulpPathRewriter } from './utils/gulp' -import { buildConfig } from './info' -import { epOutput, projRoot } from './utils/paths' -import { getPackageManifest } from './utils/pkg' -import { EP_PREFIX } from './constants' -import type { BuildConfigEntries } from './info' - -export const buildPackage = (pkgPath: string) => { - const manifest = getPackageManifest(path.resolve(pkgPath, 'package.json')) - const pkgName = manifest.name!.replace(`${EP_PREFIX}/`, '') - - const tasks = (Object.entries(buildConfig) as BuildConfigEntries).map( - ([module, config]) => { - const output = path.resolve(pkgPath, 'dist', config.output.name) - - const build = () => { - const tsConfig = path.resolve(projRoot, 'tsconfig.json') - const inputs = [ - '**/*.ts', - '!node_modules', - '!gulpfile.ts', - '!__test?(s)__/*', - '!test?(s)/*', - path.resolve(projRoot, 'typings', '*.d.ts'), - ] - return withTaskName(`build:${pkgName}:${module}`, () => - src(inputs) - .pipe( - ts.createProject(tsConfig, { - module: config.module, - strict: false, - })() - ) - .pipe(gulpPathRewriter(module)) - .pipe(dest(output)) - ) - } - - const copy = () => - withTaskName(`copy:${pkgName}:${module}`, () => - src(`${output}/**`).pipe( - dest(path.resolve(epOutput, config.output.name, pkgName)) - ) - ) - - return series(build(), copy()) - } - ) - - return parallel(...tasks) -} diff --git a/build/plugins/rollup-plugin-entry.ts b/build/plugins/rollup-plugin-entry.ts new file mode 100644 index 0000000000..e6e6b79930 --- /dev/null +++ b/build/plugins/rollup-plugin-entry.ts @@ -0,0 +1,32 @@ +import path from 'path' +import { pkgRoot } from '../utils/paths' +import { EP_PKG, EP_PREFIX } from '../utils/constants' +import { getWorkspaceNames } from '../utils/pkg' +import type { Plugin } from 'rollup' + +export async function RollupResolveEntryPlugin(): Promise { + const pkgs = (await getWorkspaceNames(pkgRoot)) + .filter((pkg) => pkg.startsWith(`${EP_PREFIX}/`)) + .map((pkg) => pkg.replace(`${EP_PREFIX}/`, '')) + + return { + name: 'element-plus-entry-plugin', + + transform(code, id) { + if (id.includes('packages')) { + code = code.replaceAll( + `${EP_PREFIX}/theme-chalk`, + `${EP_PKG}/theme-chalk` + ) + code = code.replace( + new RegExp(`@element-plus\\/(${pkgs.join('|')})`, 'g'), + `${path.relative(path.dirname(id), path.resolve(pkgRoot))}/$1` + ) + return { + code, + map: null, + } + } + }, + } +} diff --git a/build/plugins/size-reporter.ts b/build/plugins/size-reporter.ts new file mode 100644 index 0000000000..3da6903d82 --- /dev/null +++ b/build/plugins/size-reporter.ts @@ -0,0 +1,9 @@ +import { cyan, bold, yellow, green } from 'chalk' + +import type { FileSizeReporter } from 'rollup-plugin-filesize' + +export const reporter: FileSizeReporter = (opt, outputOptions, info) => { + return `${cyan(bold(info.fileName))}: bundle size ${yellow( + info.bundleSize + )} -> minified ${green(info.minSize)}` +} diff --git a/build/rollup-plugin-entry.ts b/build/rollup-plugin-entry.ts deleted file mode 100644 index 5cfdf626a7..0000000000 --- a/build/rollup-plugin-entry.ts +++ /dev/null @@ -1,23 +0,0 @@ -import path from 'path' -import type { Plugin } from 'rollup' - -export function RollupResolveEntryPlugin(): Plugin { - return { - name: 'element-plus-entry-plugin', - transform(code, id) { - if (id.includes('packages')) { - return { - code: code.replace( - /@element-plus\/(components|directives|utils|hooks|tokens|locale)/g, - `${path.relative( - path.dirname(id), - path.resolve(__dirname, '../packages') - )}/$1` - ), - map: null, - } - } - return { code, map: null } - }, - } -} diff --git a/build/size-reporter.ts b/build/size-reporter.ts deleted file mode 100644 index b2d6f9babd..0000000000 --- a/build/size-reporter.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { cyan, bold, yellow, green } from 'chalk' - -import type { FileSizeReporter } from 'rollup-plugin-filesize' - -const reporter: FileSizeReporter = (opt, outputOptions, info) => { - const values = [ - info.fileName ? [`${outputOptions.file?.split('packages/').pop()}`] : [], - - [`${info.bundleSize}`], - ...(info.minSize ? [`${info.minSize}`] : []), - ] - - return `${cyan(bold(values[0]))}: bundle size ${yellow( - values[1] - )} -> minified ${green(values[2])}` -} - -export default reporter diff --git a/build/style.ts b/build/style.ts deleted file mode 100644 index 8c2c3daead..0000000000 --- a/build/style.ts +++ /dev/null @@ -1,44 +0,0 @@ -import path from 'path' -import { parallel, dest, src } from 'gulp' -import ts from 'gulp-typescript' -import { buildOutput, compRoot } from './utils/paths' -import { buildConfig } from './info' -import { withTaskName, gulpPathRewriter } from './utils/gulp' -import { run } from './utils/process' - -import type { Module } from './info' - -const inputs = path.resolve(compRoot, '**/style/*.ts') -const output = path.resolve(buildOutput, 'styles') - -const tsProject = (module: Module) => - ts.createProject('tsconfig.json', { - declaration: true, - target: 'ESNext', - skipLibCheck: true, - module: buildConfig[module].module, - })() - -const build = (module: Module) => - withTaskName(`buildStyle:${module}`, () => - src(inputs) - .pipe(gulpPathRewriter(module)) - .pipe(tsProject(module)) - .pipe(dest(path.resolve(output, buildConfig[module].output.name))) - ) - -export const buildStyle = parallel(build('esm'), build('cjs')) - -export const copyStyle = () => { - const copy = (module: Module) => { - const config = buildConfig[module] - const src = path.resolve(buildOutput, 'styles', config.output.name) - const dst = path.resolve(config.output.path, 'components') - - return withTaskName(`copyStyle:${module}`, () => - run(`rsync -a ${src}/ ${dst}/`) - ) - } - - return parallel(copy('esm'), copy('cjs')) -} diff --git a/build/component-types.ts b/build/types-definitions.ts similarity index 82% rename from build/component-types.ts rename to build/types-definitions.ts index e9853b4ef9..fb5b08ad04 100644 --- a/build/component-types.ts +++ b/build/types-definitions.ts @@ -6,9 +6,10 @@ import glob from 'fast-glob' import { bold } from 'chalk' import { green, red, yellow } from './utils/log' -import { buildOutput, compRoot, projRoot } from './utils/paths' +import { buildOutput, pkgRoot, projRoot } from './utils/paths' -import { pathRewriter } from './utils/pkg' +import { excludeFiles, pathRewriter } from './utils/pkg' +import { run } from './utils/process' import type { SourceFile } from 'ts-morph' const TSCONFIG_PATH = path.resolve(projRoot, 'tsconfig.json') @@ -17,7 +18,7 @@ const outDir = path.resolve(buildOutput, 'types') /** * fork = require( https://github.com/egoist/vue-dts-gen/blob/main/src/index.ts */ -export const genComponentTypes = async () => { +export const generateTypesDefinitions = async () => { const project = new Project({ compilerOptions: { allowJs: true, @@ -35,27 +36,12 @@ export const genComponentTypes = async () => { skipAddingFilesFromTsConfig: true, }) - const excludedFiles = [ - /\/demo\/\w+\.vue$/, - 'mock', - 'package.json', - 'spec', - 'test', - 'css', - '.DS_Store', - 'node_modules', - ] - const filePaths = ( - await glob('**/*', { - cwd: compRoot, - onlyFiles: true, + const filePaths = excludeFiles( + await glob('**/*.{js,ts,vue}', { + cwd: pkgRoot, absolute: true, + onlyFiles: true, }) - ).filter( - (path) => - !excludedFiles.some((f) => - f instanceof RegExp ? f.test(path) : path.includes(f) - ) ) const sourceFiles: SourceFile[] = [] @@ -93,7 +79,6 @@ export const genComponentTypes = async () => { ) const diagnostics = project.getPreEmitDiagnostics() - console.log(project.formatDiagnosticsWithColorAndContext(diagnostics)) await project.emit({ @@ -101,7 +86,7 @@ export const genComponentTypes = async () => { }) const tasks = sourceFiles.map(async (sourceFile) => { - const relativePath = path.relative(compRoot, sourceFile.getFilePath()) + const relativePath = path.relative(pkgRoot, sourceFile.getFilePath()) yellow(`Generating definition for file: ${bold(relativePath)}`) const emitOutput = sourceFile.getEmitOutput() @@ -119,14 +104,22 @@ export const genComponentTypes = async () => { await fs.writeFile( filepath, - pathRewriter('esm', true)(outputFile.getText()), + pathRewriter('esm')(outputFile.getText()), 'utf8' ) green(`Definition for file: ${bold(relativePath)} generated`) }) + await Promise.all(tasks) }) await Promise.all(tasks) + + const epFiles = await glob('**/*', { + cwd: path.resolve(outDir, 'element-plus'), + absolute: true, + }) + await run(`mv ${epFiles.join(' ')} ${outDir}`) + await run(`rmdir ${path.resolve(outDir, 'element-plus')}`) } diff --git a/build/constants.ts b/build/utils/constants.ts similarity index 52% rename from build/constants.ts rename to build/utils/constants.ts index 32cdbde1d5..730c8a84b4 100644 --- a/build/constants.ts +++ b/build/utils/constants.ts @@ -1 +1,2 @@ export const EP_PREFIX = '@element-plus' +export const EP_PKG = 'element-plus' diff --git a/build/utils/gulp.ts b/build/utils/gulp.ts index 6916b7fe63..300d8d080c 100644 --- a/build/utils/gulp.ts +++ b/build/utils/gulp.ts @@ -1,17 +1,4 @@ -import through2 from 'through2' -import { pathRewriter } from './pkg' import type { TaskFunction } from 'gulp' -import type { Module } from '../info' export const withTaskName = (name: string, fn: T) => Object.assign(fn, { displayName: name }) - -export const gulpPathRewriter = (module: Module) => { - const rewriter = pathRewriter(module, true) - - return through2.obj((file, _, cb) => { - const contents: string = file.contents.toString() - file.contents = Buffer.from(rewriter(contents)) - cb(null, file) - }) -} diff --git a/build/utils/log.ts b/build/utils/log.ts index 3cebc83756..c2635002fd 100644 --- a/build/utils/log.ts +++ b/build/utils/log.ts @@ -4,6 +4,7 @@ import chalk from 'chalk' export function cyan(str: string) { console.log(chalk.cyan(str)) } + export function yellow(str: string) { console.log(chalk.yellow(str)) } diff --git a/build/utils/pkg.ts b/build/utils/pkg.ts index 9045a2d80c..4b4c143f4f 100644 --- a/build/utils/pkg.ts +++ b/build/utils/pkg.ts @@ -1,24 +1,18 @@ import findWorkspacePackages from '@pnpm/find-workspace-packages' -import { buildConfig } from '../info' -import { EP_PREFIX } from '../constants' +import { buildConfig } from '../build-info' +import { EP_PREFIX } from './constants' import { projRoot } from './paths' -import type { Module } from '../info' +import type { Module } from '../build-info' import type { ProjectManifest } from '@pnpm/types' export const getWorkspacePackages = () => findWorkspacePackages(projRoot) -export const getWorkspaceNames = async () => { +export const getWorkspaceNames = async (dir = projRoot) => { const pkgs = await findWorkspacePackages(projRoot) return pkgs + .filter((pkg) => pkg.dir.startsWith(dir)) .map((pkg) => pkg.manifest.name) .filter((name): name is string => !!name) } -export const getWorkspacePackageManifest = async ( - name: string -): Promise => { - const packages = await getWorkspacePackages() - const { manifest } = packages.find((pkg) => pkg.manifest.name === name)! - return manifest -} export const getPackageManifest = (pkgPath: string) => { // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -31,13 +25,19 @@ export const getPackageDependencies = (pkgPath: string): string[] => { return Object.keys(dependencies ?? {}) } -export const pathRewriter = (module: Module, replaceAll: boolean) => { - const replaceName = replaceAll ? 'replaceAll' : 'replace' +export const pathRewriter = (module: Module) => { const config = buildConfig[module] return (id: string) => { - id = id[replaceName](`${EP_PREFIX}/theme-chalk`, 'element-plus/theme-chalk') - id = id[replaceName](`${EP_PREFIX}/`, `${config.bundle.path}/`) + id = id.replaceAll(`${EP_PREFIX}/theme-chalk`, 'element-plus/theme-chalk') + id = id.replaceAll(`${EP_PREFIX}/`, `${config.bundle.path}/`) return id } } + +export const excludeFiles = (files: string[]) => { + const excludes = ['node_modules', 'test', 'mock', 'gulpfile', 'dist'] + return files.filter( + (path) => !excludes.some((exclude) => path.includes(exclude)) + ) +} diff --git a/build/utils/process.ts b/build/utils/process.ts index 504b2db309..0fa50f313e 100644 --- a/build/utils/process.ts +++ b/build/utils/process.ts @@ -1,13 +1,11 @@ import { spawn } from 'child_process' -import { green } from './log' +import { green } from 'chalk' import { projRoot } from './paths' export const run = async (command: string, cwd: string = projRoot) => new Promise((resolve, reject) => { - const args = command.split(' ') - const cmd = args.shift()! - - green(`run: ${cmd} ${args.join(' ')}`) + const [cmd, ...args] = command.split(' ') + console.log(`run: ${green(`${cmd} ${args.join(' ')}`)}`) const app = spawn(cmd, args, { cwd, stdio: 'inherit', diff --git a/build/utils/rollup.ts b/build/utils/rollup.ts index e78c62421b..7983fa6cfe 100644 --- a/build/utils/rollup.ts +++ b/build/utils/rollup.ts @@ -1,26 +1,15 @@ -import { EP_PREFIX } from '../constants' import { epPackage } from './paths' -import { - getWorkspacePackages, - getPackageDependencies, - getWorkspaceNames, - pathRewriter, -} from './pkg' -import type { Module } from '../info' +import { getPackageDependencies } from './pkg' import type { OutputOptions, RollupBuild } from 'rollup' export const generateExternal = async (options: { full: boolean }) => { - const monoPackages = (await getWorkspacePackages()) - .map((pkg) => pkg.manifest.name) - // filter root package - .filter((name): name is string => !!name) - return (id: string) => { const packages: string[] = ['vue'] if (!options.full) { - const depPackages = getPackageDependencies(epPackage) - packages.push('@vue', ...monoPackages, ...depPackages) + packages.push('element-plus/theme-chalk') + // dependencies + packages.push('@vue', ...getPackageDependencies(epPackage)) } return [...new Set(packages)].some( @@ -32,21 +21,3 @@ export const generateExternal = async (options: { full: boolean }) => { export function writeBundles(bundle: RollupBuild, options: OutputOptions[]) { return Promise.all(options.map((option) => bundle.write(option))) } - -export const rollupPathRewriter = async () => { - const workspacePkgs = (await getWorkspaceNames()).filter((pkg) => - pkg.startsWith(EP_PREFIX) - ) - - return (module: Module) => { - const rewriter = pathRewriter(module, false) - - return (id: string) => { - if (workspacePkgs.some((pkg) => id.startsWith(pkg))) { - return rewriter(id) - } else { - return '' - } - } - } -} diff --git a/build/crowdin-credentials.ts b/docs/.vitepress/build/crowdin-credentials.ts similarity index 50% rename from build/crowdin-credentials.ts rename to docs/.vitepress/build/crowdin-credentials.ts index 3885dbbc24..a8eac436f0 100644 --- a/build/crowdin-credentials.ts +++ b/docs/.vitepress/build/crowdin-credentials.ts @@ -1,22 +1,26 @@ import path from 'path' -import fs from 'fs' +import fs from 'fs/promises' import chalk from 'chalk' -import { errorAndExit } from './utils/log' +import { errorAndExit } from '../../../build/utils/log' +import { docRoot } from '../utils/paths' const credentialPlaceholder = 'API_TOKEN_PLACEHOLDER' const CREDENTIAL = process.env.CROWDIN_TOKEN +if (!CREDENTIAL) { + errorAndExit(new Error('Environment variable CROWDIN_TOKEN cannot be empty')) +} ;(async () => { console.info(chalk.cyan('Fetching Crowdin credential')) - const configPath = path.resolve(__dirname, '../docs/crowdin.yml') + const configPath = path.resolve(docRoot, 'crowdin.yml') try { - const file = await fs.promises.readFile(configPath, { + const file = await fs.readFile(configPath, { encoding: 'utf-8', }) - await fs.promises.writeFile( + await fs.writeFile( configPath, - file.replace(credentialPlaceholder, CREDENTIAL!) + file.replace(credentialPlaceholder, CREDENTIAL) ) console.info(chalk.green('Crowdin credential update successfully')) } catch (e: any) { diff --git a/docs/.vitepress/build/crowdin-generate.ts b/docs/.vitepress/build/crowdin-generate.ts index 872f164157..de36a98c71 100644 --- a/docs/.vitepress/build/crowdin-generate.ts +++ b/docs/.vitepress/build/crowdin-generate.ts @@ -3,6 +3,7 @@ import path from 'path' import chalk from 'chalk' import { docRoot } from '../utils/paths' +import { errorAndExit } from '../../../build/utils/log' // NB: this file is only for generating files that enables developers to develop the website. const componentLocaleRoot = path.resolve(docRoot, '.vitepress/crowdin') @@ -101,11 +102,10 @@ main() .then(() => { console.log(chalk.green('Locale for website development generated')) }) - .catch((e) => { - if (e.message === exists) { + .catch((err) => { + if (err.message === exists) { // do nothing } else { - console.log(chalk.red(e.message)) - throw e + errorAndExit(err) } }) diff --git a/docs/package.json b/docs/package.json index 577fefde39..1f26d05738 100644 --- a/docs/package.json +++ b/docs/package.json @@ -5,7 +5,8 @@ "dev": "pnpm gen-locale && vitepress dev .", "build": "cross-env NODE_ENV=production && vitepress build .", "serve": "cross-env NODE_ENV=production && vitepress serve .", - "gen-locale": "rimraf .vitepress/i18n && sucrase-node .vitepress/build/crowdin-generate.ts" + "gen-locale": "rimraf .vitepress/i18n && sucrase-node .vitepress/build/crowdin-generate.ts", + "crowdin-credentials": "sucrase-node .vitepress/build/crowdin-credentials.ts" }, "dependencies": { "@vueuse/core": "^6.5.3", diff --git a/package.json b/package.json index 5f32949c9d..1ee38a99e1 100644 --- a/package.json +++ b/package.json @@ -14,19 +14,19 @@ "test": "jest", "dev": "pnpm -C play dev", "gen": "bash ./scripts/gc.sh", - "gen:version": "sucrase-node build/gen-version.ts", - "update:version": "sucrase-node build/update-version.ts", + "gen:version": "sucrase-node scripts/gen-version.ts", + "update:version": "sucrase-node scripts/update-version.ts", "clean": "pnpm run clean:lib && pnpm run clean -r --stream", "clean:lib": "rimraf dist", - "build": "gulp -f build/gulpfile.ts", + "build": "gulp --require sucrase/register/ts -f build/gulpfile.ts", "format": "prettier --write .", "lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --max-warnings 0 && pretty-quick --check --branch dev", "lint:fix": "eslint --fix . --ext .vue,.js,.ts,.jsx,.tsx && pretty-quick --branch dev", - "docs:dev": "pnpm -C docs dev", - "docs:build": "pnpm -C docs build", - "docs:serve": "pnpm -C docs serve", - "docs:gen-locale": "pnpm -C docs gen-locale", - "docs:crowdin": "sucrase-node build/crowdin-credentials.ts", + "docs:dev": "pnpm run -C docs dev", + "docs:build": "pnpm run -C docs build", + "docs:serve": "pnpm run -C docs serve", + "docs:gen-locale": "pnpm run -C docs gen-locale", + "docs:crowdin-credentials": "pnpm run -C docs crowdin-credentials", "prepare": "husky install", "postinstall": "pnpm gen:version" }, diff --git a/packages/components/image/src/image.ts b/packages/components/image/src/image.ts index 79cb8ea2ab..73d1b8aef6 100644 --- a/packages/components/image/src/image.ts +++ b/packages/components/image/src/image.ts @@ -1,4 +1,3 @@ -import { isBoolean } from '@vueuse/shared' import { buildProps, definePropType, mutable } from '@element-plus/utils/props' import type { ExtractPropTypes } from 'vue' @@ -41,7 +40,7 @@ export type ImageProps = ExtractPropTypes export const imageEmits = { error: (evt: Event) => evt instanceof Event, - switch: (val: boolean) => isBoolean(val), + switch: (val: boolean) => typeof val === 'boolean', close: () => true, } export type ImageEmits = typeof imageEmits diff --git a/packages/directives/gulpfile.ts b/packages/directives/gulpfile.ts deleted file mode 100644 index db84bd9736..0000000000 --- a/packages/directives/gulpfile.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { buildPackage } from '../../build/packages' - -export default buildPackage(__dirname) diff --git a/packages/directives/package.json b/packages/directives/package.json index 0a5774223f..cfd31ac124 100644 --- a/packages/directives/package.json +++ b/packages/directives/package.json @@ -10,9 +10,5 @@ "peerDependencies": { "vue": "^3.2.0" }, - "scripts": { - "clean": "rimraf dist", - "build": "gulp" - }, "gitHead": "c69724230befa8fede0e6b9c37fb0b7e39fd7cdd" } diff --git a/packages/element-plus/package.json b/packages/element-plus/package.json index f83330cda7..477c73d446 100644 --- a/packages/element-plus/package.json +++ b/packages/element-plus/package.json @@ -35,7 +35,8 @@ "vue": "^3.2.0" }, "dependencies": { - "@popperjs/core": "^2.10.2", + "@element-plus/icons": "^0.0.11", + "@popperjs/core": "^2.10.1", "@vueuse/core": "~6.1.0", "async-validator": "^4.0.3", "dayjs": "^1.10.7", diff --git a/packages/hooks/gulpfile.ts b/packages/hooks/gulpfile.ts deleted file mode 100644 index db84bd9736..0000000000 --- a/packages/hooks/gulpfile.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { buildPackage } from '../../build/packages' - -export default buildPackage(__dirname) diff --git a/packages/hooks/package.json b/packages/hooks/package.json index 179773240d..a413cc691d 100644 --- a/packages/hooks/package.json +++ b/packages/hooks/package.json @@ -11,9 +11,5 @@ "peerDependencies": { "vue": "^3.2.0" }, - "scripts": { - "clean": "rimraf dist", - "build": "gulp" - }, "gitHead": "c69724230befa8fede0e6b9c37fb0b7e39fd7cdd" } diff --git a/packages/hooks/use-form-item/index.ts b/packages/hooks/use-form-item/index.ts index b2fbcfd51d..6c80d9abd6 100644 --- a/packages/hooks/use-form-item/index.ts +++ b/packages/hooks/use-form-item/index.ts @@ -4,7 +4,7 @@ import { buildProps } from '@element-plus/utils/props' import { useGlobalConfig } from '@element-plus/utils/util' import type { ExtractPropTypes } from 'vue' -import type { MaybeRef } from '@vueuse/shared' +import type { MaybeRef } from '@vueuse/core' const sizes = ['', 'large', 'medium', 'small', 'mini'] as const diff --git a/packages/locale/gulpfile.ts b/packages/locale/gulpfile.ts deleted file mode 100644 index db84bd9736..0000000000 --- a/packages/locale/gulpfile.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { buildPackage } from '../../build/packages' - -export default buildPackage(__dirname) diff --git a/packages/locale/package.json b/packages/locale/package.json index 92976cabca..4f15cd7402 100644 --- a/packages/locale/package.json +++ b/packages/locale/package.json @@ -8,9 +8,5 @@ "jsdelivr": "index.js", "types": "index.d.ts", "license": "MIT", - "scripts": { - "clean": "rimraf dist", - "build": "gulp" - }, "gitHead": "c69724230befa8fede0e6b9c37fb0b7e39fd7cdd" } diff --git a/packages/theme-chalk/package.json b/packages/theme-chalk/package.json index 71b0859865..498eaaa69a 100644 --- a/packages/theme-chalk/package.json +++ b/packages/theme-chalk/package.json @@ -8,7 +8,7 @@ "style": "index.css", "scripts": { "clean": "rimraf dist", - "build": "gulp" + "build": "gulp --require sucrase/register/ts" }, "repository": { "type": "git", diff --git a/packages/tokens/gulpfile.ts b/packages/tokens/gulpfile.ts deleted file mode 100644 index db84bd9736..0000000000 --- a/packages/tokens/gulpfile.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { buildPackage } from '../../build/packages' - -export default buildPackage(__dirname) diff --git a/packages/tokens/package.json b/packages/tokens/package.json index 89a6d55aa3..4aabb3dda7 100644 --- a/packages/tokens/package.json +++ b/packages/tokens/package.json @@ -5,10 +5,6 @@ "peerDependencies": { "vue": "^3.2.0" }, - "scripts": { - "clean": "rimraf dist", - "build": "gulp" - }, "main": "index.ts", "module": "index.ts", "types": "index.d.js", diff --git a/packages/utils/gulpfile.ts b/packages/utils/gulpfile.ts deleted file mode 100644 index db84bd9736..0000000000 --- a/packages/utils/gulpfile.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { buildPackage } from '../../build/packages' - -export default buildPackage(__dirname) diff --git a/packages/utils/package.json b/packages/utils/package.json index 9eb65b5a31..46c527d182 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -5,9 +5,5 @@ "peerDependencies": { "vue": "^3.2.0" }, - "scripts": { - "clean": "rimraf dist", - "build": "gulp" - }, "gitHead": "c69724230befa8fede0e6b9c37fb0b7e39fd7cdd" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f4e20d0d01..e099436d0c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -188,7 +188,8 @@ importers: packages/element-plus: specifiers: - '@popperjs/core': ^2.10.2 + '@element-plus/icons': ^0.0.11 + '@popperjs/core': ^2.10.1 '@vueuse/core': ~6.1.0 async-validator: ^4.0.3 dayjs: ^1.10.7 @@ -197,6 +198,7 @@ importers: normalize-wheel-es: ^1.1.0 resize-observer-polyfill: ^1.5.1 dependencies: + '@element-plus/icons': 0.0.11 '@popperjs/core': 2.10.2 '@vueuse/core': 6.1.0_vue@3.2.20 async-validator: 4.0.3 diff --git a/scripts/.eslintrc.js b/scripts/.eslintrc.js new file mode 100644 index 0000000000..0c567a8612 --- /dev/null +++ b/scripts/.eslintrc.js @@ -0,0 +1,5 @@ +module.exports = { + rules: { + 'no-console': 'off', + }, +} diff --git a/build/gen-version.ts b/scripts/gen-version.ts similarity index 100% rename from build/gen-version.ts rename to scripts/gen-version.ts diff --git a/build/update-version.ts b/scripts/update-version.ts similarity index 85% rename from build/update-version.ts rename to scripts/update-version.ts index a302e76a10..b7117f9485 100644 --- a/build/update-version.ts +++ b/scripts/update-version.ts @@ -1,7 +1,7 @@ import fs from 'fs' -import { epPackage } from './utils/paths' -import { cyan, red, yellow, green } from './utils/log' -import { getPackageManifest } from './utils/pkg' +import { epPackage } from '../build/utils/paths' +import { cyan, red, yellow, green } from '../build/utils/log' +import { getPackageManifest } from '../build/utils/pkg' const tagVersion = process.env.TAG_VERSION const gitHead = process.env.GIT_HEAD