[Vue CLI 3] 插件开发中的 genCacheConfig 细节研究

@vue/cli-plugin-babel/index.js 中:vue

api.genCacheConfig('babel-loader', {}, [])

咱们看一下 api.genCacheConfig 在文件:@vue/cli-service/lib/PluginAPI.js 中被定义:node

Generate a cache identifier from a number of variables

在函数一开始接受 3 个参数:webpack

  • id
  • partialIdentifier
  • configFiles

而后看一下函数的内部:web

返回:api

  • cacheIdentifier
  • cacheDirectory
genCacheConfig (id, partialIdentifier, configFiles) {
  const cacheDirectory = this.resolve(`node_modules/.cache/${id}`)
  const variables = {}
  const cacheIdentifier = hash(variables)
  return { cacheDirectory, cacheIdentifier }
}

咱们打印了 cacheDirectory 目录,发现一个目录地址:babel

/Users/***/node_modules/.cache

我本地的有 4 个文件夹:ide

  • babel-loader
  • uglifyjs-webpack-plugin
  • eslint-loader
  • vue-loader

咱们上面 cli-plugin-babel 就是指向了 babel-loader 的目录:函数

上面的 hash 用到了:ui

const hash = require('hash-sum')
/Users/***/node_modules/.cache/babel-loader

首先,babel-loader 是不具有去一个 .cache 目录写入文件的,那究竟是谁呢?this

还记得咱们以前经过 vue inspect --rule js 打印的 babelwebpack 配置吗?

/* config.module.rule('js') */
{
  test: /\.jsx?$/,
  exclude: [
    function () { /* omitted long function */ }
  ],
  use: [
    /* config.module.rule('js').use('cache-loader') */
    {
      loader: 'cache-loader',
      options: {
        cacheDirectory: '/Users/***/node_modules/.cache/babel-loader',
        cacheIdentifier: '2f4347b9'
      }
    },
    /* config.module.rule('js').use('babel-loader') */
    {
      loader: 'babel-loader'
    }
  ]
}

这里面的 use 配置在 babel-loader 以前配置了一个 cache-loader

{
  loader: 'cache-loader',
  options: {
    cacheDirectory: '/Users/***/node_modules/.cache/babel-loader',
    cacheIdentifier: '2f4347b9'
  }
}

cache-loader 到底作什么的呢:

Caches the result of following loaders on disk (default) or in the database

它的使用中有一个示例:

Add this loader in front of other (expensive) loaders to cache the result on disk.

通常它会放置在 use 配置里面,并且是其余 loaders 的前面:

module.exports = {
  module: {
    rules: [
      {
        test: /\.ext$/,
        use: [
          'cache-loader',
          ...loaders
        ],
        include: path.resolve('src')
      }
    ]
  }
}

那其实结果就很清晰了,写文件的就是它:

一开始经过 Set 来建立一个 对象,后面还使用了 addhas
var directories = new Set();

它有一个函数 write,接受 3 个参数:

  • key
  • data
  • callback
function write(key, data, callback) {
  var dirname = path.dirname(key);
  var content = JSON.stringify(data);

  if (directories.has(dirname)) {
    // for performance skip creating directory
    fs.writeFile(key, content, 'utf-8', callback);
  } else {
    mkdirp(dirname, function (mkdirErr) {
      if (mkdirErr) {
        callback(mkdirErr);
        return;
      }

      directories.add(dirname);

      fs.writeFile(key, content, 'utf-8', callback);
    });
  }
}

这里建立目录用到了:mkdirp 来建立目录

var mkdirp = require('mkdirp');

而后经过 fs.writeFile 来写文件

var fs = require('fs');
fs.writeFile(key, content, 'utf-8', callback);
相关文章
相关标签/搜索