From ca7906114f7cf74c822d978579f292d8f89feda9 Mon Sep 17 00:00:00 2001 From: Ahmad Luthfi Masruri Date: Mon, 29 Mar 2021 07:48:10 +0700 Subject: [PATCH] fix: use typescripts --- scripts/bootstrap.js | 120 -------------------------------- scripts/bootstrap.ts | 121 +++++++++++++++++++++++++++++++++ scripts/build-assets.js | 116 ------------------------------- scripts/build-types.js | 108 ----------------------------- scripts/build.js | 109 ----------------------------- scripts/build.ts | 113 ++++++++++++++++++++++++++++++ scripts/buildAssets.ts | 113 ++++++++++++++++++++++++++++++ scripts/dev-assets.js | 89 ------------------------ scripts/dev.js | 44 ------------ scripts/dev.ts | 47 +++++++++++++ scripts/devAssets.ts | 65 ++++++++++++++++++ scripts/release.js | 12 ---- scripts/release.ts | 14 ++++ scripts/{utils.js => utils.ts} | 86 +++++++++++++++++++---- 14 files changed, 544 insertions(+), 613 deletions(-) delete mode 100644 scripts/bootstrap.js create mode 100644 scripts/bootstrap.ts delete mode 100644 scripts/build-assets.js delete mode 100644 scripts/build-types.js delete mode 100644 scripts/build.js create mode 100644 scripts/build.ts create mode 100644 scripts/buildAssets.ts delete mode 100644 scripts/dev-assets.js delete mode 100644 scripts/dev.js create mode 100644 scripts/dev.ts create mode 100644 scripts/devAssets.ts delete mode 100644 scripts/release.js create mode 100644 scripts/release.ts rename scripts/{utils.js => utils.ts} (50%) diff --git a/scripts/bootstrap.js b/scripts/bootstrap.js deleted file mode 100644 index de559555..00000000 --- a/scripts/bootstrap.js +++ /dev/null @@ -1,120 +0,0 @@ -// create package.json, README, etc. for packages that don't have them yet - -const args = require('minimist')(process.argv.slice(2)) -const fs = require('fs') -const path = require('path') -const version = require('../package.json').version - -const packagesDir = path.resolve(__dirname, '../packages') -const files = fs.readdirSync(packagesDir) - -files.forEach((shortName) => { - if (!fs.statSync(path.join(packagesDir, shortName)).isDirectory()) { - return - } - - const name = `@vueup/${shortName}` - const pkgPath = path.join(packagesDir, shortName, `package.json`) - const pkgExists = fs.existsSync(pkgPath) - if (pkgExists) { - const pkg = require(pkgPath) - if (pkg.private) { - return - } - } - - if (args.force || !pkgExists) { - const json = { - name, - version, - description: name, - main: 'index.js', - module: `dist/${shortName}.esm-bundler.js`, - files: [`index.js`, `dist`], - types: `dist/${shortName}.d.ts`, - repository: { - type: 'git', - url: 'git+https://github.com/vuejs/vue.git', - }, - keywords: ['vue-quill'], - author: 'Ahmad Luthfi Masruri', - license: 'MIT', - bugs: { - url: 'https://github.com/vueup/vue-quill/issues', - }, - homepage: `https://github.com/vueup/vue-quill/tree/dev/packages/${shortName}#readme`, - } - fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2)) - } - - const readmePath = path.join(packagesDir, shortName, `README.md`) - if (args.force || !fs.existsSync(readmePath)) { - fs.writeFileSync(readmePath, `# ${name}`) - } - - const apiExtractorConfigPath = path.join( - packagesDir, - shortName, - `api-extractor.json` - ) - if (args.force || !fs.existsSync(apiExtractorConfigPath)) { - fs.writeFileSync( - apiExtractorConfigPath, - ` -{ - "extends": "../../api-extractor.json", - "mainEntryPointFilePath": "./dist/packages//src/index.d.ts", - "dtsRollup": { - "publicTrimmedFilePath": "./dist/.d.ts" - } -} -`.trim() - ) - } - - const assetsConfigPath = path.join( - packagesDir, - shortName, - `assets.config.json` - ) - if (args.force || !fs.existsSync(assetsConfigPath)) { - fs.writeFileSync( - assetsConfigPath, - ` -{ - "css": [ - { - "input": "./src/assets/css/index.css", - "output": "./dist/${shortName}.css" - } - ] -} -`.trim() - ) - } - - const srcDir = path.join(packagesDir, shortName, `src`) - const indexPath = path.join(packagesDir, shortName, `src/index.ts`) - if (args.force || !fs.existsSync(indexPath)) { - if (!fs.existsSync(srcDir)) { - fs.mkdirSync(srcDir) - } - fs.writeFileSync(indexPath, ``) - } - - const nodeIndexPath = path.join(packagesDir, shortName, 'index.js') - if (args.force || !fs.existsSync(nodeIndexPath)) { - fs.writeFileSync( - nodeIndexPath, - ` -'use strict' - -if (process.env.NODE_ENV === 'production') { - module.exports = require('./dist/${shortName}.cjs.prod.js') -} else { - module.exports = require('./dist/${shortName}.cjs.js') -} - `.trim() + '\n' - ) - } -}) diff --git a/scripts/bootstrap.ts b/scripts/bootstrap.ts new file mode 100644 index 00000000..748f8145 --- /dev/null +++ b/scripts/bootstrap.ts @@ -0,0 +1,121 @@ +// create package.json, README, etc. for packages that don't have them yet +(() => { + const fs = require('fs') + const path = require('path') + + const args = require('minimist')(process.argv.slice(2)) + const version: string = require('../package.json').version + const packagesDir: string = path.resolve(__dirname, '../packages') + const files: string[] = fs.readdirSync(packagesDir) + + files.forEach((shortName) => { + if (!fs.statSync(path.join(packagesDir, shortName)).isDirectory()) { + return + } + + const name = `@vueup/${shortName}` + const pkgPath = path.join(packagesDir, shortName, `package.json`) + const pkgExists = fs.existsSync(pkgPath) + if (pkgExists) { + const pkg = require(pkgPath) + if (pkg.private) { + return + } + } + + if (args.force || !pkgExists) { + const json = { + name, + version, + description: name, + main: 'index.js', + module: `dist/${shortName}.esm-bundler.js`, + files: [`index.js`, `dist`], + types: `dist/${shortName}.d.ts`, + repository: { + type: 'git', + url: 'git+https://github.com/vuejs/vue.git', + }, + keywords: ['vue-quill'], + author: 'Ahmad Luthfi Masruri', + license: 'MIT', + bugs: { + url: 'https://github.com/vueup/vue-quill/issues', + }, + homepage: `https://github.com/vueup/vue-quill/tree/dev/packages/${shortName}#readme`, + } + fs.writeFileSync(pkgPath, JSON.stringify(json, null, 2)) + } + + const readmePath = path.join(packagesDir, shortName, `README.md`) + if (args.force || !fs.existsSync(readmePath)) { + fs.writeFileSync(readmePath, `# ${name}`) + } + + const apiExtractorConfigPath = path.join( + packagesDir, + shortName, + `api-extractor.json` + ) + if (args.force || !fs.existsSync(apiExtractorConfigPath)) { + fs.writeFileSync( + apiExtractorConfigPath, + ` +{ + "extends": "../../api-extractor.json", + "mainEntryPointFilePath": "./dist/packages//src/index.d.ts", + "dtsRollup": { + "publicTrimmedFilePath": "./dist/.d.ts" + } +} +`.trim() + ) + } + + const assetsConfigPath = path.join( + packagesDir, + shortName, + `assets.config.json` + ) + if (args.force || !fs.existsSync(assetsConfigPath)) { + fs.writeFileSync( + assetsConfigPath, + ` +{ + "css": [ + { + "input": "./src/assets/css/index.css", + "output": "./dist/${shortName}.css" + } + ] +} +`.trim() + ) + } + + const srcDir = path.join(packagesDir, shortName, `src`) + const indexPath = path.join(packagesDir, shortName, `src/index.ts`) + if (args.force || !fs.existsSync(indexPath)) { + if (!fs.existsSync(srcDir)) { + fs.mkdirSync(srcDir) + } + fs.writeFileSync(indexPath, ``) + } + + const nodeIndexPath = path.join(packagesDir, shortName, 'index.js') + if (args.force || !fs.existsSync(nodeIndexPath)) { + fs.writeFileSync( + nodeIndexPath, + ` +'use strict' + +if (process.env.NODE_ENV === 'production') { + module.exports = require('./dist/${shortName}.cjs.prod.js') +} else { + module.exports = require('./dist/${shortName}.cjs.js') +} + `.trim() + '\n' + ) + } + }) +})() diff --git a/scripts/build-assets.js b/scripts/build-assets.js deleted file mode 100644 index 497bb3c1..00000000 --- a/scripts/build-assets.js +++ /dev/null @@ -1,116 +0,0 @@ -/* -Produces production builds and stitches together d.ts files. - -To specify the package to build, simply pass its name and the desired build -formats to output (defaults to `buildOptions.formats` specified in that package, -or "esm,cjs"): - -``` -# name supports fuzzy match. will build all packages with name containing "dom": -npm run assets:build -- vue-quill -``` -*/ - -const fs = require('fs-extra') -const path = require('path') -const chalk = require('chalk') -const execa = require('execa') -const { - targetAssets: allTargets, - fuzzyMatchTarget, - checkAssetsSize, - runParallel, -} = require('./utils') - -const args = require('minimist')(process.argv.slice(2)) -const targets = args._ -const devOnly = args.devOnly || args.d -const prodOnly = !devOnly && (args.prodOnly || args.p) -// const sourceMap = args.sourcemap || args.s -const isRelease = args.release -const buildAllMatching = args.all || args.a -const nextVersion = - args.nextVersion || - require(path.resolve(__dirname, '..', 'package.json')).version -const commit = - args.commit || execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) - -run() - -async function run() { - if (isRelease) { - // remove build cache for release builds to avoid outdated enum values - await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) - } - if (!targets.length) { - await buildAll(allTargets) - checkAllSizes(allTargets) - } else { - await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - } -} - -async function buildAll(targets) { - await runParallel(require('os').cpus().length, targets, buildAssets) -} - -async function buildAssets(target) { - const rootDir = path.resolve(__dirname, '..') - const pkgDir = path.resolve(__dirname, `../packages/${target}`) - const assetsConfig = require(path.resolve(pkgDir, 'assets.config.json')) - - // only build published packages for release - if (isRelease && assetsConfig.private) return - - if (assetsConfig.css) { - assetsConfig.css.forEach((css) => { - const input = path.resolve(pkgDir, css.input) - const output = path.resolve(pkgDir, css.output) - const outputProd = path.resolve( - pkgDir, - path.dirname(output), - path.parse(output).name + '.prod.css' - ) - const inputExt = path.extname(input) - - if (inputExt === '.styl' || inputExt === '.css') { - console.log( - chalk.cyan(`${input} → ${path.relative(rootDir, output)}...`) - ) - execa.sync('stylus', [input, '-o', output]) - console.log( - chalk.green( - `created: ${chalk.bold(path.relative(rootDir, output))}\n` - ) - ) - - // create production build - console.log( - chalk.cyan(`${input} → ${path.relative(rootDir, outputProd)}...`) - ) - execa.sync('stylus', [input, '-o', outputProd, '-c']) - console.log( - chalk.green( - `created: ${chalk.bold(path.relative(rootDir, outputProd))}\n` - ) - ) - } else { - console.log(chalk.redBright(`File extention not supported: ${input}`)) - } - }) - } -} - -function checkAllSizes(targets) { - if (devOnly) return - console.log() - for (const target of targets) { - checkAssetsSize(target) - } - console.log() -} - -module.exports = { - buildAssets, -} diff --git a/scripts/build-types.js b/scripts/build-types.js deleted file mode 100644 index ea9a9227..00000000 --- a/scripts/build-types.js +++ /dev/null @@ -1,108 +0,0 @@ -/* -Produces production builds and stitches together d.ts files. - -To specify the package to build, simply pass its name and the desired build -formats to output (defaults to `buildOptions.formats` specified in that package, -or "esm,cjs"): - -``` -# name supports fuzzy match. will build all packages with name containing "dom": -npm run assets:build -- vue-quill -``` -*/ - -const fs = require('fs-extra') -const path = require('path') -const chalk = require('chalk') -const execa = require('execa') -const { - targetAssets: allTargets, - fuzzyMatchTarget, - runParallel, -} = require('./utils') - -const args = require('minimist')(process.argv.slice(2)) -const targets = args._ -const buildAllMatching = args.all || args.a -const isRelease = args.release || (args.nextVersion && args.nextVersion !== '') -const nextVersion = - args.nextVersion || - require(path.resolve(__dirname, '..', 'package.json')).version - -run() - -async function run() { - if (isRelease) { - // remove build cache for release builds to avoid outdated enum values - await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) - } - if (!targets.length) { - await buildAll(allTargets) - checkAllSizes(allTargets) - } else { - await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - } -} - -async function buildAll(targets) { - await runParallel(require('os').cpus().length, targets, buildTypes) -} - -async function buildTypes(target) { - const pkgDir = path.resolve(__dirname, `../packages/${target}`) - console.log() - console.log( - chalk.bold(chalk.yellow(`Rolling up type definitions for ${target}...`)) - ) - - // build types - const { Extractor, ExtractorConfig } = require('@microsoft/api-extractor') - - const extractorConfigPath = path.resolve(pkgDir, `api-extractor.json`) - const extractorConfig = ExtractorConfig.loadFileAndPrepare( - extractorConfigPath - ) - const extractorResult = Extractor.invoke(extractorConfig, { - localBuild: true, - showVerboseMessages: true, - }) - - if (extractorResult.succeeded) { - // concat additional d.ts to rolled-up dts - try { - const typesDir = path.resolve(pkgDir, 'types') - if (await fs.promises.access(typesDir)) { - const dtsPath = path.resolve(pkgDir, pkg.types) - const existing = await fs.readFile(dtsPath, 'utf-8') - const typeFiles = await fs.readdir(typesDir) - const toAdd = await Promise.all( - typeFiles.map((file) => { - return fs.readFile(path.resolve(typesDir, file), 'utf-8') - }) - ) - await fs.writeFile(dtsPath, existing + '\n' + toAdd.join('\n')) - } - console.log( - chalk.bold(chalk.green(`API Extractor completed successfully.`)) - ) - } catch (err) { - console.log() - console.log( - chalk.yellow(`There's no additional .d.ts to roll-up with ${err}`) - ) - } - } else { - console.error( - `API Extractor completed with ${extractorResult.errorCount} errors` + - ` and ${extractorResult.warningCount} warnings` - ) - process.exitCode = 1 - } - - await fs.remove(`${pkgDir}/dist/packages`) -} - -module.exports = { - buildTypes, -} diff --git a/scripts/build.js b/scripts/build.js deleted file mode 100644 index 7d9f58b6..00000000 --- a/scripts/build.js +++ /dev/null @@ -1,109 +0,0 @@ -/* -Produces production builds and stitches together d.ts files. - -To specify the package to build, simply pass its name and the desired build -formats to output (defaults to `buildOptions.formats` specified in that package, -or "esm,cjs"): - -``` -# name supports fuzzy match. will build all packages with name containing "dom": -npm run build -- vue-quill - -# specify the format to output -npm run build -- vue-quill --formats cjs -``` -*/ - -const fs = require('fs-extra') -const path = require('path') -const execa = require('execa') -const { buildTypes } = require('./build-types') -const { buildAssets } = require('./build-assets') -const { - targets: allTargets, - fuzzyMatchTarget, - checkBuildSize, - runParallel, -} = require('./utils') - -const args = require('minimist')(process.argv.slice(2)) -const targets = args._ -const formats = args.formats || args.f -const devOnly = args.devOnly || args.d -const prodOnly = !devOnly && (args.prodOnly || args.p) -const sourceMap = args.sourcemap || args.s -const isRelease = args.release || (args.nextVersion && args.nextVersion !== '') -const hasTypes = args.t || args.types || isRelease -const hasAssets = args.assets || isRelease -const buildAllMatching = args.all || args.a -const nextVersion = - args.nextVersion || - require(path.resolve(__dirname, '..', 'package.json')).version -const commit = - args.commit || execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) - -run() - -async function run() { - if (isRelease) { - // remove build cache for release builds to avoid outdated enum values - await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) - } - if (!targets.length) { - await buildAll(allTargets) - checkAllSizes(allTargets) - } else { - await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - } -} - -async function buildAll(targets) { - await runParallel(require('os').cpus().length, targets, build) -} - -async function build(target) { - const pkgDir = path.resolve(__dirname, `../packages/${target}`) - const pkg = require(path.resolve(pkgDir, 'package.json')) - const assetsConfig = require(path.resolve(pkgDir, 'assets.config.json')) - - // only build published packages for release - if (isRelease && pkg.private) return - - // if building a specific format, do not remove dist. - if (!formats) await fs.remove(`${pkgDir}/dist`) - - const env = - (pkg.buildOptions && pkg.buildOptions.env) || - (devOnly ? 'development' : 'production') - await execa( - 'rollup', - [ - '-c', - '--environment', - [ - `COMMIT:${commit}`, - `NODE_ENV:${env}`, - `TARGET:${target}`, - formats ? `FORMATS:${formats}` : ``, - hasTypes ? `TYPES:true` : ``, - prodOnly ? `PROD_ONLY:true` : ``, - sourceMap ? `SOURCE_MAP:true` : ``, - nextVersion ? `NEXT_VERSION:${nextVersion}` : ``, - ] - .filter(Boolean) - .join(','), - ], - { stdio: 'inherit' } - ) - - if (hasTypes && pkg.types) buildTypes(target) - if (hasAssets && assetsConfig.css) buildAssets(target) -} - -function checkAllSizes(targets) { - if (devOnly) return - console.log() - for (const target of targets) checkBuildSize(target) - console.log() -} diff --git a/scripts/build.ts b/scripts/build.ts new file mode 100644 index 00000000..8fa383db --- /dev/null +++ b/scripts/build.ts @@ -0,0 +1,113 @@ +/* +Produces production builds and stitches together d.ts files. + +To specify the package to build, simply pass its name and the desired build +formats to output (defaults to `buildOptions.formats` specified in that package, +or "esm,cjs"): + +``` +# name supports fuzzy match. will build all packages with name containing "dom": +npm run build -- vue-quill + +# specify the format to output +npm run build -- vue-quill --formats cjs +``` +*/ +(() => { + const fs = require('fs-extra') + const path = require('path') + const execa = require('execa') + const { + targets: allTargets, + fuzzyMatchTarget, + checkBuildSize, + runParallel, + generateTypes + } = require('./utils') + + const args = require('minimist')(process.argv.slice(2)) + const targets: string[] = args._ + const formats: string[] = args.formats || args.f + const devOnly: boolean = args.devOnly || args.d + const prodOnly: boolean = !devOnly && (args.prodOnly || args.p) + const sourceMap: boolean = args.sourcemap || args.s + const isRelease: boolean = args.release || (args.nextVersion && args.nextVersion !== '') + const hasTypes: boolean = args.t || args.types || isRelease + const buildAssets: boolean = args.assets || isRelease + const buildAllMatching: string[] = args.all || args.a + const nextVersion: string = + args.nextVersion || + require(path.resolve(__dirname, '..', 'package.json')).version + const commit = + args.commit || execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) + + run() + + async function run() { + if (isRelease) { + // remove build cache for release builds to avoid outdated enum values + await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) + } + if (!targets.length) { + await buildAll(allTargets) + checkAllSizes(allTargets) + } else { + await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) + checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) + } + } + + async function buildAll(targets: string[]) { + await runParallel(require('os').cpus().length, targets, build) + } + + async function build(target: string) { + const pkgDir = path.resolve(__dirname, `../packages/${target}`) + const pkg = require(path.resolve(pkgDir, 'package.json')) + let assets: any = {} + try { assets = require(path.resolve(pkgDir, 'assets.config.json')) } catch { } + + // only build published packages for release + if (isRelease && pkg.private) return + + // if building a specific format, do not remove dist. + if (!formats) await fs.remove(`${pkgDir}/dist`) + + const env = + (pkg.buildOptions && pkg.buildOptions.env) || + (devOnly ? 'development' : 'production') + await execa( + 'rollup', + [ + '-c', + '--environment', + [ + `COMMIT:${commit}`, + `NODE_ENV:${env}`, + `TARGET:${target}`, + formats ? `FORMATS:${formats}` : ``, + hasTypes ? `TYPES:true` : ``, + prodOnly ? `PROD_ONLY:true` : ``, + sourceMap ? `SOURCE_MAP:true` : ``, + nextVersion ? `NEXT_VERSION:${nextVersion}` : ``, + ] + .filter(Boolean) + .join(','), + ], + { stdio: 'inherit' } + ) + + if (hasTypes && pkg.types) await generateTypes(target) + if (buildAssets && assets.css) { + const buildAssetsRunner = path.resolve(__dirname, 'buildAssets.ts') + await execa('npx', ['ts-node', buildAssetsRunner, target]) + } + } + + function checkAllSizes(targets: string[]) { + if (devOnly) return + console.log() + for (const target of targets) checkBuildSize(target) + console.log() + } +})() diff --git a/scripts/buildAssets.ts b/scripts/buildAssets.ts new file mode 100644 index 00000000..635a342f --- /dev/null +++ b/scripts/buildAssets.ts @@ -0,0 +1,113 @@ +/* +Produces production assets files. +To specify the package assets to build, simply pass its name + +``` +# name supports fuzzy match. will build all packages with name containing "vue-quill": +npm run assets:build -- vue-quill +``` +*/ +(() => { + const fs = require('fs-extra') + const path = require('path') + const chalk = require('chalk') + const execa = require('execa') + const { + targetAssets: allTargets, + fuzzyMatchTarget, + checkAssetsSize, + runParallel, + } = require('./utils') + + const args: any = require('minimist')(process.argv.slice(2)) + const targets: string[] = args._ + const devOnly: boolean = args.devOnly || args.d + const prodOnly: boolean = !devOnly && (args.prodOnly || args.p) + // const sourceMap = args.sourcemap || args.s + const isRelease: boolean = args.release + const buildAllMatching: string[] = args.all || args.a + // const nextVersion: string = + // args.nextVersion || + // require(path.resolve(__dirname, '..', 'package.json')).version + // const commit: string = + // args.commit || execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) + + run() + + async function run() { + if (isRelease) { + // remove build cache for release builds to avoid outdated enum values + await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) + } + if (!targets.length) { + await buildAll(allTargets) + checkAllSizes(allTargets) + } else { + await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) + checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) + } + } + + async function buildAll(targets: string[]) { + await runParallel(require('os').cpus().length, targets, buildAssets) + } + + async function buildAssets(target: string) { + const rootDir = path.resolve(__dirname, '..') + const pkgDir = path.resolve(__dirname, `../packages/${target}`) + const assets = require(path.resolve(pkgDir, 'assets.config.json')) + + // only build published packages for release + if (isRelease && assets.private) return + if (!assets.css) return + + assets.css.forEach(async (css: any) => { + const input = path.resolve(pkgDir, css.input) + const inputExt = path.extname(input) + const output = path.resolve(pkgDir, css.output) + const outputProd = path.resolve( + pkgDir, + path.dirname(output), + path.parse(output).name + '.prod.css' + ) + + if (inputExt === '.styl' || inputExt === '.css') { + if (!prodOnly) { + console.log( + chalk.cyan(`${input} → ${path.relative(rootDir, output)}...`) + ) + execa.sync('stylus', [input, '-o', output]) + console.log( + chalk.green( + `created: ${chalk.bold(path.relative(rootDir, output))}\n` + ) + ) + } + + // create production build + if (!devOnly) { + console.log( + chalk.cyan(`${input} → ${path.relative(rootDir, outputProd)}...`) + ) + execa.sync('stylus', [input, '-o', outputProd, '-c']) + console.log( + chalk.green( + `created: ${chalk.bold(path.relative(rootDir, outputProd))}\n` + ) + ) + } + } else { + console.log(chalk.redBright(`File extention not supported: ${input}`)) + } + }) + } + + function checkAllSizes(targets: string[]) { + if (devOnly) return + console.log() + for (const target of targets) { + checkAssetsSize(target) + } + console.log() + } +})() \ No newline at end of file diff --git a/scripts/dev-assets.js b/scripts/dev-assets.js deleted file mode 100644 index 5676df83..00000000 --- a/scripts/dev-assets.js +++ /dev/null @@ -1,89 +0,0 @@ -/* -Produces production builds and stitches together d.ts files. - -To specify the package to build, simply pass its name and the desired build -formats to output (defaults to `buildOptions.formats` specified in that package, -or "esm,cjs"): - -``` -# name supports fuzzy match. will build all packages with name containing "dom": -npm run assets:build -- vue-quill -``` -*/ - -const fs = require('fs-extra') -const path = require('path') -const chalk = require('chalk') -const execa = require('execa') -const { - targetAssets: allTargets, - fuzzyMatchTarget, - checkFileSize, -} = require('./utils') - -const args = require('minimist')(process.argv.slice(2)) -const targets = args._ -const devOnly = args.devOnly || args.d -// const sourceMap = args.sourcemap || args.s -const isRelease = args.release -const buildAllMatching = args.all || args.a -const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) - -run() - -async function run() { - if (isRelease) { - // remove build cache for release builds to avoid outdated enum values - await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) - } - if (!targets.length) { - await buildAll(allTargets) - // checkAllSizes(allTargets) - } else { - await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - // checkAllSizes(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) - } -} - -async function buildAll(targets) { - await runParallel(require('os').cpus().length, targets, build) -} - -async function runParallel(maxConcurrency, source, iteratorFn) { - const ret = [] - const executing = [] - for (const item of source) { - const p = Promise.resolve().then(() => iteratorFn(item, source)) - ret.push(p) - - if (maxConcurrency <= source.length) { - const e = p.then(() => executing.splice(executing.indexOf(e), 1)) - executing.push(e) - if (executing.length >= maxConcurrency) { - await Promise.race(executing) - } - } - } - return Promise.all(ret) -} - -async function build(target) { - const rootDir = path.resolve(__dirname, '..') - const pkgDir = path.resolve(rootDir, `packages/${target}`) - const assetsConfig = require(path.resolve(pkgDir, 'assets.config.json')) - - if (assetsConfig.css) { - console.log(chalk.cyan(`Waiting for changes...`)) - assetsConfig.css.forEach((css) => { - const input = path.resolve(pkgDir, css.input) - const output = path.resolve(pkgDir, css.output) - const inputExt = path.extname(input) - - if (inputExt === '.styl' || inputExt === '.css') { - execa('stylus', ['-w', input, '-o', output]) - } else { - console.log(chalk.redBright(`File extention not supported: ${input}`)) - } - }) - } -} diff --git a/scripts/dev.js b/scripts/dev.js deleted file mode 100644 index 3d959f0e..00000000 --- a/scripts/dev.js +++ /dev/null @@ -1,44 +0,0 @@ -/* -Run Rollup in watch mode for development. - -To specific the package to watch, simply pass its name and the desired build -formats to watch (defaults to "global"): - -``` -# name supports fuzzy match. will watch all packages with name containing "dom" -npm run dev -- vue-quill - -# specify the format to output -npm run dev -- vue-quill --formats cjs - -# Can also drop all __DEV__ blocks with: -__DEV__=false npm run dev -``` -*/ - -const execa = require('execa') -const { fuzzyMatchTarget } = require('./utils') -const args = require('minimist')(process.argv.slice(2)) -const target = args._.length ? fuzzyMatchTarget(args._)[0] : 'vue-quill' -const formats = args.formats || args.f -const sourceMap = args.sourcemap || args.s -const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) - -execa( - 'rollup', - [ - '-wc', - '--environment', - [ - `COMMIT:${commit}`, - `TARGET:${target}`, - `FORMATS:${formats || 'global'}`, - sourceMap ? `SOURCE_MAP:true` : ``, - ] - .filter(Boolean) - .join(','), - ], - { - stdio: 'inherit', - } -) diff --git a/scripts/dev.ts b/scripts/dev.ts new file mode 100644 index 00000000..48d2fbac --- /dev/null +++ b/scripts/dev.ts @@ -0,0 +1,47 @@ +/* +Run Rollup in watch mode for development. + +To specific the package to watch, simply pass its name and the desired build +formats to watch (defaults to "global"): + +``` +# name supports fuzzy match. will watch all packages with name containing "dom" +npm run dev -- vue-quill + +# specify the format to output +npm run dev -- vue-quill --formats cjs + +# Can also drop all __DEV__ blocks with: +__DEV__=false npm run dev +``` +*/ +(() => { + const execa = require('execa') + const { fuzzyMatchTarget } = require('./utils') + + const args = require('minimist')(process.argv.slice(2)) + console.log(args) + const target: string = args._.length ? fuzzyMatchTarget(args._)[0] : 'vue-quill' + const formats: string[] = args.formats || args.f + const sourceMap: boolean = args.sourcemap || args.s + const commit = execa.sync('git', ['rev-parse', 'HEAD']).stdout.slice(0, 7) + + execa( + 'rollup', + [ + '-wc', + '--environment', + [ + `COMMIT:${commit}`, + `TARGET:${target}`, + `FORMATS:${formats || 'global'}`, + sourceMap ? `SOURCE_MAP:true` : ``, + ] + .filter(Boolean) + .join(','), + ], + { + stdio: 'inherit', + } + ) +})() diff --git a/scripts/devAssets.ts b/scripts/devAssets.ts new file mode 100644 index 00000000..5211d157 --- /dev/null +++ b/scripts/devAssets.ts @@ -0,0 +1,65 @@ +/* +Produces development assets files. +To specify the package to build, simply pass its name + +``` +# name supports fuzzy match. will build all packages with name containing "vue-quill": +npm run assets:build -- vue-quill +``` +*/ +(() => { + const fs = require('fs-extra') + const path = require('path') + const chalk = require('chalk') + const execa = require('execa') + const { + targetAssets: allTargets, + fuzzyMatchTarget, + runParallel + } = require('./utils') + + const args = require('minimist')(process.argv.slice(2)) + const targets: string[] = args._ + // const sourceMap = args.sourcemap || args.s + const isRelease: boolean = args.release + const buildAllMatching: string[] = args.all || args.a + + run() + + async function run() { + if (isRelease) { + // remove build cache for release builds to avoid outdated enum values + await fs.remove(path.resolve(__dirname, '../node_modules/.rts2_cache')) + } + if (!targets.length) { + await buildAll(allTargets) + } else { + await buildAll(fuzzyMatchTarget(targets, buildAllMatching, allTargets)) + } + } + + async function buildAll(targets: string[]) { + await runParallel(require('os').cpus().length, targets, build) + } + + async function build(target: string) { + const rootDir = path.resolve(__dirname, '..') + const pkgDir = path.resolve(rootDir, `packages/${target}`) + const assets = require(path.resolve(pkgDir, 'assets.config.json')) + + if (assets.css) { + console.log(chalk.cyan(`Waiting for changes...`)) + assets.css.forEach((css: any) => { + const input = path.resolve(pkgDir, css.input) + const output = path.resolve(pkgDir, css.output) + const inputExt = path.extname(input) + + if (inputExt === '.styl' || inputExt === '.css') { + execa('stylus', ['-w', input, '-o', output]) + } else { + console.log(chalk.redBright(`File extention not supported: ${input}`)) + } + }) + } + } +})() diff --git a/scripts/release.js b/scripts/release.js deleted file mode 100644 index ee7c902d..00000000 --- a/scripts/release.js +++ /dev/null @@ -1,12 +0,0 @@ -const chalk = require('chalk') -const execa = require('execa') - -const args = require('minimist')(process.argv.slice(2)) -const targets = args._ - -if (process.env.CI && targets[0]) { - execa.sync('zip', ['-r', `${targets[0]}vue-quill-dist.zip`, '.', '-i', 'dist']) - execa.sync('npx', ['semantic-release']) -} else { - console.log(chalk.redBright("You can't run semantic-release locally")) -} diff --git a/scripts/release.ts b/scripts/release.ts new file mode 100644 index 00000000..921f2343 --- /dev/null +++ b/scripts/release.ts @@ -0,0 +1,14 @@ +(() => { + const chalk = require('chalk') + const execa = require('execa') + + const args = require('minimist')(process.argv.slice(2)) + const targets = args._ + + if (process.env.CI && targets[0]) { + execa.sync('zip', ['-r', `${targets[0]}-dist.zip`, '-i', 'dist']) + execa.sync('npx', ['semantic-release']) + } else { + console.log(chalk.redBright("You can't run semantic-release locally")) + } +})() \ No newline at end of file diff --git a/scripts/utils.js b/scripts/utils.ts similarity index 50% rename from scripts/utils.js rename to scripts/utils.ts index bb3703fb..da450977 100644 --- a/scripts/utils.js +++ b/scripts/utils.ts @@ -1,11 +1,11 @@ -const fs = require('fs') +const fs = require('fs-extra') const chalk = require('chalk') const path = require('path') const { gzipSync } = require('zlib') const { compress } = require('brotli') const packagesDir = path.resolve(__dirname, '../packages') -const targets = fs.readdirSync(packagesDir).filter((f) => { +const targets: string[] = fs.readdirSync(packagesDir).filter((f: string) => { const pkgDir = path.resolve(__dirname, '..', 'packages', f) if (!fs.statSync(pkgDir).isDirectory()) { return false @@ -21,7 +21,7 @@ const targets = fs.readdirSync(packagesDir).filter((f) => { return true }) -const targetAssets = fs.readdirSync(packagesDir).filter((f) => { +const targetAssets: string[] = fs.readdirSync(packagesDir).filter((f: string) => { const pkgDir = path.resolve(__dirname, '..', 'packages', f) if (!fs.statSync(pkgDir).isDirectory()) { return false @@ -30,16 +30,17 @@ const targetAssets = fs.readdirSync(packagesDir).filter((f) => { if (!fs.existsSync(pkgPath)) { return false } - const assetsConfig = require(pkgPath) - if (assetsConfig.private && !assetsConfig.css) { + const assets = require(pkgPath) + if (assets.private && !assets.css) { return false } return true }) -function fuzzyMatchTarget(partialTargets, includeAllMatching, targets) { - const matched = [] +function fuzzyMatchTarget(partialTargets: string[], includeAllMatching?: string[], targets?: string[]) { + const matched: string[] = [] partialTargets.forEach((partialTarget) => { + if (!targets) return for (const target of targets) { if (target.match(partialTarget)) { matched.push(target) @@ -64,15 +65,15 @@ function fuzzyMatchTarget(partialTargets, includeAllMatching, targets) { } } -async function runParallel(maxConcurrency, source, iteratorFn) { +async function runParallel(maxConcurrency: number, source: string[], iteratorFn: Function) { const ret = [] - const executing = [] + const executing: any[] = [] for (const item of source) { const p = Promise.resolve().then(() => iteratorFn(item, source)) ret.push(p) if (maxConcurrency <= source.length) { - const e = p.then(() => executing.splice(executing.indexOf(e), 1)) + const e: any = p.then(() => executing.splice(executing.indexOf(e), 1)) executing.push(e) if (executing.length >= maxConcurrency) { await Promise.race(executing) @@ -82,24 +83,24 @@ async function runParallel(maxConcurrency, source, iteratorFn) { return Promise.all(ret) } -function checkBuildSize(target) { +function checkBuildSize(target: string) { const pkgDir = path.resolve(`packages/${target}`) checkFileSize(`${pkgDir}/dist/${target}.global.prod.js`) } -function checkAssetsSize(target, ext = '.css') { +function checkAssetsSize(target: string, ext = '.css') { const pkgDir = path.resolve(`packages/${target}`) const distDir = path.resolve(pkgDir, 'dist') - fs.readdir(distDir, function (err, files) { + fs.readdir(distDir, function (err: string, files: string[]) { if (err) console.log(chalk.redBright('Unable to scan directory: ' + err)) - files.forEach((file) => { + files.forEach((file: string) => { if (file.includes(`prod${ext}`)) checkFileSize(path.resolve(distDir, file)) }) }) } -function checkFileSize(filePath) { +function checkFileSize(filePath: string) { if (!fs.existsSync(filePath)) { return } @@ -116,6 +117,60 @@ function checkFileSize(filePath) { ) } +async function generateTypes(target: string) { + const pkgDir = path.resolve(__dirname, `../packages/${target}`) + console.log() + console.log( + chalk.bold(chalk.yellow(`Rolling up type definitions for ${target}...`)) + ) + + // build types + const { Extractor, ExtractorConfig } = require('@microsoft/api-extractor') + const extractorConfigPath = path.resolve(pkgDir, `api-extractor.json`) + const extractorConfig = ExtractorConfig.loadFileAndPrepare( + extractorConfigPath + ) + const extractorResult = Extractor.invoke(extractorConfig, { + localBuild: true, + showVerboseMessages: true, + }) + + if (extractorResult.succeeded) { + // concat additional d.ts to rolled-up dts + const pkg = require(`${pkgDir}/package.json`) + try { + const typesDir = path.resolve(pkgDir, 'types') + await fs.promises.access(typesDir).then(async () => { + const dtsPath = path.resolve(pkgDir, pkg.types) + const existing = await fs.readFile(dtsPath, 'utf-8') + const typeFiles = await fs.readdir(typesDir) + const toAdd = await Promise.all( + typeFiles.map((file: string) => { + return fs.readFile(path.resolve(typesDir, file), 'utf-8') + }) + ) + await fs.writeFile(dtsPath, existing + '\n' + toAdd.join('\n')) + }) + console.log( + chalk.bold(chalk.green(`API Extractor completed successfully.`)) + ) + } catch (err) { + console.log() + console.log( + chalk.yellow(`There's no additional .d.ts to roll-up with ${err}`) + ) + } + } else { + console.error( + `API Extractor completed with ${extractorResult.errorCount} errors` + + ` and ${extractorResult.warningCount} warnings` + ) + process.exitCode = 1 + } + + await fs.remove(`${pkgDir}/dist/packages`) +} + module.exports = { targets, targetAssets, @@ -124,4 +179,5 @@ module.exports = { checkBuildSize, checkAssetsSize, checkFileSize, + generateTypes }