refactor: update package path and bundle folder (#3016)

This commit is contained in:
jeremywu 2021-08-24 13:36:48 +08:00 committed by GitHub
parent 21820acafc
commit b0f4fc5f23
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
925 changed files with 7289 additions and 7836 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
**/lib/*

View File

@ -31,15 +31,12 @@ jobs:
registry-url: https://registry.npmjs.com/
- name: Get version
run: echo "TAG_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
- name: build
run: yarn fast-build
env:
TAG_VERSION: ${{env.TAG_VERSION}}
- name: generate npm token
run: echo "GIT_HEAD=${GITHUB_SHA}" >> GITHUB_ENV
- name: build&publish
run: echo "//registry.npmjs.com/:_authToken=${{ secrets.NPM_PUBLISH_TOKEN }}" > ./.npmrc
- name: Publish npm
run: sh ./scripts/publish.sh
run: sh ./scripts/monorepo.sh
env:
NODE_AUTH_TOKEN: ${{secrets.NPM_PUBLISH_TOKEN}}
TAG_VERSION: ${{env.TAG_VERSION}}
GIT_HEAD: ${{env.GIT_HEAD}}
REGISTRY: https://registry.npmjs.com/

1
.gitignore vendored
View File

@ -14,3 +14,4 @@ lib
website/play/index.vue
packages/element-plus/version.ts
/es/
es

3
.markdownlint.json Normal file
View File

@ -0,0 +1,3 @@
{
"MD033": false
}

View File

@ -1,43 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const cp = require('child_process')
const { getPackagesSync } = require('@lerna/project')
const ora = require('ora')
const chalk = require('chalk')
const spinner = ora(`${chalk.blue('Building...')}`).start()
const pkgs = getPackagesSync()
.map(pkg => pkg.name)
.filter(name =>
name.includes('@element-plus') &&
!name.includes('transition') &&
!name.includes('utils'),
)
const STEP = 4
const START = 0
const buildChild = (start, end) => {
let s = start
let e = end
const c1 = cp.spawn('node', ['./build/build.component.js', s, e])
c1.stdout.on('data', function (data) {
spinner.info(`${chalk.blue(data)}`)
})
c1.stderr.on('data', function (data) {
spinner.warn(`${chalk.red(data)}`)
})
c1.on('close', function (code) {
s += STEP
e += STEP
if (s > pkgs.length) {
spinner.succeed(`${chalk.green('Build done. Exit code ' + code)}`)
return
}
buildChild(s, e)
})
}
/**
* @link https://github.com/ezolenko/rollup-plugin-typescript2/issues/177
*/
buildChild(START, STEP)

View File

@ -1,16 +1,28 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const helper = require('components-helper')
const { name, version } = require('../package.json')
const icon = require('../website/icon.json')
import helper from 'components-helper'
import path from 'path'
import { epRoot } from './paths'
const { name, version } = require(path.resolve(
epRoot,
'./package.json',
))
import icon from '../website/icon.json'
const icons = icon.map(item => 'el-icon-' + item).join('/')
const tagVer = process.env.TAG_VERSION
const _version = tagVer ? tagVer.startsWith('v') ? tagVer.slice(1) : tagVer : version
const _version = tagVer
? tagVer.startsWith('v')
? tagVer.slice(1)
: tagVer
: version
helper({
name,
version: _version,
entry: 'website/docs/en-US/!(custom-theme|datetime-picker|i18n|installation|message-box|message|migration-from-2.x|notification|quickstart|transition|typography).md',
outDir: 'lib',
entry:
'website/docs/en-US/!(custom-theme|datetime-picker|i18n|installation|message-box|message|migration-from-2.x|notification|quickstart|transition|typography).md',
outDir: 'dist/element-plus',
reComponentName,
reDocUrl,
reAttribute,
@ -18,22 +30,31 @@ helper({
propsName: 'Attribute',
propsOptions: 'Accepted Values',
eventsName: 'Event Name',
tableRegExp: '#+\\s+(.*\\s*Attributes|.*\\s*Events|.*\\s*Slots|.*\\s*Directives)\\s*\\n+(\\|?.+\\|.+)\\n\\|?\\s*:?-+:?\\s*\\|.+((\\n\\|?.+\\|.+)+)',
tableRegExp:
'#+\\s+(.*\\s*Attributes|.*\\s*Events|.*\\s*Slots|.*\\s*Directives)\\s*\\n+(\\|?.+\\|.+)\\n\\|?\\s*:?-+:?\\s*\\|.+((\\n\\|?.+\\|.+)+)',
})
function reComponentName(title) {
return 'el-' + title.replace(/\B([A-Z])/g, '-$1').replace(/[ ]+/g, '-').toLowerCase()
return (
'el-' +
title
.replace(/\B([A-Z])/g, '-$1')
.replace(/[ ]+/g, '-')
.toLowerCase()
)
}
function reDocUrl(fileName, header) {
const docs = 'https://element-plus.org/#/en-US/component/'
const _header = header ? header.replace(/[ ]+/g, '-').toLowerCase() : undefined
const _header = header
? header.replace(/[ ]+/g, '-').toLowerCase()
: undefined
return docs + fileName + (_header ? '#' + _header : '')
}
function reAttribute(value, key, item) {
const _value = value.match(/^\*\*(.*)\*\*$/)
const str = _value ? _value[1]: value
const str = _value ? _value[1] : value
if (key === 'Accepted Values' && /icon/i.test(item[0])) {
return icons
@ -41,7 +62,7 @@ function reAttribute(value, key, item) {
return 'default'
} else if (str === '' || /^(-|—)$/.test(str)) {
return undefined
} else if (key === 'Attribute' && /v-model:(.+)/.test(str)){
} else if (key === 'Attribute' && /v-model:(.+)/.test(str)) {
const _str = str.match(/v-model:(.+)/)
return _str ? _str[1] : undefined
} else if (key === 'Attribute' && /v-model/.test(str)) {

View File

@ -1,70 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
'use strict'
const fs = require('fs')
const algoliasearch = require('algoliasearch')
const slugify = require('transliteration').slugify
const algoliaKey = process.env.ALGOLIA_KEY
const client = algoliasearch('7DCTSU0WBW', algoliaKey)
const langs = {
'zh-CN': 'element-zh',
'en-US': 'element-en',
'es': 'element-es',
'fr-FR': 'element-fr',
'jp': 'element-jp',
}
const fg = require('fast-glob')
;['zh-CN', 'en-US', 'es', 'fr-FR', 'jp'].forEach(lang => {
const indexName = langs[lang]
const index = client.initIndex(indexName)
index.clearObjects().then(() => {
const files = fg.sync(`website/docs/${lang}/*.md`)
let indices = []
files.forEach(file => {
const regExp = new RegExp(`website\/docs\/${lang}\/(.*).md`)
const pathContent = file.match(regExp)
const path = pathContent[1]
const index = path.lastIndexOf('/')
const names = index !== -1 ? path.split('/') : []
const component = names.length ? names[names.length - 1] : path
const content = fs.readFileSync(file, 'utf8')
const matches = content
.replace(/:::[\s\S]*?:::/g, '')
.replace(/```[\s\S]*?```/g, '')
.match(/#{2,4}[^#]*/g)
.map(match =>
match
.replace(/\n+/g, '\n')
.split('\n')
.filter(part => !!part),
)
.map(match => {
const length = match.length
if (length > 2) {
const desc = match.slice(1, length).join('')
return [match[0], desc]
}
return match
})
let i = 0
indices = indices.concat(
matches.map(match => {
const title = match[0].replace(/#{2,4}/, '').trim()
const index = { component, title }
index.anchor = slugify(title)
index.content = (match[1] || title).replace(/<[^>]+>/g, '')
index.path = path
index.sort = i++
return index
}),
)
})
index.saveObjects(indices, {
autoGenerateObjectIDIfNotExist: true,
})
})
})

View File

@ -1,39 +0,0 @@
/* eslint-disable */
const fs = require('fs')
const save = require('file-save')
const { resolve, basename } = require('path')
const localePath = resolve(__dirname, '../packages/locale/lang')
const fileList = fs.readdirSync(localePath)
const transform = function(filename, name, cb) {
require('@babel/core').transformFile(resolve(localePath, filename), {
plugins: [
'@babel/plugin-transform-modules-umd',
],
moduleId: name,
}, cb)
}
fileList
.filter(function(file) {
return /\.ts$/.test(file)
})
.forEach(function(file) {
const name = basename(file, '.ts')
transform(file, name, function(err, result) {
if (err) {
console.error(err)
} else {
const code = result.code
const transformedCode = code
.replace('define(\"', 'define(\"element/locale/')
.replace(
/global\.(\S*) = mod.exports/,
'global.ElementPlus.lang = global.ElementPlus.lang || {};\n global.ElementPlus.lang.$1 = mod.exports.default'
)
save(resolve(__dirname, '../lib/umd/locale', `${name}.js`)).write(transformedCode)
}
})
})

View File

@ -1,50 +0,0 @@
/* eslint-disable */
const pkg = require('../package.json')
const path = require('path')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const rollup = require('rollup')
const typescript = require('rollup-plugin-typescript2')
const root = path.resolve(__dirname, '..');
const file = process.argv[2];
const defaultOpts = {
input: path.resolve(root, file),
plugins: [
nodeResolve(),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: false,
},
'exclude': [
'node_modules',
'__tests__',
],
},
abortOnError: false,
}),
],
external() {
return true
},
}
const run = async (name) => {
const esm = {
format: 'es',
file: `es/${name}`,
};
const cjs = {
format: 'cjs',
file: `lib/${name}`,
exports: 'named',
}
const bundle = await rollup.rollup(defaultOpts);
await Promise.all([bundle.write(esm), bundle.write(cjs)]);
console.log(name, 'build finished');
}
let normalizedName = file.slice(11); // remove ./packages
run(`${normalizedName.split('.').shift()}.js`);

View File

@ -1,84 +0,0 @@
/* eslint-disable */
const pkg = require('../package.json')
const path = require('path')
const { getPackages } = require('@lerna/project')
const css = require('rollup-plugin-css-only')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const vue = require('rollup-plugin-vue')
const rollup = require('rollup')
const typescript = require('rollup-plugin-typescript2')
const { noElPrefixFile } = require('./common')
const deps = Object.keys(pkg.dependencies)
const runBuild = async () => {
let index = 0
const pkgs = await getPackages()
const inputs = pkgs
.map(pkg => pkg.name)
.filter(name =>
name.includes('@element-plus') &&
!name.includes('utils'),
).slice(process.argv[2], process.argv[3])
build(inputs[index])
async function build(name) {
if (!name) return
const inputOptions = {
input: path.resolve(__dirname, `../packages/${name.split('@element-plus/')[1]}/index.ts`),
plugins: [
nodeResolve(),
css(),
vue({
target: 'browser',
css: false,
}),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: false,
},
'exclude': [
'node_modules',
'__tests__',
],
},
abortOnError: false,
}),
],
external(id) {
return /^vue/.test(id)
|| /^@element-plus/.test(id)
|| deps.some(k => new RegExp('^' + k).test(id))
},
}
const getOutFile = () => {
const compName = name.split('@element-plus/')[1]
if (noElPrefixFile.test(name)) {
return `lib/${compName}/index.js`
}
return `lib/el-${compName}/index.js`
}
const outOptions = {
format: 'es',
file: getOutFile(),
paths(id) {
if (/^@element-plus/.test(id)) {
if (noElPrefixFile.test(id)) return id.replace('@element-plus', '..')
return id.replace('@element-plus/', '../el-')
}
},
}
const bundle = await rollup.rollup(inputOptions)
console.log(name, 'done')
await bundle.write(outOptions)
index++
if (index < inputs.length) {
await build(inputs[index])
}
}
}
runBuild()

