[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);
相關文章
相關標籤/搜索