Using PicGo in Node.js
Using PicGo in an existing Node.js project is straightforward. Point PicGo to a config file (or let it use the default one), and call upload once your configuration is valid.
Note
To support the local plugin system, PicGo only works in a Node.js environment (including the Electron main process). It does not support browser environments.
Initialization
If you need to initialize PicGo with a custom config file, see Configuration. Note that initialization differs across versions.
Use the default config file
Since v1.5.0+
// since v1.5.0
// CommonJS
const { PicGo } = require('picgo')
// or ES modules
import { PicGo } from 'picgo'
const picgo = new PicGo() // <- Uses the default config fileBefore v1.5.0
// before v1.5.0
const PicGo = require('picgo')
const picgo = new PicGo() // <- Uses the default config fileUse a custom config file
Since v1.5.0+
// since v1.5.0
// CommonJS
const { PicGo } = require('picgo')
// or es6
import { PicGo } from 'picgo'
const picgo = new PicGo('/xxx/xxx.json') // <- Pass the config file path when constructingBefore v1.5.0
// before v1.5.0
const PicGo = require('picgo')
const picgo = new PicGo('/xxx/xxx.json') // <- Pass the config file path when constructingUpload
const main = async () => {
const res = await picgo.upload(['/xxx/xxx.jpg']) // <- Always pass an array, even if you only upload one image
// Since 1.4.21 you can get the upload output
console.log(res) // ['https:/xxx.com/xxx.jpg']
}Event listeners
During the upload lifecycle, PicGo emits several events and passes useful parameters to event handlers.
If you need a refresher on the lifecycle diagram, see Overview.
uploadProgress
- Parameter:
Number - Description: upload progress. You can use it to drive a progress bar. Possible values are
0,30,60,100, and-1.-1means upload failed;100means upload succeeded.
picgo.on('uploadProgress', progress => {
console.log(progress)
})beforeTransform
- Parameter:
ctx - Description: fired before the input enters the transformer. You can read the input via
ctx.input.
picgo.on('beforeTransform', ctx => {
console.log(ctx.input) // ['/xxx/xxx.jpg']
})beforeUpload
- Parameter:
ctx - Description: fired before the output enters the uploader. You can read the output after the transformer via
ctx.output.
picgo.on('beforeUpload', ctx => {
console.log(ctx.output) // [{ base64Image, fileName, width, height, extname }]
})afterUpload
- Parameter:
ctx - Description: fired after the uploader successfully uploads. You can read the output after the uploader via
ctx.output.
picgo.on('afterUpload', ctx => {
console.log(ctx.output) // [{fileName, width, height, extname, imgUrl}] <- Note that imgUrl is now included.
})finished
- Parameter:
ctx - Description: fired after the uploader succeeds and after
afterUploadPluginshave run. Use it to get the final output.
picgo.on('finished', ctx => {
console.log(ctx.output) // [{fileName, width, height, extname, imgUrl}] <- Note that imgUrl is now included.
})failed
- Parameter:
error - Description: fired when an upload fails or an error is thrown during the lifecycle. You can catch the error here. (Before v1.2.10 you couldn’t get the error details, but you could still listen to this event.)
picgo.on('failed', error => {
console.log(error) // error message
})notification
- Parameter:
notice - Description: upload failure notifications emitted by an uploader. Listen to this to show user-facing messages.
picgo.on('notification', notice => {
console.log(notice) // { title, body, text? }
})title and body are always present. text is optional extra information (for example, a URL where the user can look up an error code) and can be undefined.
Lifecycle plugins
In addition to listening to lifecycle events, you can plug into those lifecycle stages to implement more advanced behaviors—for example, renaming files or compressing images in beforeUpload, or adding watermarks in beforeTransform.
PicGo exposes a helper object that contains plugin containers for the lifecycle stages. Register a plugin via register(). You register an object that must include a handle method, and PicGo will pass ctx into handle.
Note
Register your plugins before calling upload(), otherwise they won’t take effect.
helper.beforeTransformPlugins
Called after the
beforeTransformevent is emitted.
picgo.helper.beforeTransformPlugins.register('name', {
handle: function (ctx) {
console.log(ctx.input)
}
})
picgo.upload(['/xxx/xxx.jpg'])helper.beforeUploadPlugins
Called after the
beforeUploadevent is emitted.
picgo.helper.beforeUploadPlugins.register('name', {
handle: function (ctx) {
console.log(ctx.output)
}
})
picgo.upload(['/xxx/xxx.jpg'])helper.afterUploadPlugins
Called after
afterUploadis emitted and beforefinished.
picgo.helper.afterUploadPlugins.register('name', {
handle: function (ctx) {
console.log(ctx.output)
}
})
picgo.upload(['/xxx/xxx.jpg'])If you want to build more advanced features (plugin-specific configuration, naming your plugin, publishing it for others), see Plugin Development.
Logging 1.3.7+
PicGo’s logger module supports persistent log writing. You can call picgo.log.xxx to write logs, where xxx can be success, warn, info, or error.
Logger calls create a picgo.log file next to your PicGo config file, and the same logs are also printed to the console.
Example:
2019-04-18 13:52:58 [PicGo INFO] Before transform
2019-04-18 13:52:58 [PicGo INFO] Transforming...
2019-04-18 13:52:58 [PicGo INFO] Before upload
2019-04-18 13:52:58 [PicGo INFO] Uploading...
2019-04-18 13:53:01 [PicGo SUCCESS]
https://xxxx.pngLoading third-party plugins 1.4.19+
- Since 1.4.19, PicGo exposes
pluginHandlerandpluginLoaderfor working with third-party plugins. - Since 1.5.0, PicGo also exposes
use()to make manual plugin loading easier.
In short:
pluginHandler: install/update/uninstall plugins via npm.pluginLoader: dynamically register/get/unregister plugins at runtime.
Both can be used to bring in plugins, but they differ:
pluginHandleruses npm to install/uninstall plugins. This is persistent—after restarting PicGo, installed plugins are auto-loaded.pluginLoaderis for dynamic runtime loading, useful when you need to load different plugins on the fly.
use 1.5.0+
- (plugin: IPicGoPlugin, name?: string): IPicGoPluginInterface
Manually load a third-party plugin. If the second parameter name is omitted, PicGo will instantiate the plugin without registering it into PicGo’s plugin list—this is handy for dynamic loading. Example:
const { PicGo } = require('picgo')
const PluginMigrater = require('picgo-plugin-pic-migrater')
const MinioUploader = require('picgo-plugin-minio')
const picgo = new PicGo()
const plugin = picgo.use(PluginMigrater) // will not register this plugin, just use it
picgo.use(MinioUploader, 'minio') // will register this plugin
picgo.setConfig({
'picgo-plugin-pic-migrater': {
newFileSuffix: '_new',
include: '',
exclude: ''
},
picBed: {
current: 'minio',
uploader: 'minio',
minio: {
endpoint: 'http://localhost:9000',
accessKey: 'minioadmin',
secretKey: 'minioadmin',
bucket: 'picgo',
path: '/',
useSSL: false
}
}
})
// will use minio for migrating
plugin.migrateFiles(['/xxx/yyy.md']) // { total: number, success: number }pluginHandler
- install([...pluginName]): Promise<IPluginHandlerResult>
- update([...pluginName]): Promise<IPluginHandlerResult>
- uninstall([...pluginName]): Promise<IPluginHandlerResult>
PicGo exposes three methods corresponding to npm install, npm update, and npm uninstall.
All three methods accept an array. pluginName can be:
- The full package name, e.g.
picgo-plugin-xxx. - The short name, e.g.
xxx. - A scoped package, e.g.
@xxx/picgo-plugin-yyy. - A local path, e.g.
./xxx/yyy/picgo-plugin-zzz.
The result indicates whether the operation succeeded. Example:
const main = async () => {
const res = await picgo.pluginHandler.install(['xxx'])
if (res.success) {
console.log(res.body) // ['picgo-plugin-xxx']
} else {
console.log(res.body) // error message
}
}See api-pluginHandler for details.
pluginLoader
- registerPlugin(pluginName, plugin): register a plugin dynamically
- unregisterPlugin(pluginName): unregister a plugin dynamically
- getPlugin(pluginName): get a plugin
- hasPlugin(pluginName): check whether a plugin exists
Example:
const pluginXXX = require('picgo-plugin-xxx')
console.log(picgo.pluginLoader.hasPlugin('xxx')) // false
// Note: pluginName must be unique
picgo.pluginLoader.registerPlugin('xxx', pluginXXX)
console.log(picgo.pluginLoader.hasPlugin('xxx')) // trueSee api-pluginLoader for details.
Notes for bundling with Webpack
If you want to integrate PicGo into a Node.js project bundled by webpack (for example, an Electron project), you may see errors like Can't find module "." during bundling. This happens because webpack can’t reliably handle PicGo’s dynamic require() for plugins.
For PicGo, dynamically loaded plugins do not need to be bundled, because PicGo loads them at runtime rather than at build time. You can work around this by bypassing webpack’s require:
const requireFunc = typeof __webpack_require__ === 'function' ? __non_webpack_require__ : require
const PicGo = requireFunc('picgo')
const picgo = new PicGo()For more background, see this issue。