View File

@ -1,16 +0,0 @@
/* eslint-disable */
// name came from the terminal as `./packages/*` notation, so when resolve the name, we'd like
// to add a `..` to do so. because the current file is under `build/`, `packages/` is at the
// same level as `build/`,
const run = require('./build');
const compPath = process.argv[2]
if (!compPath) {
console.error('Usage: node build.js [component]')
process.exit(1)
}
const outPutPrefix = ['hooks', 'directives'].some((p) => compPath.includes(p)) ? '' : 'el-';
const compName = compPath.split('/').pop()
run(`${outPutPrefix}${compName}/index.js`, compPath)

View File

@ -1,5 +0,0 @@
/* eslint-disable */
const run = require('./build');
run('index.js', './packages/element-plus', true)

View File

@ -1,81 +0,0 @@
/* eslint-disable */
const pkg = require('../package.json')
const path = require('path')
const css = require('rollup-plugin-css-only')
const { nodeResolve } = require('@rollup/plugin-node-resolve')
const vue = require('rollup-plugin-vue')
const rollup = require('rollup')
const typescript = require('rollup-plugin-typescript2')
const { noElPrefixFile } = require('./common');
const deps = Object.keys(pkg.dependencies)
const root = path.resolve(__dirname, '..');
const defaultOpts = {
plugins: [
nodeResolve(),
css(),
vue({
target: 'browser',
css: false,
}),
typescript({
tsconfigOverride: {
compilerOptions: {
declaration: false,
},
'exclude': [
'node_modules',
'__tests__',
],
},
abortOnError: false,
}),
],
external(id) {
return /^vue/.test(id)
|| /^@element-plus/.test(id)
|| deps.some(k => new RegExp('^' + k).test(id))
},
}
const isPkg = (id) => {
return id.startsWith('@element-plus')
}
const isExcluded = (id) => {
return noElPrefixFile.test(id)
}
const replacePrefix = (prefix, target) => {
return prefix + target.slice(14) // @element-plus/.length = 14
}
const run = async (name, input, isRoot = false) => {
const inputPath = `${path.resolve(root, input)}/index.ts`
defaultOpts.input = inputPath
const getPaths = (id) => {
if (isPkg(id)) {
if (isExcluded(id)) return replacePrefix(isRoot ? './' : '../', id)
return replacePrefix(isRoot ? './el-' : '../el-', id)
}
}
const esm = {
format: 'es',
file: `es/${name}`,
paths: getPaths,
};
const cjs = {
format: 'cjs',
file: `lib/${name}`,
paths: getPaths,
exports: 'named',
};
const bundle = await rollup.rollup(defaultOpts);
await Promise.all([bundle.write(esm), bundle.write(cjs)])
console.log(name, 'build finished');
}
module.exports = run;

View File

@ -1,3 +0,0 @@
module.exports = {
noElPrefixFile: /(utils|directives|hooks|locale)/,
}

177
build/components.ts Normal file
View File

