[internal] chore(pkg): use async and hooks (#4435)

[skip release]
This commit is contained in:
Pooya Parsa 2018-11-27 19:02:00 +03:30 committed by GitHub
parent 7cf9f80c14
commit 74d3bdcafb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 110 additions and 87 deletions

View File

@ -1,11 +1,11 @@
export default { export default {
build: false, build: false,
extend(pkg, { load }) { hooks: {
pkg.on('build:done', () => { async 'build:done'(pkg) {
const mono = load('../..') const mono = pkg.load('../..')
const nuxt = load('../nuxt') const nuxt = pkg.load('../nuxt')
pkg.copyFilesFrom(mono, [ await pkg.copyFilesFrom(mono, [
'LICENSE' 'LICENSE'
]) ])
@ -17,7 +17,7 @@ export default {
'collective' 'collective'
]) ])
pkg.writePackage() await pkg.writePackage()
}) }
} }
} }

View File

@ -1,11 +1,11 @@
export default { export default {
build: true, build: true,
extend(pkg, { load }) { hooks: {
pkg.on('build:done', () => { async 'build:done'(pkg) {
const mono = load('../..') const mono = pkg.load('../..')
const nuxt = load('../nuxt') const nuxt = pkg.load('../nuxt')
pkg.copyFilesFrom(mono, [ await pkg.copyFilesFrom(mono, [
'LICENSE' 'LICENSE'
]) ])
@ -17,7 +17,7 @@ export default {
'engines' 'engines'
]) ])
pkg.writePackage() await pkg.writePackage()
}) }
} }
} }

View File

@ -1,13 +1,13 @@
export default { export default {
build: true, build: true,
extend(pkg, { load }) { hooks: {
pkg.on('build:done', () => { async 'build:done'(pkg) {
const mono = load('../..') const mono = pkg.load('../..')
pkg.copyFilesFrom(mono, [ await pkg.copyFilesFrom(mono, [
'LICENSE', 'LICENSE',
'README.md' 'README.md'
]) ])
}) }
} }
} }

View File

