upload-webpack-plugin

2.0.0 • Public • Published

npm node deps cover size vulnerability

upload-webpack-plugin

A plugin for webpack which uploads file to the remote server before the files are emitted.

开始使用

使用 npm:

$ npm install upload-webpack-plugin --save-dev

使用 yarn:

$ yarn add upload-webpack-plugin --dev

然后在webpack配置文件内引入插件,提供上传函数,并根据实际情况,看是否返回上传后的地址,如:

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({ uploader }),
  ],
};

或者使用Promise的方式:

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {
  return new Promise(resolve => {

    // do some stuff

    resolve(`${cdnPrefix}/${filename}`);
  })
}

module.exports = {
  plugins: [
    new UploadPlugin({ uploader }),
  ],
};

ℹ️ 在不需要替换cssjshtml内引用的已上传的文件的链接时,可以不用返回或者返回undefined

ℹ️ 使用Promise的方式时,会等待上传结果返回后,才会继续打包流程,记得最后一定要调用resolve(值可为空)。

选项

插件启用所有值的选项签名如下:

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
        enable: true,
        muteLog: false,
        gather: false,
        clean: [/.*\.((?!(html)).)+/],
        exclude: [/\.css$/, /\.js$/],
        include: ['index.html', /\.css$/, /\.js$/],
        replace: {
          typesWithOrder: ['.css', '.js', '.html'],
          useRealFilename: false,
        },
      } }),
  ],
};
名称 类型 默认值 描述
uploader {Function} null 默认上传函数
gather {Boolean} false 汇总上传,如果为true,会一次性提供所有生成的文件
enable {Boolean} true 是否启用插件
include {String[]|RegExp[]} [] 只上传指定`类型
exclude {String[]|RegExp[]} [] 除了指定`类型
clean {Boolean|String[]|RegExp[]} false 删除上传成功后的资源
muteLog {Boolean} false 禁止插件所有提示
replace.typesWithOrder {Array} ['.css', '.js', '.html'] 需要替换引用资源链接的文件类型和顺序
replace.useRealFilename {Boolean} false 替换引用资源链接时,使用真实文件名进行匹配

uploader

Type: Function Default: null

资源上传函数,也是唯一的必须提供的选项,如果只是单纯地获取资源进行上传,不需要返回任何值,如果需要根据不同文件类型定制不同的远程地址,可以返回指定值。

⚠️ 请务必提供上传函数,否则插件会静默失败并跳过调用过程

module.exports = {
  entry: {
    main: path.resolve(__dirname, 'src/index'),
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash:7].[contentHash:7].js',
    publicPath: 'https://cdn.lkangd.com/', // 默认的 publicPath
  },
  plugins: [
    new UploadWebpackPlugin({ uploader(source, name) => {

      // do some stuff

      return `https://cdn.custom.com/${name}`; // 需要与 output.output 区分的情况
    } }),
  ],
};

也可以使用Promise的方式。

module.exports = {
  entry: {
    main: path.resolve(__dirname, 'src/index'),
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash:7].[contentHash:7].js',
    publicPath: 'https://cdn.lkangd.com/', // 默认的 publicPath
  },
  plugins: [
    new UploadWebpackPlugin({ uploader(source, name) => {
      return new Promise(resolve => {

        // do some stuff

        setTimeout(() => { // 模拟上传时间 3 秒
          resolve(`https://cdn.custom.com/${name}`); // 需要与 output.output 区分的情况
        }, 3000);
      });

    } }),
  ],
};

gather

Type: Boolean Default: false

汇总上传,此时会将所有生成的资源一次性提供给uploader函数使用,uploader的第一个参数会变为形如{ foo: [source_of_foo], bar: [source_of_bar] }的对象。

上传完成后,根据实际情况返回形如{ foo: [remote_url_of_foo], bar: [remote_url_of_bar] }map对象。

⚠️ 返回值只接受原来存在的文件对应地址,其他值会静默过滤

webpack.config.js