@ -0,0 +1,177 @@
/* eslint-disable */
import fs from 'fs'
import path from 'path'
import rollup from 'rollup'
import vue from 'rollup-plugin-vue'
import css from 'rollup-plugin-css-only'
import filesize from 'rollup-plugin-filesize'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import esbuild from 'rollup-plugin-esbuild'
import chalk from 'chalk'
import { compRoot, buildOutput } from './paths'
import getDeps from './get-deps'
import genDefs from './gen-dts'
import reporter from './size-reporter'
const outputDir = path.resolve(buildOutput, './element-plus')
const pathToPkgJson = path.resolve(compRoot, './package.json')
async function getComponents() {
const raw = await fs.promises.readdir(compRoot)
// filter out package.json since under packages/components we only got this file
//
return raw
.filter(f => f !== 'package.json' && f !== 'index.ts')
.map(f => ({ path: path.resolve(compRoot, f), name: f }))
}
const plugins = [
css(),
vue({
target: 'browser',
// css: false,
}),
nodeResolve(),
esbuild(),
]
const EP_PREFIX = '@element-plus'
const VUE_REGEX = 'vue'
const VUE_MONO = '@vue'
const externals = getDeps(pathToPkgJson)
const excludes = ['icons']
const pathsRewriter = id => {
if (id.startsWith(`${EP_PREFIX}/components`)) return id.replace(`${EP_PREFIX}/components`, '..')
if (id.startsWith(EP_PREFIX) && excludes.every(e => !id.endsWith(e))) return id.replace(EP_PREFIX, '../..')
return id
}
; (async () => {
// run type diagnoses first
yellow('Start building types for individual components')
await genDefs(compRoot)
green('Typing generated successfully')
yellow('Start building individual components')
await buildComponents()
green('Components built successfully')
yellow('Start building entry file')
await buildEntry()
green('Entry built successfully')
})().then(() => {
console.log('Individual component build finished')
process.exit(0)
}).catch((e) => {
console.error(e.message)
process.exit(1)
})
async function buildComponents() {
const componentPaths = await getComponents()
const builds = componentPaths.map(async ({
path: p,
name: componentName,
}) => {
const entry = path.resolve(p, './index.ts')
if (!fs.existsSync(entry)) return
const external = (id) => {
return id.startsWith(VUE_REGEX)
|| id.startsWith(VUE_MONO)
|| id.startsWith(EP_PREFIX)
|| externals.some(i => id.startsWith(i))
}
const esm = {
format: 'es',
file: `${outputDir}/es/components/${componentName}/index.js`,
plugins: [
filesize({
reporter,
})
],
paths: pathsRewriter,
}
const cjs = {
format: 'es',
file: `${outputDir}/lib/components/${componentName}/index.js`,
plugins: [
filesize({
reporter,
})
],
paths: pathsRewriter,
}
const rollupConfig = {
input: entry,
plugins,
external,
}
const bundle = await rollup.rollup(rollupConfig)
await bundle.write(esm as any)
await bundle.write(cjs as any)
})
try {
await Promise.all(
builds
)
} catch (e) {
logAndShutdown(e)
}
}
async function buildEntry() {
const entry = path.resolve(compRoot, 'index.ts')
const config = {
input: entry,
plugins,
external: _ => true,
}
try {
const bundle = await rollup.rollup(config)
await bundle.write({
format: 'es',
file: `${outputDir}/es/components/index.js`,
plugins: [
filesize({
reporter,
})
]
})
await bundle.write({
format: 'cjs',
file: `${outputDir}/lib/components/index.js`,
plugins: [
filesize({
reporter,
})
],
})
} catch (e) {
logAndShutdown(e)
}
}
function yellow(str) {
console.log(chalk.cyan(str))
}
function green(str) {
console.log(chalk.green(str))
}
function red(str) {
console.error(chalk.red(str))
}
function logAndShutdown(e) {
red(e.message)
process.exit(1)
}

2
build/constants.ts Normal file
View File

@ -0,0 +1,2 @@
export const EP_PREFIX = '@element-plus'
export const excludes = ['icons']

120
build/full-bundle.ts Normal file
View File

@ -0,0 +1,120 @@
import { nodeResolve } from '@rollup/plugin-node-resolve'
import rollup from 'rollup'
import chalk from 'chalk'
import path from 'path'
import fs from 'fs'
import commonjs from '@rollup/plugin-commonjs'
import vue from 'rollup-plugin-vue'
import esbuild from 'rollup-plugin-esbuild'
import genDts from './gen-entry-dts'
import RollupResolveEntryPlugin from './rollup.plugin.entry'
import { epRoot, buildOutput } from './paths'
import { EP_PREFIX, excludes } from './constants'
;(async () => {
const config = {
input: path.resolve(epRoot, './index.ts'),
plugins: [
nodeResolve(),
vue({
target: 'browser',
// css: false,
exposeFilename: false,
}),
commonjs(),
esbuild({
minify: false,
}),
],
external(id) {
return /^vue/.test(id)
},
}
console.log(chalk.cyan('Start generating full bundle'))
const umd = {
format: 'umd',
file: path.resolve(buildOutput, 'element-plus/dist/index.js'),
exports: 'named',
name: 'ElementPlus',
}
const umdMinified = {
...umd,
file: path.resolve(buildOutput, 'element-plus/dist/index.full.js'),
}
console.log(chalk.bold(chalk.yellow('Building bundle')))
// Full bundle generation
const bundle = await rollup.rollup({
...config,
plugins: [...config.plugins, RollupResolveEntryPlugin()],
})
console.log(chalk.yellow('Generating index.js'))
await bundle.write(umd as any)
console.log(chalk.green('index.js generated'))
console.log(chalk.yellow('Generating index.full.js'))
await bundle.write(umdMinified as any)
console.log(chalk.green('index.full.js generated'))
console.log(chalk.yellow('Generating entry files without dependencies'))
// Entry bundle generation
const entryFiles = await fs.promises.readdir(epRoot, { withFileTypes: true })
const entryPoints = entryFiles.filter(f => f.isFile()).filter(f => {
return f.name !== 'package.json' && f.name !== 'README.md'
}).map(f => path.resolve(epRoot, f.name))
const entryBundle = await rollup.rollup({
...config,
input: entryPoints,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
external: _ => true,
})
const rewriter = id => {
if (id.startsWith(`${EP_PREFIX}/components`)) return id.replace(`${EP_PREFIX}/components`, './components')
if (id.startsWith(EP_PREFIX) && excludes.every(e => !id.endsWith(e))) return id.replace(EP_PREFIX, '.')
}
console.log(chalk.yellow('Generating cjs entry'))
await entryBundle.write({
format: 'cjs',
dir: path.resolve(buildOutput, 'element-plus/lib'),
exports: 'named',
paths: rewriter,
})
console.log(chalk.green('cjs entry generated'))
console.log(chalk.yellow('Generating esm entry'))
await entryBundle.write({
format: 'esm',
dir: path.resolve(buildOutput, 'element-plus/es'),
paths: rewriter,
})
console.log(chalk.green('esm entry generated'))
console.log(chalk.bold(chalk.green('Full bundle generated')))
console.log(chalk.yellow('Generate entry file definitions'))
await genDts()
console.log(chalk.green('Entry file definitions generated'))
})()

View File

