npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

upload-webpack-plugin

v2.0.0

Published

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

Downloads

22

Readme

npm node deps cover size vulnerability

使用 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[]}|[]|除了指定类型|名称的文件,都上传,与include互斥,级别比include高 |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