module.exports = {
  entry: {
    main: path.resolve(__dirname, 'src/index'),
  },
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name].[chunkhash:7].[contentHash:7].js',
    publicPath: 'https://cdn.lkangd.com/', // 默认的 publicPath
  },
  plugins: [
    new UploadWebpackPlugin({ uploader(sourceMaps) => {
      const result = {};
      Object.keys(sourceMaps).forEach(localPath => {
        const file = sourceMaps[localPath];
        const remoteUrl = (function() { /** do some stuff */  })();
        result[localPath] = remoteUrl;
      })

      return result;
    }, options: {
      gather: true, // 设置 options.gather 为 true
    } }),
  ],
};

enable

Type: Boolean Default: true

插件总开关,可根据运行环境决定是否使用插件。

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
        enable: verdictProduction(), // 环境判断函数...
      } }),
  ],
};

include

Type: String[]|RegExp[] Default: []

只上传指定类型或指定文件名的文件,与exclude选项互斥,级别比exclude低。

⚠️ 选项值为空时不过滤任何文件。

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
        include: ['index.html', /\.css$/, /\.js$/], // 只上传文件名为'index.html'和类型为`css`、`js`的文件
      } }),
  ],
};

exclude

Type: String[]|RegExp[] Default: []

只上传指定类型或指定文件名的文件,与include选项互斥,级别比include高。

⚠️ 选项值为空时不过滤任何文件。

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
        include: ['index.html', /\.css$/, /\.js$/], // 因为同时提供了 exclude 选项,而且值有冲突,所以只会上传 'index.html'
        exclude: [/\.css$/, /\.js$/], // 只上传文件名为'index.html'和类型为`css`、`js`以外的文件
      } }),
  ],
};

clean

Type: Boolean|String[]|RegExp[] Default: false

删除即将生成的指定类型的文件。

⚠️ 选项值为true时,删除所有即将生成的文件,打包结束后本地将不会生成任何文件。

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
        clean: [/.*\.((?!(html)).)+/], // 删除除了 .html 后缀以外的所有文件
      } }),
  ],
};

replace.typesWithOrder

Type: Array Default: ['.css', '.js', '.html']

需要替换引用资源链接的文件类型和顺序,web 环境下的常规引用顺序分为下面几种情况:

  1. html引用js;
  2. html引用css;
  3. js引用css;

所以默认值['.css', '.js', '.html']代表的就是上面描述的情况。

⚠️ 因为webpack打包涉及动态加载chunk 的情况,而 chunk 之间可能存在依赖关系,所以'.css'和'.js'默认会进行替换。因此,当选项配置为['.html']时和默认值是对等的。

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
         replace: { typesWithOrder: [] }, // 数组为空时,html 类型文件内的所有资源引用将不会被返回的远程地址所替换
      } }),
  ],
};

replace.useRealFilename

Type: Boolean Default: false

替换引用资源链接时,使用真实文件名进行匹配。

⚠️ 当使用file-loaderurl-loader之类的插件时,可配置outputPath,如果这个值配置了和原始文件所在的目录不同的时候,比如原始文件foo.jpg的本地相对地址为/assets/foo.jpg,而相关 loader 的outputPath/image/时,foo.jpg在其它文件的引用地址为/image/foo.jpg,构建过程中插件拿到的是本地地址/assets/foo.jpg,所以会出现不替换的情况,因此请遵守以下要求:

  • 配置outputPath与原始路径不同时,设置replace.useRealFilename = true,并确保文件命名具有唯一辨识值,如:name: '[name].[contentHash:7].[ext]';
  • 配置命名方式为形如name: '[name].[ext]'等不具有唯一hash值时,请勿配置outputPath
  • 上面两个要求都是基于uploader函数有返回的情况下进行要求的;

⚠️ 建议使用file-loaderurl-loader之类的插件时不配置outputPath,并保持replace.useRealFilename为原始值false

webpack.config.js

const UploadPlugin = require('upload-webpack-plugin');
const uploader = (file, filename) => {

  // do some stuff

  return `${cdnPrefix}/${filename}`; // return the remote url of current asset is optional
}