@ -1,165 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path')
const fs = require('fs')
const { Project } = require('ts-morph')
const vueCompiler = require('@vue/compiler-sfc')
const klawSync = require('klaw-sync')
const ora = require('ora')
const TSCONFIG_PATH = path.resolve(__dirname, '../tsconfig.json')
const DEMO_RE = /\/demo\/\w+\.vue$/
const TEST_RE = /__test__|__tests__/
const excludedFiles = [
'mock',
'package.json',
'spec',
'test',
'tests',
'css',
'.DS_Store',
]
const exclude = path => !excludedFiles.some(f => path.includes(f))
/**
* fork = require( https://github.com/egoist/vue-dts-gen/blob/main/src/index.ts
*/
const genVueTypes = async () => {
const project = new Project({
compilerOptions: {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
noEmitOnError: false,
outDir: path.resolve(__dirname, '../dist'),
baseUrl: path.resolve(__dirname, '../'),
paths: {
'@element-plus/*': ['packages/*'],
},
},
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})
const sourceFiles = []
const filePaths = klawSync(path.resolve(__dirname, '../packages'), {
nodir: true,
})
.map(item => item.path)
.filter(path => !DEMO_RE.test(path))
.filter(path => !TEST_RE.test(path))
.filter(exclude)
await Promise.all(
filePaths.map(async file => {
if (file.endsWith('.vue')) {
const content = await fs.promises.readFile(file, 'utf-8')
const sfc = vueCompiler.parse(content)
const { script, scriptSetup } = sfc.descriptor
if (script || scriptSetup) {
let content = ''
let isTS = false
if (script && script.content) {
content += script.content
if (script.lang === 'ts') isTS = true
}
if (scriptSetup) {
const compiled = vueCompiler.compileScript(sfc.descriptor, {
id: 'xxx',
})
content += compiled.content
if (scriptSetup.lang === 'ts') isTS = true
}
const sourceFile = project.createSourceFile(
path.relative(process.cwd(), file) + (isTS ? '.ts' : '.js'),
content,
)
sourceFiles.push(sourceFile)
}
} else if (file.endsWith('.ts')) {
const sourceFile = project.addSourceFileAtPath(file)
sourceFiles.push(sourceFile)
}
}),
)
// const diagnostics = project.getPreEmitDiagnostics()
// TODO: print all diagnoses status and fix them one by one.
// console.log(project.formatDiagnosticsWithColorAndContext(diagnostics))
await project.emit({
emitOnlyDtsFiles: true,
})
const ROOT_PATH = path.resolve(__dirname, '../packages')
const excludes = ['utils', 'directives', 'hooks', 'locale']
const ElementPlusSign = '@element-plus/'
for (const sourceFile of sourceFiles) {
const sourceFilePathName = sourceFile.getFilePath()
if (sourceFilePathName.includes('packages/element-plus')) {
sourceFile.getExportDeclarations().map(modifySpecifier)
}
sourceFile.getImportDeclarations().map(modifySpecifier)
function modifySpecifier(d) {
const specifier = d.getModuleSpecifierValue()
if (specifier && specifier.includes(ElementPlusSign)) {
const importItem = specifier.slice(ElementPlusSign.length)
let replacer
if (excludes.some(e => importItem.startsWith(e))) {
replacer = ''
} else {
replacer = 'el-'
}
const originalPath = path.resolve(
ROOT_PATH,
`./${replacer}${importItem}`,
)
const sourceFilePath = sourceFile.getFilePath()
const sourceDir = sourceFilePath.includes('packages/element-plus')
? path.dirname(path.resolve(sourceFilePath, '../'))
: path.dirname(sourceFilePath)
const replaceTo = path.relative(sourceDir, originalPath)
// This is a delicated judgment which might fail when edge case occurs
d.setModuleSpecifier(
replaceTo.startsWith('.') ? replaceTo : `./${replaceTo}`,
)
}
}
// console.log(sourceFile.getFilePath())
const emitOutput = sourceFile.getEmitOutput()
for (const outputFile of emitOutput.getOutputFiles()) {
const filepath = outputFile.getFilePath()
await fs.promises.mkdir(path.dirname(filepath), {
recursive: true,
})
await fs.promises.writeFile(filepath, outputFile.getText(), 'utf8')
}
}
}
// const cwd = process.cwd()
// function getRelativePath(_path) {
// console.log(_path)
// const relativePath = path.relative(
// cwd,
// path.resolve(__dirname, '../packages'),
// )
// // console.log(path.relative(_path, relativePath))
// return path.relative(_path, relativePath)
// }
const spinner = ora('Generate types...\n').start()
genVueTypes()
.then(() => spinner.succeed('Success !\n'))
.catch(e => spinner.fail(`${e} !\n`))

132
build/gen-dts.ts Normal file
View File

@ -0,0 +1,132 @@
import path from 'path'
import fs from 'fs'
import { Project } from 'ts-morph'
import vueCompiler from '@vue/compiler-sfc'
import klawSync from 'klaw-sync'
import chalk from 'chalk'
const TSCONFIG_PATH = path.resolve(__dirname, '../tsconfig.json')
const DEMO_RE = /\/demo\/\w+\.vue$/
const TEST_RE = /__test__|__tests__/
const excludedFiles = [
'mock',
'package.json',
'spec',
'test',
'tests',
'css',
'.DS_Store',
]
const exclude = (path: string) => !excludedFiles.some(f => path.includes(f))
/**
* fork = require( https://github.com/egoist/vue-dts-gen/blob/main/src/index.ts
*/
const genVueTypes = async (root, outDir = path.resolve(__dirname, '../dist/types')) => {
const project = new Project({
compilerOptions: {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
noEmitOnError: true,
outDir,
baseUrl: path.resolve(__dirname, '../'),
paths: {
'@element-plus/*': ['packages/*'],
},
skipLibCheck: true,
},
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})
const sourceFiles = []
const filePaths = klawSync(root, {
nodir: true,
})
.map(item => item.path)
.filter(path => !DEMO_RE.test(path))
.filter(path => !TEST_RE.test(path))
.filter(exclude)
await Promise.all(
filePaths.map(async file => {
if (file.endsWith('.vue')) {
const content = await fs.promises.readFile(file, 'utf-8')
const sfc = vueCompiler.parse(content)
const { script, scriptSetup } = sfc.descriptor
if (script || scriptSetup) {
let content = ''
let isTS = false
if (script && script.content) {
content += script.content
if (script.lang === 'ts') isTS = true
}
if (scriptSetup) {
const compiled = vueCompiler.compileScript(sfc.descriptor, {
id: 'xxx',
})
content += compiled.content
if (scriptSetup.lang === 'ts') isTS = true
}
const sourceFile = project.createSourceFile(
path.relative(process.cwd(), file) + (isTS ? '.ts' : '.js'),
content,
)
sourceFiles.push(sourceFile)
}
} else if (file.endsWith('.ts')) {
const sourceFile = project.addSourceFileAtPath(file)
sourceFiles.push(sourceFile)
}
}),
)
const diagnostics = project.getPreEmitDiagnostics()
console.log(project.formatDiagnosticsWithColorAndContext(diagnostics))
await project.emit({
emitOnlyDtsFiles: true,
})
for (const sourceFile of sourceFiles) {
console.log(
chalk.yellow(
'Generating definition for file: ' +
chalk.bold(
sourceFile.getBaseName(),
),
),
)
const emitOutput = sourceFile.getEmitOutput()
for (const outputFile of emitOutput.getOutputFiles()) {
const filepath = outputFile.getFilePath()
await fs.promises.mkdir(path.dirname(filepath), {
recursive: true,
})
await fs.promises.writeFile(filepath,
outputFile
.getText()
.replaceAll('@element-plus/components', 'element-plus/es')
.replaceAll('@element-plus/theme-chalk', 'element-plus/theme-chalk')
.replaceAll('@element-plus', 'element-plus/es'),
'utf8')
console.log(
chalk.green(
'Definition for file: ' +
chalk.bold(
sourceFile.getBaseName(),
) +
' generated',
),
)
}
}
}
export default genVueTypes

67
build/gen-entry-dts.ts Normal file
View File

@ -0,0 +1,67 @@
import path from 'path'
import fs from 'fs'
import chalk from 'chalk'
import glob from 'fast-glob'
import { Project } from 'ts-morph'
import { epRoot, buildOutput } from './paths'
const TSCONFIG_PATH = path.resolve(__dirname, '../tsconfig.dts.json')
const gen = async () => {
const files = await glob(epRoot + '/*.ts')
const project = new Project({
compilerOptions: {
allowJs: true,
declaration: true,
emitDeclarationOnly: true,
noEmitOnError: false,
outDir: path.resolve(buildOutput, 'entry/types'),
skipLibCheck: true,
esModuleInterop: true,
target: 99, // ESNext
downlevelIteration: true,
// types: ["./typings", "esnext", "dom"],
},
skipFileDependencyResolution: true,
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})
const sourceFiles = []
files.map(f => {
const sourceFile = project.addSourceFileAtPath(f)
sourceFiles.push(sourceFile)
})
for (const sourceFile of sourceFiles) {
console.log(chalk.yellow(
`Emitting file: ${chalk.bold(sourceFile.getFilePath())}`,
))
await sourceFile.emit()
const emitOutput = sourceFile.getEmitOutput()
for (const outputFile of emitOutput.getOutputFiles()) {
const filepath = outputFile.getFilePath()
await fs.promises.mkdir(path.dirname(filepath), {
recursive: true,
})
await fs.promises.writeFile(filepath,
outputFile
.getText()
.replaceAll('@element-plus', '.'),
// .replaceAll('@element-plus/theme-chalk', 'element-plus/theme-chalk'),
'utf8')
console.log(
chalk.green(
'Definition for file: ' +
chalk.bold(
sourceFile.getBaseName(),
) +
' generated',
),
)
}
}
}
export default gen

