# webpack 自定义plugin
## Plugin是如何被注册到 webpack 的生命周期中的:
1. 在webpack函数的 createCompiler 方法中,注册了所有插件
2. 在注册插件时,会调用插件函数或者插件对象的 apply 方法
3. 插件方法会接收 compiler 对象,我们可以通过 compiler 对象来注册Hook事件
4. 某些插件也会传入一个 compilation 对象,我们也可以监听 compilation 的 HOOK 事件
## 自定义一个每次打包完自动上传代码到服务器的插件:AutoUploadPlugin
1. 在根目录新建plugins文件夹,在里面新建 AutoUploadPlugin.js
需要借助 node-ssh 来连接服务器,安装:`npm install node-ssh -D`
```
const { NodeSSH } = require('node-ssh')
class AutoUploadPlugin {
// 通过构造函数来接收插件参数,并实例化ssh
constructor(options){
this.ssh = new NodeSSH()
this.options = options
}
// 实现apply
apply(compiler){
// 监听钩子,afterEmit 为打包资源被输出到打包目录后的 hook
compiler.hooks.afterEmit.tapAsync('AutoUploadPlugin', async (compilation, callback) => {
// 上传文件到服务器操作步骤
// 1.获取输出文件夹
const outputPath = compilation.outputOptions.path
// 2.用 node-ssh 库来连接服务器(ssh连接)
await this.connectServer()
// 3.删除服务器上文件夹内的内容
const serverDir = this.options.remotePath
await this.ssh.execCommand(`rm -rf ${serverDir}/*`)
// 4.上传文件到服务器(ssh连接)
await this.uploadFiles(outputPath, serverDir)
// 5.关闭SSH
this.ssh.dispose()
callback()
})
}
// 封装连接
async connectServer(){
await this.ssh.connect({
host: this.options.host,
username: this.options.username,
password: this.options.password
})
console.log('服务器连接成功!')
}
// 封装上传文件
async uploadFiles(localPath, remotePath){
const status = await this.ssh.putDirectory(localPath, remotePath, {
recursive: true, // 递归上传
concurrency: 10, // 并发数
})
console.log('上传', status ? '成功!' : '失败!')
}
}
module.exports = AutoUploadPlugin
```
2. webpack 引入并使用刚才的插件
```
// 引入自定义的插件
const AutoUploadPlugin = require('./plugins/AutoUploadPlugin.js')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './src/main.js',
output: {
path: path.resolve(__dirname, './build'),
filename: 'bundle.js'
},
plugins: [
new HtmlWebpackPlugin(),
// 使用自定义的插件,并且将参数传递过去
new AutoUploadPlugin({
host: '127.0.0.0',
username: 'root',
password: 'root123456',
remotePath: '/www/wwwroot/test'
})
]
}
```