module.exports = {
  module: {
    rules: [
      {
        test: /\.(zip|txt|ttf|woff)$/i,
        loader: 'file-loader',
        options: {
          name: '[name].[contentHash:7].[ext]',
          outputPath: 'others',
        },
      },
      {
        test: /\.(png|jpe?g|gif)$/i,
        loader: 'file-loader',
        options: {
          name: '[name].[contentHash:7].[ext]',
          outputPath: 'images',
        },
      },
    ],
  },
  plugins: [
    new UploadPlugin({
      uploader,
      options: {
         replace: { useRealFilename: true }, // 此时会对本地址路径为 /assets/foo.123456.jpg 的资源,使用 foo.123456.jpg 进行查找替换
      } }),
  ],
};

muteLog

Type: Boolean Default: false

禁止插件所有提示,为false会提示每个资源的上传情况。

bash / console

🌟 ✔ Upload complete 21/21
🌟 ✔ images/happy-boy.b85a8a2.gif is uploaded and it will be as https://custom.lkangd.com/images/happy-boy.b85a8a2.gif
🌟 ✔ others/example.d45b548.txt is uploaded and it will be as https://custom.lkangd.com/others/example.d45b548.txt
🌟 ✔ others/example.2f8a720.zip is uploaded and it will be as https://custom.lkangd.com/others/example.2f8a720.zip
🌟 ✔ others/dimmed.ff2b498.woff is uploaded and it will be as https://custom.lkangd.com/others/dimmed.ff2b498.woff
🌟 ✔ others/dimmed.424ed69.ttf is uploaded and it will be as https://custom.lkangd.com/others/dimmed.424ed69.ttf
🌟 ✔ static/favicon.ico is uploaded and it will be as https://custom.lkangd.com/static/favicon.ico
🌟 ✔ static/loading.gif is uploaded and it will be as https://custom.lkangd.com/static/loading.gif
🌟 ✔ static/static.jpg is uploaded and it will be as https://custom.lkangd.com/static/static.jpg
🌟 ✔ dynamicInDynamic.088e3a7.6879457.bundle.js is uploaded and it will be as https://custom.lkangd.com/dynamicInDynamic.088e3a7.6879457.bundle.js
🌟 ✔ dynamic.56ad341.bundle.css is uploaded and it will be as https://custom.lkangd.com/dynamic.56ad341.bundle.css
🌟 ✔ dynamic.56ad341.2a7837e.bundle.js is uploaded and it will be as https://custom.lkangd.com/dynamic.56ad341.2a7837e.bundle.js
🌟 ✔ dynamicSub.1e2a156.bundle.css is uploaded and it will be as https://custom.lkangd.com/dynamicSub.1e2a156.bundle.css
🌟 ✔ dynamicSub.1e2a156.2dce103.bundle.js is uploaded and it will be as https://custom.lkangd.com/dynamicSub.1e2a156.2dce103.bundle.js
🌟 ✔ manifest.6cf1b05.cb9796c.js is uploaded and it will be as https://custom.lkangd.com/manifest.6cf1b05.cb9796c.js
🌟 ✔ vendor.4752143.ae53a19.bundle.js is uploaded and it will be as https://custom.lkangd.com/vendor.4752143.ae53a19.bundle.js
🌟 ✔ common.cca58f5.bundle.css is uploaded and it will be as https://custom.lkangd.com/common.cca58f5.bundle.css
🌟 ✔ common.cca58f5.abae7d8.bundle.js is uploaded and it will be as https://custom.lkangd.com/common.cca58f5.abae7d8.bundle.js
🌟 ✔ main.dc19a08.564a3f0.bundle.js is uploaded and it will be as https://custom.lkangd.com/main.dc19a08.564a3f0.bundle.js
🌟 ✔ sub.7f0f75e.8dcdfd1.bundle.js is uploaded and it will be as https://custom.lkangd.com/sub.7f0f75e.8dcdfd1.bundle.js
🌟 ✔ sub.html is uploaded and it will be as https://custom.lkangd.com/sub.html
🌟 ✔ index.html is uploaded and it will be as https://custom.lkangd.com/index.html

License

MIT

Package Sidebar

Install

npm i upload-webpack-plugin

Weekly Downloads

5

Version

2.0.0

License

MIT

Unpacked Size

48.1 kB

Total Files

19

Last publish

Collaborators

  • lkangd