View File

@ -1,68 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
const { noElPrefixFile } = require('./common')
const outsideImport = /import .* from '..\/(.*?)\/src\/.*/
// global.d.ts
fs.copyFileSync(
path.resolve(__dirname, '../typings/vue-shim.d.ts'),
path.resolve(__dirname, '../lib/element-plus.d.ts'),
)
// index.d.ts
const newIndexPath = path.resolve(__dirname, '../lib/index.d.ts')
fs.copyFileSync(path.resolve(__dirname, '../lib/element-plus/index.d.ts'), newIndexPath)
const index = fs.readFileSync(newIndexPath)
const newIndex = index.toString().replace(/@element-plus\//g, './el-').replace('el-utils', 'utils').replace('el-locale', 'locale')
fs.writeFileSync(newIndexPath, newIndex)
// remove ep
fs.rmdirSync(path.resolve(__dirname, '../lib/element-plus'), { recursive: true })
// remove test-utils
fs.rmdirSync(path.resolve(__dirname, '../lib/test-utils'), { recursive: true })
// component
const libDirPath = path.resolve(__dirname, '../lib')
fs.readdirSync(libDirPath).forEach(comp => {
if (!noElPrefixFile.test(comp)) {
if (fs.lstatSync(path.resolve(libDirPath, comp)).isDirectory()) {
// rename
const newCompName = `el-${comp}`
fs.renameSync(path.resolve(libDirPath, comp),
path.resolve(libDirPath, newCompName))
// re-import
const imp = fs.readFileSync(path.resolve(__dirname, '../lib', newCompName, 'index.d.ts')).toString()
if (outsideImport.test(imp) || imp.includes('@element-plus/')) {
const newImp = imp.replace(outsideImport, (i, c) => {
return i.replace(`../${c}`, `../el-${c}`)
}).replace(/@element-plus\//g, '../el-').replace('el-utils', 'utils').replace('el-locale', 'locale')
fs.writeFileSync(path.resolve(__dirname, '../lib', newCompName, 'index.d.ts'), newImp)
}
}
}
})
// after components dir renamed
fs.readdirSync(libDirPath).forEach(comp => {
// check src/*.d.ts exist
const srcPath = path.resolve(libDirPath, comp, './src')
if (fs.existsSync(srcPath)) {
if (fs.lstatSync(srcPath).isDirectory()) {
fs.readdir(srcPath, 'utf-8', (err, data) => {
if (err) return
// replace all @element-plus in src/*.d.ts
data.forEach(f => {
if (!fs.lstatSync(path.resolve(srcPath, f)).isDirectory()) {
const imp = fs.readFileSync(path.resolve(srcPath, f)).toString()
if (imp.includes('@element-plus/')) {
const newImp = imp.replace(/@element-plus\//g, '../../el-').replace('el-utils', 'utils').replace('el-locale', 'locale')
fs.writeFileSync(path.resolve(srcPath, f), newImp)
}
}
})
})
}
}
})

View File

@ -1,12 +1,15 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
import fs from 'fs'
import path from 'path'
import pkg from '../packages/element-plus/package.json' // need to be checked
const tagVer = process.env.TAG_VERSION
let version = ''
if (tagVer) {
version = tagVer.startsWith('v') ? tagVer.slice(1) : tagVer
} else {
version = require('../package.json').version
version = pkg.version
}
fs.writeFileSync(
path.resolve(__dirname, '../packages/element-plus/version.ts'),
`export const version = '${version}'

12
build/get-deps.ts Normal file
View File

@ -0,0 +1,12 @@
/* eslint-disable */
/**
*
* @param {PathLike} path path to dependencies
* @returns {Array<string>}
*/
export default path => {
const pkgJson = require(path)
const { dependencies } = pkgJson
return Object.keys(dependencies)
}

View File

@ -1,4 +0,0 @@
/* eslint-disable */
const os = require('os')
console.log(os.cpus().length)

4
build/getCpus.ts Normal file
View File

@ -0,0 +1,4 @@
/* eslint-disable */
import os from 'os'
export default os.cpus().length

View File

@ -1,4 +0,0 @@
/* eslint-disable */
const { getPackagesSync } = require('@lerna/project');
module.exports = getPackagesSync();

4
build/getPkgs.ts Normal file
View File

@ -0,0 +1,4 @@
/* eslint-disable */
import { getPackagesSync } from '@lerna/project';
export default getPackagesSync();

16
build/gulp-rewriter.ts Normal file
View File

@ -0,0 +1,16 @@
import through2 from 'through2'
const rewriter = (rewriteTo = '../..') => {
return through2.obj(function(file, _, cb) {
const compIdentifier = '@element-plus'
file.contents = Buffer.from(
file.contents
.toString()
.replaceAll(compIdentifier, rewriteTo),
)
cb(null, file)
})
}
export default rewriter

58
build/gulpfile.ts Normal file
View File

@ -0,0 +1,58 @@
import gulp from 'gulp'
import ts from 'gulp-typescript'
import path from 'path'
import through2 from 'through2'
const output = path.resolve(__dirname, '../dist/styles')
const tsProject = ts.createProject('tsconfig.json', {
declaration: true,
target: 'ESNEXT',
skipLibCheck: true,
module: 'commonjs',
})
const rewriter = () => {
return through2.obj(function(file, _, cb) {
const compIdentifier = '@element-plus/components'
const compReplacer = '../../../components'
const themeIdentifier = '@element-plus/theme-chalk'
const themeReplacer = '../../../../theme-chalk'
file.contents = Buffer.from(
file.contents
.toString()
.replaceAll(compIdentifier, compReplacer)
.replaceAll(themeIdentifier, themeReplacer),
)
cb(null, file)
})
}
const inputs = '../packages/components/**/style/*.ts'
function compileEsm() {
return gulp
.src(inputs)
.pipe(rewriter())
.pipe(tsProject())
.pipe(gulp.dest(path.resolve(output, 'lib')))
}
function compileCjs() {
return gulp
.src(inputs)
.pipe(rewriter())
.pipe(
ts.createProject('tsconfig.json', {
declaration: true,
target: 'ESNEXT',
skipLibCheck: true,
module: 'ESNEXT',
})(),
)
.pipe(gulp.dest(path.resolve(output, 'es')))
}
export const build = gulp.series(compileEsm, compileCjs)
export default build

26
build/paths.ts Normal file
View File

@ -0,0 +1,26 @@
import path from 'path'
const projRoot = path.resolve(__dirname, '../')
const pkgRoot = path.resolve(projRoot, './packages')
const compRoot = path.resolve(pkgRoot, './components')
const themeRoot = path.resolve(pkgRoot, './theme-chalk')
const hookRoot = path.resolve(pkgRoot, './hooks')
const localeRoot = path.resolve(pkgRoot, './locale')
const directiveRoot = path.resolve(pkgRoot, './directives')
const epRoot = path.resolve(pkgRoot, './element-plus')
const utilRoot = path.resolve(pkgRoot, './utils')
const buildOutput = path.resolve(projRoot, './dist')
export {
projRoot,
pkgRoot,
compRoot,
themeRoot,
hookRoot,
directiveRoot,
localeRoot,
epRoot,
utilRoot,
buildOutput,
}

View File

@ -1,48 +0,0 @@
// import vue from 'rollup-plugin-vue'
import { nodeResolve } from '@rollup/plugin-node-resolve'
import path from 'path'
// import commonjs from '@rollup/plugin-commonjs'
import { terser } from 'rollup-plugin-terser'
import typescript from 'rollup-plugin-typescript2'
import pkg from '../package.json'
const deps = Object.keys(pkg.dependencies)
// eslint-disable-next-line @typescript-eslint/no-var-requires
const vue = require('rollup-plugin-vue')
export default [
{
input: path.resolve(__dirname, '../packages/element-plus/index.ts'),
output: {
format: 'es',
file: 'lib/index.esm.js',
},
plugins: [
terser(),
nodeResolve(),
// commonjs(),
vue({
target: 'browser',
css: false,
exposeFilename: false,
}),
typescript({
tsconfigOverride: {
'include': [
'packages/**/*',
'typings/vue-shim.d.ts',
],
'exclude': [
'node_modules',
'packages/**/__tests__/*',
],
},
abortOnError: false,
}),
],
external(id) {
return /^vue/.test(id)
|| deps.some(k => new RegExp('^' + k).test(id))
},
},
]

View File

@ -49,7 +49,7 @@ export default inputs.map(name => ({
css(),
vue({
target: 'browser',
css: false,
// css: false,
}),
nodeResolve(),
esbuild(),

View File

@ -0,0 +1,23 @@
import path from 'path'
import type { Plugin } from 'rollup'
export default function entryPlugin(): Plugin {
return {
name: 'element-plus-entry-plugin',
transform(code, id) {
if (id.includes('packages')) {
return {
code: code.replace(
/@element-plus\//g,
`${path.relative(
path.dirname(id),
path.resolve(__dirname, '../packages'),
)}/`,
),
map: null,
}
}
return { code, map: null }
},
}
}

77
build/size-reporter.ts Normal file
View File

@ -0,0 +1,77 @@
import chalk from 'chalk'
export default async function reporter(opt, outputOptions, info) {
const values = [
// ...(outputOptions.file || outputOptions.dest
// ? [
// `${title('Destination: ')}${value(
// outputOptions.file || outputOptions.dest,
// )}`,
// ]
// :
info.fileName
? [`${outputOptions.file.split('packages/').pop()}`]
: [],
// )
// ...(info.bundleSizeBefore
// ? [
// `${value(info.bundleSize)} (was ${value(
// info.bundleSizeBefore,
// )}${info.lastVersion
// ? ` in version ${info.lastVersion}`
// : ' in last build'
// })`,
// ]
// :
[`${info.bundleSize}`],
// ),
...(info.minSize
?
// info.minSizeBefore
// ? [
// `${title('Minified Size: ')} ${value(info.minSize)} (was ${value(
// info.minSizeBefore,
// )}${info.lastVersion
// ? ` in version ${info.lastVersion}`
// : ' in last build'
// })`,
// ]
// :
[`${info.minSize}`]
: []),
// ...(info.gzipSize
// ? info.gzipSizeBefore
// ? [
// `${title('Gzipped Size: ')} ${value(info.gzipSize)} (was ${value(
// info.gzipSizeBefore,
// )}${info.lastVersion
// ? ` in version ${info.lastVersion}`
// : ' in last build'
// })`,
// ]
// : [`${title('Gzipped Size: ')} ${value(info.gzipSize)}`]
// : []),
// ...(info.brotliSize
// ? info.brotliSizeBefore
// ? [
// `${title('Brotli size: ')}${value(info.brotliSize)} (was ${value(
// info.brotliSizeBefore,
// )}${info.lastVersion
// ? ` in version ${info.lastVersion}`
// : ' in last build'
// })`,
// ]
// : [`${title('Brotli size: ')}${value(info.brotliSize)}`]
// : []),
]
return `${
chalk.cyan(chalk.bold(values[0]))
}: bundle size ${
chalk.yellow(values[1])
} -> minified ${
chalk.green(values[2])
}`
}

50
build/update-version.ts Normal file
View File

@ -0,0 +1,50 @@
import chalk from 'chalk'
import path from 'path'
import fs from 'fs'
import { epRoot } from './paths'
const tagVersion = process.env.TAG_VERSION
const gitHead = process.env.GIT_HEAD
if (!tagVersion || !gitHead) {
console.log(
chalk.red(
'No tag version or git head were found, make sure that you set the environment variable $TAG_VERSION \n',
),
)
process.exit(1)
}
console.log(chalk.cyan('Start updating version'))
console.log(chalk.cyan([
'NOTICE:',
`$TAG_VERSION: ${tagVersion}`,
`$GIT_HEAD: ${gitHead}`,
].join('\n')))
; (async () => {
console.log(chalk.yellow(`Updating package.json for element-plus`))
const pkgJson = path.resolve(epRoot, './package.json')
// eslint-disable-next-line @typescript-eslint/no-var-requires
const json = require(pkgJson)
json.version = tagVersion
json.gitHead = gitHead
if (!(process.argv.includes('-d') || process.argv.includes('--dry-run'))) {
try {
await fs.promises.writeFile(pkgJson, JSON.stringify(json, null, 2), {
encoding: 'utf-8',
})
} catch (e) {
process.exit(1)
}
} else {
console.log(json)
}
console.log(chalk.green(`Version updated to ${tagVersion}`))
console.log(chalk.green(`Git head updated to ${gitHead}`))
})()

View File

@ -38,7 +38,7 @@ const config = {
mode: 'production',
entry,
output: {
path: path.resolve(__dirname, '../lib'),
path: path.resolve(__dirname, '../dist/element-plus/dist'),
publicPath: '/',
filename: isFullMode ? 'index.full.js' : 'index.js',
libraryTarget: 'umd',

132
build/worker.js Normal file
View File

@ -0,0 +1,132 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs')
const path = require('path')
const { parentPort, workerData } = require('worker_threads')
const { Project } = require('ts-morph')
const chalk = require('chalk')
const vueCompiler = require('@vue/compiler-sfc')
const TSCONFIG_PATH = path.resolve(process.cwd(), 'tsconfig.dts.json')
; (async () => {
const { filePaths, workerId, outDir } = workerData
let messagePort
parentPort.once('message', async ({ port }) => {
messagePort = port
messagePort.postMessage({
type: 'log',
message: chalk.yellow(`Worker: ${chalk.bold(workerData.workerId)} started`),
})
const project = new Project({
compilerOptions: {
outDir,
},
tsConfigFilePath: TSCONFIG_PATH,
skipAddingFilesFromTsConfig: true,
})
const sourceFiles = []
await Promise.all(filePaths.map(async file => {
if (file.endsWith('.vue')) {
const content = await fs.promises.readFile(file, 'utf-8')
const sfc = vueCompiler.parse(content)
const { script, scriptSetup } = sfc.descriptor
if (script || scriptSetup) {
let content = ''
let isTS = false
if (script && script.content) {
content += script.content
if (script.lang === 'ts') isTS = true
}
if (scriptSetup) {
const compiled = vueCompiler.compileScript(sfc.descriptor, {
id: 'xxx',
})
content += compiled.content
if (scriptSetup.lang === 'ts') isTS = true
}
const sourceFile = project.createSourceFile(
path.relative(process.cwd(), file) + (isTS ? '.ts' : '.js'),
content,
)
sourceFiles.push(sourceFile)
}
} else if (file.endsWith('.ts')) {
const sourceFile = project.addSourceFileAtPath(file)
sourceFiles.push(sourceFile)
}
}))
const diagnostics = project.getPreEmitDiagnostics()
await project.emit({
emitOnlyDtsFiles: true,
})
messagePort.postMessage({
type: 'log',
message: project.formatDiagnosticsWithColorAndContext(diagnostics),
})
for (const sourceFile of sourceFiles) {
messagePort.postMessage({
type: 'log',
message: chalk.yellow(
'Generating definition for file: ' +
chalk.bold(
sourceFile.getFilePath(),
),
),
})
// console.log(sourceFile.getStructure())
const ElementPlusSign = '@element-plus/'
sourceFile.getImportDeclarations(dec => dec.getModuleSpecifierValue().startsWith(ElementPlusSign)).map(modifySpecifier)
function modifySpecifier(d) {
const replaceTo = 'element-plus/es/' + d.getModuleSpecifierValue().slice(ElementPlusSign.length)
d.setModuleSpecifier(
replaceTo,
)
}
// console.log(sourceFile.getFilePath())
const emitOutput = sourceFile.getEmitOutput({
emitOnlyDtsFiles: true,
})
for (const outputFile of emitOutput.getOutputFiles()) {
// console.log(outputFile)
const filepath = outputFile.getFilePath()
await fs.promises.mkdir(path.dirname(filepath), {
recursive: true,
})
await fs.promises.writeFile(filepath, outputFile.getText(), 'utf8')
messagePort.postMessage({
type: 'log',
message: chalk.green(
'Definition for file: ' +
chalk.bold(
sourceFile.getBaseName(),
) +
' generated',
),
})
}
messagePort.postMessage({ type: 'fulfill', message: workerId })
}
})
// parentPort.emit
})()

View File

@ -1,27 +1,30 @@
{
"name": "element-plus",
"private": true,
"version": "0.0.0-development",
"scripts": {
"cz": "npx git-cz",
"test": "jest",
"gen": "bash ./scripts/gc.sh",
"bootstrap": "yarn --frozen-lockfile && npx lerna bootstrap && yarn gen:version",
"gen:version": "node build/gen-version.js",
"gen:version": "esno build/gen-version.ts",
"build": "yarn bootstrap && yarn clean:lib && yarn build:esm-bundle && yarn build:lib && yarn build:lib-full && yarn build:esm && yarn build:utils && yarn build:locale && yarn build:locale-umd && yarn build:theme && yarn build:helper",
"clean:lib": "rimraf lib && rimraf es && rimraf dist",
"build:lib": "cross-env LIBMODE=core webpack --config ./build/webpack.config.js",
"build:lib-full": "cross-env LIBMODE=full webpack --config ./build/webpack.config.js",
"build:esm-bundle": "rollup --config ./build/rollup.config.bundle.js && yarn build:type",
"build:type": "node build/gen-dts.js",
"build:esm": "node ./build/bincomp.js",
"build:components": "rollup --config ./build/rollup.config.js",
"build:utils": "cross-env BABEL_ENV=utils babel packages/utils --extensions .ts --out-dir lib/utils",
"build:locale": "cross-env BABEL_ENV=utils babel packages/locale --extensions .ts --out-dir lib/locale",
"build:locale-umd": "node ./build/build-locale.js",
"build:theme": "cd packages/theme-chalk && yarn clean && yarn build",
"build:helper": "node build/build-helper.js",
"build:locale-umd": "esno ./build/build-locale.ts",
"build:helper": "esno build/build-helper.ts",
"build:indices": "node build/build-indices.js",
"update:version": "esno build/update-version.ts",
"build:comps": "rimraf dist/components && esno build/components.ts",
"build:style": "gulp --cwd ./build",
"build:prod": "sh scripts/monorepo.sh",
"build:directives": "cd packages/directives && yarn clean && yarn build",
"build:hooks": "cd packages/hooks && yarn clean && yarn build",
"build:locale": "cd packages/locale && yarn clean && yarn build",
"build:theme": "cd packages/theme-chalk && yarn clean && yarn build",
"build:utils": "cd packages/utils && yarn clean && yarn build",
"build:tokens": "cd packages/tokens && yarn clean && yarn build",
"build:full-bundle": "esno build/full-bundle.ts",
"format": "yarn format:scss",
"format:scss": "prettier --write **/*.scss",
"lint": "eslint ./packages --ext .vue,.js,.ts",
@ -44,10 +47,12 @@
"@babel/preset-typescript": "^7.10.4",
"@commitlint/cli": "^9.1.2",
"@commitlint/config-conventional": "^9.1.2",
"@rollup/plugin-alias": "^3.1.5",
"@rollup/plugin-commonjs": "^15.1.0",
"@rollup/plugin-node-resolve": "^9.0.0",
"@rollup/plugin-typescript": "^6.0.0",
"@types/jest": "^26.0.10",
"@types/klaw-sync": "^6.0.1",
"@types/lodash": "^4.14.161",
"@typescript-eslint/eslint-plugin": "^3.10.1",
"@typescript-eslint/parser": "^3.10.1",
@ -70,8 +75,12 @@
"esbuild": "^0.12.5",
"eslint": "^7.7.0",
"eslint-plugin-vue": "^7.0.0-beta.0",
"esno": "^0.9.1",
"fast-glob": "^3.2.7",
"file-loader": "^6.0.0",
"file-save": "^0.2.0",
"gulp": "^4.0.2",
"gulp-typescript": "^6.0.0-alpha.1",
"highlight.js": "^10.4.1",
"html-webpack-plugin": "^4.3.0",
"husky": "^4.2.5",
@ -91,6 +100,7 @@
"rollup": "^2.28.2",
"rollup-plugin-css-only": "^2.1.0",
"rollup-plugin-esbuild": "^4.2.3",
"rollup-plugin-filesize": "^9.1.1",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.27.3",
"rollup-plugin-vue": "^6.0.0",
@ -98,11 +108,12 @@
"sass-loader": "10.1.1",
"style-loader": "^1.2.1",
"throttle-debounce": "2.3.0",
"through2": "^4.0.2",
"transliteration": "^2.1.11",
"ts-loader": "^8.0.3",
"ts-morph": "^11.0.3",
"ts-node": "^10.1.0",
"typescript": "^4.0.2",
"ts-node": "^10.2.0",
"typescript": "^4.3.5",
"url-loader": "^4.1.0",
"vue": "3.1.1",
"vue-jest": "5.0.0-alpha.5",

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/affix",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/alert",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Aside from '../container/src/aside.vue'
Aside.install = (app: App): void => {
app.component(Aside.name, Aside)
}
const _Aside: SFCWithInstall<typeof Aside> = Aside
export default _Aside

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/aside",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/autocomplete",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,15 +0,0 @@
{
"name": "@element-plus/avatar",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
},
"dependencies": {
"@element-plus/utils": "^0.0.0"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/backtop",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,13 +0,0 @@
{
"name": "@element-plus/badge",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@element-plus/button": "^0.0.0",
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import BreadcrumbItem from '../breadcrumb/src/item.vue'
BreadcrumbItem.install = (app: App): void => {
app.component(BreadcrumbItem.name, BreadcrumbItem)
}
const _BreadcrumbItem: SFCWithInstall<typeof BreadcrumbItem> = BreadcrumbItem
export default _BreadcrumbItem

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/breadcrumb-item",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Breadcrumb from './src/index.vue'
Breadcrumb.install = (app: App): void => {
app.component(Breadcrumb.name, Breadcrumb)
}
const _Breadcrumb: SFCWithInstall<typeof Breadcrumb> = Breadcrumb
export default _Breadcrumb

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/breadcrumb",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import ButtonGroup from '../button/src/button-group.vue'
ButtonGroup.install = (app: App): void => {
app.component(ButtonGroup.name, ButtonGroup)
}
const _ButtonGroup: SFCWithInstall<typeof ButtonGroup> = ButtonGroup
export default _ButtonGroup

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/button-group",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Button from './src/button.vue'
Button.install = (app: App): void => {
app.component(Button.name, Button)
}
const _Button: SFCWithInstall<typeof Button> = Button
export default _Button

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/button",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/calendar",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/card",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import CarouselItem from '../carousel/src/item.vue'
CarouselItem.install = (app: App): void => {
app.component(CarouselItem.name, CarouselItem)
}
const _CarouselItem: SFCWithInstall<typeof CarouselItem> = CarouselItem
export default _CarouselItem

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/carousel-item",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Carousel from './src/main.vue'
Carousel.install = (app: App): void => {
app.component(Carousel.name, Carousel)
}
const _Carousel: SFCWithInstall<typeof Carousel> = Carousel
export default _Carousel

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/carousel",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.0"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/cascader-panel",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/cascader",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/check-tag",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import CheckboxButton from '../checkbox/src/checkbox-button.vue'
CheckboxButton.install = (app: App): void => {
app.component(CheckboxButton.name, CheckboxButton)
}
const _CheckboxButton: SFCWithInstall<typeof CheckboxButton> = CheckboxButton
export default _CheckboxButton

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/checkbox-button",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import CheckboxGroup from '../checkbox/src/checkbox-group.vue'
CheckboxGroup.install = (app: App): void => {
app.component(CheckboxGroup.name, CheckboxGroup)
}
const _CheckboxGroup: SFCWithInstall<typeof CheckboxGroup> = CheckboxGroup
export default _CheckboxGroup

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/checkbox-group",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Checkbox from './src/checkbox.vue'
Checkbox.install = (app: App): void => {
app.component(Checkbox.name, Checkbox)
}
const _Checkbox: SFCWithInstall<typeof Checkbox> = Checkbox
export default _Checkbox

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/checkbox",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/col",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import CollapseItem from '../collapse/src/collapse-item.vue'
CollapseItem.install = (app: App): void => {
app.component(CollapseItem.name, CollapseItem)
}
const _CollapseItem: SFCWithInstall<typeof CollapseItem> = CollapseItem
export default _CollapseItem

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/collapse-item",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import CollapseTransition from '../transition/collapse-transition/index.vue'
CollapseTransition.install = (app: App): void => {
app.component(CollapseTransition.name, CollapseTransition)
}
const _CollapseTransition: SFCWithInstall<typeof CollapseTransition> = CollapseTransition
export default _CollapseTransition

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/collapse-transition",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,11 +0,0 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Collapse from './src/collapse.vue'
Collapse.install = (app: App): void => {
app.component(Collapse.name, Collapse)
}
const _Collapse: SFCWithInstall<typeof Collapse> = Collapse
export default _Collapse

View File

@ -1,16 +0,0 @@
{
"name": "@element-plus/collapse",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"dependencies": {
"mitt": "^2.1.0",
"@element-plus/utils": "^0.0.0"
},
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.3"
}
}

View File

@ -1,12 +0,0 @@
{
"name": "@element-plus/color-picker",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"peerDependencies": {
"vue": "3.1.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.0"
}
}

View File

@ -1,6 +1,6 @@
import { mount } from '@vue/test-utils'
import Affix from '../src/index.vue'
import { defineGetter, makeScroll } from '@element-plus/test-utils'
import Affix from '../src/index.vue'
let clientHeightRestore = null

View File

@ -1,11 +1,14 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Affix from './src/index.vue'
import type { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
Affix.install = (app: App): void => {
app.component(Affix.name, Affix)
}
const _Affix: SFCWithInstall<typeof Affix> = Affix
const _Affix = Affix as SFCWithInstall<typeof Affix>
export default _Affix
export const ElAffix = _Affix

View File

@ -6,10 +6,12 @@
</div>
</template>
<script lang="ts">
import { computed, defineComponent, onBeforeUnmount, onMounted, PropType, reactive, ref, watch } from 'vue'
import { computed, defineComponent, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
import { getScrollContainer, off, on } from '@element-plus/utils/dom'
import { addResizeListener, removeResizeListener } from '@element-plus/utils/resize-event'
import type { PropType } from 'vue'
type Position = 'top' | 'bottom'
export default defineComponent({

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style/css'
import '@element-plus/theme-chalk/el-affix.css'

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style'
import '@element-plus/theme-chalk/src/affix.scss'

View File

@ -1,11 +1,13 @@
import { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
import Alert from './src/index.vue'
import type { App } from 'vue'
import type { SFCWithInstall } from '@element-plus/utils/types'
Alert.install = (app: App): void => {
app.component(Alert.name, Alert)
}
const _Alert: SFCWithInstall<typeof Alert> = Alert
const _Alert = Alert as SFCWithInstall<typeof Alert>
export default _Alert
export const ElAlert = _Alert

View File

@ -29,7 +29,9 @@
</transition>
</template>
<script lang='ts'>
import { defineComponent, computed, ref, PropType } from 'vue'
import { defineComponent, computed, ref } from 'vue'
import type { PropType } from 'vue'
const TYPE_CLASSES_MAP = {
'success': 'el-icon-success',

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style/css'
import '@element-plus/theme-chalk/el-alert.css'

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style'
import '@element-plus/theme-chalk/src/alert.scss'

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style/css'
import '@element-plus/theme-chalk/el-aside.css'

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style'
import '@element-plus/theme-chalk/src/aside.scss'

View File

@ -6,6 +6,7 @@ Autocomplete.install = (app: App): void => {
app.component(Autocomplete.name, Autocomplete)
}
const _Autocomplete: SFCWithInstall<typeof Autocomplete> = Autocomplete
const _Autocomplete = Autocomplete as SFCWithInstall<typeof Autocomplete>
export default _Autocomplete
export const ElAutocomplete = _Autocomplete

View File

@ -91,16 +91,16 @@ import {
onMounted, onUpdated,
nextTick, watch,
} from 'vue'
import { useAttrs } from '@element-plus/hooks'
import { NOOP } from '@vue/shared'
import debounce from 'lodash/debounce'
import { useAttrs } from '@element-plus/hooks'
import { ClickOutside } from '@element-plus/directives'
import { generateId, isArray } from '@element-plus/utils/util'
import { UPDATE_MODEL_EVENT } from '@element-plus/utils/constants'
import throwError from '@element-plus/utils/error'
import ElInput from '@element-plus/input'
import ElScrollbar from '@element-plus/scrollbar'
import ElPopper from '@element-plus/popper'
import ElInput from '@element-plus/components/input'
import ElScrollbar from '@element-plus/components/scrollbar'
import ElPopper from '@element-plus/components/popper'
import type { PropType } from 'vue'

View File

@ -0,0 +1,5 @@
import '@element-plus/components/base/style/css'
import '@element-plus/theme-chalk/el-autocomplete.css'
import '@element-plus/components/input/style/css'
import '@element-plus/components/scrollbar/style/css'
import '@element-plus/components/popper/style/css'

View File

@ -0,0 +1,5 @@
import '@element-plus/components/base/style'
import '@element-plus/theme-chalk/src/autocomplete.scss'
import '@element-plus/components/input/style/index'
import '@element-plus/components/scrollbar/style/index'
import '@element-plus/components/popper/style/index'

View File

@ -1,8 +1,9 @@
import { mount } from '@vue/test-utils'
import { nextTick } from 'vue'
import Avatar from '../src/index.vue'
import { mount } from '@vue/test-utils'
import { IMAGE_SUCCESS, IMAGE_FAIL, mockImageEvent } from '@element-plus/test-utils'
import Avatar from '../src/index.vue'
describe('Avatar.vue', () => {
mockImageEvent()

View File

@ -6,6 +6,7 @@ Avatar.install = (app: App): void => {
app.component(Avatar.name, Avatar)
}
const _Avatar: SFCWithInstall<typeof Avatar> = Avatar
const _Avatar = Avatar as SFCWithInstall<typeof Avatar>
export default _Avatar
export const ElAvatar = _Avatar

View File

@ -14,7 +14,8 @@
</template>
<script lang="ts">
import { defineComponent, computed, ref, PropType, watch, toRef } from 'vue'
import { defineComponent, computed, ref, watch, toRef } from 'vue'
import type { CSSProperties, PropType } from 'vue'
const ERROR_EVENT = 'error'
export default defineComponent({
@ -85,7 +86,7 @@ export default defineComponent({
const fitStyle = computed(() => ({
objectFit: props.fit,
}))
}) as CSSProperties)
function handleError(e: Event) {
hasLoadError.value = true

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style/css'
import '@element-plus/theme-chalk/el-avatar.css'

View File

@ -0,0 +1,2 @@
import '@element-plus/components/base/style'
import '@element-plus/theme-chalk/src/avatar.scss'

Some files were not shown because too many files have changed in this diff Show More