@ -28,7 +28,7 @@ module.exports = _require('../src/index')
async function main() { async function main() {
// Read package at current directory // Read package at current directory
const rootPackage = new Package() const rootPackage = new Package()
const workspacePackages = rootPackage.getWorkspacePackages() const workspacePackages = await rootPackage.getWorkspacePackages()
// Create a dev-only entrypoint to the src // Create a dev-only entrypoint to the src
for (const pkg of workspacePackages) { for (const pkg of workspacePackages) {

View File

@ -7,7 +7,7 @@ import Package from './package.js'
async function main() { async function main() {
// Read package at current directory // Read package at current directory
const rootPackage = new Package() const rootPackage = new Package()
const workspacePackages = rootPackage.getWorkspacePackages() const workspacePackages = await rootPackage.getWorkspacePackages()
const watch = process.argv.includes('--watch') const watch = process.argv.includes('--watch')

View File

@ -1,11 +1,11 @@
import { resolve } from 'path' import { resolve } from 'path'
import EventEmitter from 'events'
import consola from 'consola' import consola from 'consola'
import { sync as spawnSync } from 'cross-spawn' import { spawn } from 'cross-spawn'
import { existsSync, readJSONSync, writeFileSync, copySync, removeSync } from 'fs-extra' import { existsSync, readJSONSync, writeFile, copy, remove } from 'fs-extra'
import _ from 'lodash' import _ from 'lodash'
import { rollup, watch } from 'rollup' import { rollup, watch } from 'rollup'
import glob from 'glob' import { glob as _glob } from 'glob'
import pify from 'pify'
import sortPackageJson from 'sort-package-json' import sortPackageJson from 'sort-package-json'
import rollupConfig from './rollup.config' import rollupConfig from './rollup.config'
@ -16,27 +16,31 @@ const DEFAULTS = {
configPath: 'package.js', configPath: 'package.js',
distDir: 'dist', distDir: 'dist',
build: false, build: false,
suffix: process.env.PACKAGE_SUFFIX ? `-${process.env.PACKAGE_SUFFIX}` : '' suffix: process.env.PACKAGE_SUFFIX ? `-${process.env.PACKAGE_SUFFIX}` : '',
hooks: {}
} }
const glob = pify(_glob)
const sortObjectKeys = obj => _(obj).toPairs().sortBy(0).fromPairs().value() const sortObjectKeys = obj => _(obj).toPairs().sortBy(0).fromPairs().value()
export default class Package extends EventEmitter { export default class Package {
constructor(options) { constructor(options) {
super()
// Assign options // Assign options
this.options = Object.assign({}, DEFAULTS, options) this.options = Object.assign({}, DEFAULTS, options)
// Initialize // Basic logger
this.init() this.logger = consola
// Init (sync)
this._init()
} }
init() { _init() {
// Try to read package.json // Try to read package.json
this.readPkg() this.readPkg()
// Init logger // Use tagged logger
this.logger = consola.withTag(this.pkg.name) this.logger = consola.withTag(this.pkg.name)
// Try to load config // Try to load config
@ -59,24 +63,38 @@ export default class Package extends EventEmitter {
config = config.default || config config = config.default || config
Object.assign(this.options, config) Object.assign(this.options, config)
}
}
if (typeof config.extend === 'function') { async callHook(name, ...args) {
config.extend(this, { let fns = this.options.hooks[name]
load: (relativePath, opts) => new Package(Object.assign({
if (!fns) {
return
}
if (!Array.isArray(fns)) {
fns = [fns]
}
for (const fn of fns) {
await fn(this, ...args)
}
}
load(relativePath, opts) {
return new Package(Object.assign({
rootDir: this.resolvePath(relativePath) rootDir: this.resolvePath(relativePath)
}, opts)) }, opts))
})
}
}
} }
writePackage() { async writePackage() {
if (this.options.sortDependencies) { if (this.options.sortDependencies) {
this.sortDependencies() await this.sortDependencies()
} }
const pkgPath = this.resolvePath(this.options.pkgPath) const pkgPath = this.resolvePath(this.options.pkgPath)
this.logger.debug('Writing', pkgPath) this.logger.debug('Writing', pkgPath)
writeFileSync(pkgPath, JSON.stringify(this.pkg, null, 2) + '\n') await writeFile(pkgPath, JSON.stringify(this.pkg, null, 2) + '\n')
} }
generateVersion() { generateVersion() {
@ -147,11 +165,11 @@ export default class Package extends EventEmitter {
} }
} }
getWorkspacePackages() { async getWorkspacePackages() {
const packages = [] const packages = []
for (const workspace of this.pkg.workspaces || []) { for (const workspace of this.pkg.workspaces || []) {
const dirs = glob.sync(workspace) const dirs = await glob(workspace)
for (const dir of dirs) { for (const dir of dirs) {
const pkg = new Package({ const pkg = new Package({
rootDir: this.resolvePath(dir) rootDir: this.resolvePath(dir)
@ -163,36 +181,37 @@ export default class Package extends EventEmitter {
return packages return packages
} }
async build(options = {}, _watch = false) { async build(_watch = false) {
this.emit('build:before') // Prepare rollup config
const config = {
// Extend options rootDir: this.options.rootDir,
const replace = Object.assign({}, options.replace) alias: {},
const alias = Object.assign({}, options.alias) replace: {}
}
// Replace linkedDependencies with their suffixed version // Replace linkedDependencies with their suffixed version
if (this.options.suffix && this.options.suffix.length) { if (this.options.suffix && this.options.suffix.length) {
for (const _name of (this.options.linkedDependencies || [])) { for (const _name of (this.options.linkedDependencies || [])) {
const name = _name + this.options.suffix const name = _name + this.options.suffix
if (replace[`'${_name}'`] === undefined) { config.replace[`'${_name}'`] = `'${name}'`
replace[`'${_name}'`] = `'${name}'` config.alias[_name] = name
}
if (alias[_name] === undefined) {
alias[_name] = name
}
} }
} }
const config = rollupConfig({ // Allow extending config
rootDir: this.options.rootDir, await this.callHook('build:extend', { config })
...options,
replace, // Create rollup config
alias const _rollupConfig = rollupConfig(config, this.pkg)
}, this.pkg)
// Allow extending rollup config
await this.callHook('build:extendRollup', {
rollupConfig: _rollupConfig
})
if (_watch) { if (_watch) {
// Watch // Watch
const watcher = watch(config) const watcher = watch(_rollupConfig)
watcher.on('event', (event) => { watcher.on('event', (event) => {
switch (event.code) { switch (event.code) {
// The watcher is (re)starting // The watcher is (re)starting
@ -223,11 +242,12 @@ export default class Package extends EventEmitter {
// Build // Build
this.logger.info('Building bundle') this.logger.info('Building bundle')
try { try {
const bundle = await rollup(config) const bundle = await rollup(_rollupConfig)
removeSync(config.output.dir) await remove(_rollupConfig.output.dir)
await bundle.write(config.output) await bundle.write(_rollupConfig.output)
this.logger.success('Bundle built') this.logger.success('Bundle built')
this.emit('build:done') await this.callHook('build:done', { bundle })
// Analyze bundle imports against pkg // Analyze bundle imports against pkg
// if (this.pkg.dependencies) { // if (this.pkg.dependencies) {
@ -249,13 +269,13 @@ export default class Package extends EventEmitter {
} }
} }
watch(options) { watch() {
return this.build(options, true) return this.build(true)
} }
publish(tag = 'latest') { async publish(tag = 'latest') {
this.logger.info(`publishing ${this.pkg.name}@${this.pkg.version} with tag ${tag}`) this.logger.info(`publishing ${this.pkg.name}@${this.pkg.version} with tag ${tag}`)
this.exec('npm', `publish --tag ${tag}`) await this.exec('npm', `publish --tag ${tag}`)
} }
copyFieldsFrom(source, fields = []) { copyFieldsFrom(source, fields = []) {
@ -264,11 +284,11 @@ export default class Package extends EventEmitter {
} }
} }
copyFilesFrom(source, files) { async copyFilesFrom(source, files) {
for (const file of files || source.pkg.files || []) { for (const file of files || source.pkg.files || []) {
const src = resolve(source.options.rootDir, file) const src = resolve(source.options.rootDir, file)
const dst = resolve(this.options.rootDir, file) const dst = resolve(this.options.rootDir, file)
copySync(src, dst) await copy(src, dst)
} }
} }
@ -287,8 +307,8 @@ export default class Package extends EventEmitter {
} }
} }
exec(command, args, silent = false) { async exec(command, args, silent = false) {
const r = spawnSync(command, args.split(' '), { cwd: this.options.rootDir }, { env: process.env }) const r = await spawn(command, args.split(' '), { cwd: this.options.rootDir }, { env: process.env })
if (!silent) { if (!silent) {
const fullCommand = command + ' ' + args const fullCommand = command + ' ' + args
@ -313,11 +333,13 @@ export default class Package extends EventEmitter {
} }
} }
gitShortCommit() { async gitShortCommit() {
return this.exec('git', 'rev-parse --short HEAD', true).stdout const { stdout } = await this.exec('git', 'rev-parse --short HEAD', true)
return stdout
} }
gitBranch() { async gitBranch() {
return this.exec('git', 'rev-parse --abbrev-ref HEAD', true).stdout const { stdout } = await this.exec('git', 'rev-parse --abbrev-ref HEAD', true)
return stdout
} }
} }

View File

@ -16,6 +16,11 @@ export default function rollupConfig({
input = 'src/index.js', input = 'src/index.js',
replace = {}, replace = {},
alias = {}, alias = {},
resolve = {
only: [
/lodash/
]
},
...options ...options
}, pkg) { }, pkg) {
if (!pkg) { if (!pkg) {
@ -46,11 +51,7 @@ export default function rollupConfig({
...replace ...replace
} }
}), }),
nodeResolvePlugin({ nodeResolvePlugin(resolve),
only: [
/lodash/
]
}),
commonjsPlugin(), commonjsPlugin(),
jsonPlugin(), jsonPlugin(),
licensePlugin({ licensePlugin({