[Web] Explicação detalhada do plugin do webpack Ali icon (webpack-qc-iconfont-plugin)

webpack-qc-iconfont-plugin

O webpack-qc-iconfont-plugin é um plugin da webpack que pode ajudá-lo facilmente a baixar projetos de ícones Ali icon para o local

Intenção de desenvolvimento

  • A versão do gulp já havia sido lançada antes, mas na era da popularidade do webpack, ainda acho que a versão do plug-in do webpack ainda é muito necessária; portanto, durante o trabalho extra, finalmente percebi a versão do plug-in do webpack
  • Por que eu tenho que trabalhar horas extras? Como sou preguiçosa, não li a documentação oficial até o momento, por isso a base é muito ruim, por isso completei esse plug-in ainda mais no meio da noite, desculpe-me por ser preguiçosa , Adormeci ao ler o documento, não sei se existem alunos que compartilham o mesmo sentimento

Princípio de implementação

  • Tendo em vista a versão anterior do gulp, alguns alunos disseram que não podiam entender, então decidi explicar um princípio nesta versão.Não borrife, a garotinha acabou de compartilhar a experiência de aprendizado.

  • Para implementar este plug-in, você deve primeiro estudar o código css fornecido por Ali. Aqui eu forneço um //at.alicdn.com/t/font_1425510_3v068prmkkw.css para os grandes aprenderem.

  • Estude isso e você descobrirá que é realmente um arquivo css, apenas salve-o. Portanto, podemos iniciar uma solicitação para baixar o arquivo css para o local, o npm official fornece muitos pacotes de solicitações, qual solicitação / http / download ..., você pode escolher uma que você gosta.

  • Depois que a solicitação do arquivo for bem-sucedida, como queremos personalizar o prefixo e excluir algum código desnecessário, precisamos usar a regularização neste momento.Aqui é explicado pelo código-fonte do plug-in:

    let rawData = body;
    if (!isDev) rawData = rawData.replace(new RegExp(urlPrefix, 'g'), fontPath) // 当为生成环境时,将css中的在线url css地址替换为本地字体文件路径 fontPath
    var result = '/* 字体图标,来源路径:"' + url + '"*/ \r\n'; // 添加字体图标来源url注释,以便于快速定位样式来源
    var delUnnecessary = rawData.replace(/\.iconfont[\s\S]*?\}/, ''); // 利用正则删除 .iconfont { ... } 图标初始化代码
    var iconCss = delUnnecessary.match(/\.icon\-[\s\S]*?\}/g); // 利用正则匹配出所有 .icon-XXX { ... } 的图标样式代码
    var handlerData = keepIconFontStyle ? rawData : delUnnecessary; // 根据配置的 keepIconFontStyle 识别是否需要删除 .iconfont { ... } 图标初始化代码
    result += handlerData.replace(/\.icon\-[\s\S]*?\}/g, ''); // 利用正则删除原有的 .icon-XXX { ... } 的图标样式代码
    
    // 在循环匹配出的 iconCss 重新生成正确前缀的 .icon-XXX { ... } 的图标样式代码
    for (var i in iconCss) {
      var item = iconCss[i];
      if (iconPrefix) item = item.replace(/\.icon\-/, iconPrefix);
      result += item + '\r\n';
    }
    
    // 最后删除多余的空行
    result = result.replace(/\r{2,}/g, '\r');
    result = result.replace(/\n{2,}/g, '\n');
    
  • Dessa forma, a geração do arquivo css é concluída. Em seguida, é determinado se é necessário fazer o download do arquivo de ícone de fonte referenciado no css de acordo com o ambiente de desenvolvimento ou produção. Aqui, através da análise do arquivo css fornecido por Ali, o caminho do arquivo de ícone de fonte é encontrado da seguinte forma:

//at.alicdn.com/t/font_1425510_3v068prmkkw.eot
//at.alicdn.com/t/font_1425510_3v068prmkkw.woff
//at.alicdn.com/t/font_1425510_3v068prmkkw.woff2
//at.alicdn.com/t/font_1425510_3v068prmkkw.ttf
//at.alicdn.com/t/font_1425510_3v068prmkkw.svg

与提供的css文件比较:
//at.alicdn.com/t/font_1425510_3v068prmkkw.css
  • Após a comparação, verifica-se que o caminho do arquivo do ícone da fonte é apenas a extensão do arquivo css fornecido. Portanto, podemos escrever a extensão do ícone da fonte a ser baixada em uma matriz e usar o caminho do arquivo de solicitação recursiva para baixar o arquivo do ícone da fonte para o local

  • Finalmente, a versão do webpack possui um arquivo de modelo. Para fazer isso, precisamos injetar o arquivo css que geramos no arquivo de modelo. Aqui é explicado pelo código-fonte do plug-in:

    if (template) { // 判断 template 配置存在的时候进行注入
      compiler.hooks.emit.tap(pluginName, compilation => { // 注册webpack插件compiler emit hook
        for (var filename in compilation.assets) { // 循环 compilation.assets 准备输出的资源列表
          if (filename === template) { // 找到模板文件
            const htmlData = compilation.assets[filename].source() // 获取模板文件字符串数据
            if (!htmlData) return
    
            const headLinkCss = '<link rel="stylesheet" href="./' + cssName + '">' // 生成本地路径的 head link css标签
    
            // 询问该数据中已是否存在head link css标签,这里的判断是由于该插件代码会被先后执行两次,这需要你对webpack的compiler 与 compilation有初步的认识,compiler会在整个webpack生命周期中存在,而compilation是在每次编译时执行,因此前后会执行一次compiler 和 compilation,就是两次,因此未避免向生产环境注入两次head link css,我们需要进行过滤
            const findHeadLinkCss = htmlData.includes(headLinkCss)
    
            const htmlArr = htmlData.split('</head>') // 根据 '</head>' 分割数据为数组
            let htmlHeadBefore = htmlArr[0] // 获取第一个数据
    
            if (isDev) {
              // 如果是开发环境,则将生成的css以 '<style> ... </style>' 形式注入到模板文件中,以便开发调试
              const iconCss = compilation.assets[cssName].source()
              if (!iconCss) return
              htmlHeadBefore += '<style>' + iconCss + '</style>'
            } else if (!findHeadLinkCss) {
              // 如果是生成环境,且模板文件中不存在head link css标签,便将前面生成的head link css标签注入到数据中
              htmlHeadBefore += headLinkCss
            }
    
            // 最后链接前后代码
            const handledHtml = htmlHeadBefore + '</head>' + htmlArr[1]
    
            // 替换掉准备输出的模板资源文件
            compilation.assets[template] = {
              source: function () {
                return handledHtml;
              },
              size: function () {
                return handledHtml.length;
              }
            };
          }
        }
      })
    }
    
    1. A lógica do código é basicamente corrigida, aqui estão alguns conhecimentos simples do plugin webpack
    • Pontos de conhecimento envolvidos:
      • Construtor da classe ES6, o que o construtor não tem muito a dizer aqui, semelhante à classe back-end
      • Ganchos de eventos Webpack tapable, consulte a documentação oficial, você pode obter um entendimento preliminar, semelhante ao comissionamento do back-end {over} {filter}
      • Webpack é compilercom compilationeste oficial Webpack evento baseada principalmente em tapableescritos
    • Análise do código fonte:
    // 声明插件构造函数
    class WebpackQcIconfontPlugin {
    
      // 构造函数本身
      constructor(options) {
        // 用来对传入的options进行处理,统一的处理便于日后的维护,也是你自己后面编写文档是查看options 属性一个非常好的窗口
        this.options = options || {};
        if (!this.options.url) throw new Error('[' + pluginName + '] Missing options url!');
        ... ...
      }
    
      // 构造函数的原型函数apply,webpack插件需要
      apply(compiler) {
        // 这里我们获取到 webpack 插件为我们提供的事件对象 compiler
    
        // 对即将使用到的options进行获取,我通常习惯将他们重新获取赋值,在这里,而不是直接在代码中使用大量的 options.XXX,原因是当我需要去除或修改一个options属性时我找的难受,其次是我可以清晰知道这个函数使用了那些options属性,我的options属性将影响到哪些函数
        const options = this.options
        const isDev = options.isDev
        const fontExtList = options.fontExtList
        const cssName = options.cssName
        const template = options.template
    
        // 注册一个 compiler.hooks.compilation 钩子
        compiler.hooks.compilation.tap(pluginName, compilation => {
          // 执行声明的 IconfontDownloadCss 与 IconfontDownloadFontFile 构造函数,之所以将他们分别构造是为了逻辑清晰,增强代码可读性
          new IconfontDownloadCss().apply(compilation, options);
          if (!isDev && fontExtList && fontExtList.length > 0) new IconfontDownloadFontFile().apply(compilation, options);
        })
      }
    }
    
    module.exports = WebpackQcIconfontPlugin;
    
  1. Tal estrutura de base plug-Webpack simples é concluída, o resto é com base na análise que acabo de escrever IconfontDownloadCsse IconfontDownloadFontFilelógica
  2. Finalmente, a fim de facilitar outros desenvolvedores podem usar personalizado, que deve fornecer para o nosso evento plug-gancho, aqui você precisa usar tapableum acesso também solicitou branco detalhado ao site oficial do local, não vou explicar em detalhe, e uma visão geral breve aqui No evento, como o plug-in é escrito
// 声明一个异步事件,这里因为返回参数一致,所以用了统一的声明方式,简单快速便捷
const asyncHooks = new HookMap(key => new AsyncParallelHook(['result', 'callback']))

IconfontDownloadCss No construtor:

// 判断是否存在 iconfontCssCreateEnd 的注册事件
const iconCssCreateEndHooks = asyncHooks.get('iconfontCssCreateEnd')

if (iconCssCreateEndHooks) {
  // 存在使用 iconCssCreateEndHooks.callAsync 执行注册事件
  iconCssCreateEndHooks.callAsync(result, handledData => {
    if (!handledData) return callback()
    resultHandle(handledData)
  })
} else {
  // 不存在则执行默认方法
  resultHandle(result)
}

  // 注册事件时使用如下方法,和官网是一致的:
  WebpackQcIconfontPlugin.getHooks.for('iconfontCssCreateEnd').tapAsync(pluginName, (result, cb) => {
    result += '1111111'
    cb(result)
  })

IconfontDownloadFontFile No construtor:

// 判断是否存在 iconfontFileDownloadEnd 的注册事件
const iconfontFileDownloadEndHooks = asyncHooks.get('iconfontFileDownloadEnd')

if (iconfontFileDownloadEndHooks) {
  存在使用 iconfontFileDownloadEndHooks.callAsync 执行注册事件
  iconfontFileDownloadEndHooks.callAsync(fontFileList, handledData => {
    if (!handledData) return callback()
    resultHandle(handledData)
  })
} else {
  // 不存在则执行默认方法
  resultHandle(fontFileList)
}

// 注册事件时使用如下方法:
WebpackQcIconfontPlugin.getHooks.for('iconfontFileDownloadEnd').tapAsync(pluginName, (fontFileList, cb) => {
  const testFile = '测试使用的文件而已'
  fontFileList.push({
    filename: 'test.text',
    data: {
      source: function () {
        return testFile;
      },
      size: function () {
        return testFile.length;
      }
    }
  })
  cb(fontFileList)
})

Como usar

npm install webpack-qc-iconfont-plugin

webpack.config.js Ligue no arquivo:

// 引入插件
const WebpackQcIconfontPlugin = require('iconfont-webpack-plugin')

module.exports = {
  plugins: [
    // 插件调用代码
    new WebpackQcIconfontPlugin({
      url: '//at.alicdn.com/t/font_xxxxxxx_xxxxxx.css',
      isDev: true,
     fontPath: './iconfont/iconfont',
     iconPrefix: '.cu-icon-',
     keepIconFontStyle: false,
     fontExt: ['.eot', '.ttf', '.svg', '.woff', '.woff2'],
     template: 'index.html'
    }),
  ]
};

Opções

  • url

    • Tipo: String
    • Padrão: nenhum, este parâmetro é necessário (nenhum erro será relatado)
    • Descrição: obtenha o URL do código CSS no Ali icon-My icon item-
    • Uso básico:new WebpackQcIconfontPlugin({url: '//at.alicdn.com/t/font_xxxxxxx_xxxxxx.css' })
  • isDev

    • Tipo: String,
    • Padrão:true
    • Descrição: se está atualmente no modo de desenvolvimento
  • fontPath

    • Tipo: String
    • Padrão:'./iconfont/iconfont'
    • Descrição: baixar o caminho de arquivo de ícone da fonte, única isDevcomo falsa, o ambiente de produção só é válida
  • iconPrefix

    • Tipo: String
    • Padrão: consistente com o arquivo de origem .icon-
    • Descrição: prefixo uniforme para ícones de fonte.Se definido como { iconPrefix: '.cu-icon-' }, a chamada do ícone é:<i class="iconfont cu-icon-XXX"></i>
  • keepIconFontStyle

    • Tipo: Booleano
    • Padrão: indefinido, que não está aberto, não retém
    • Descrição: se quer manter o arquivo de origem css .iconfont{/*...*/}no estilo da propriedade utilizada para o vant e similares têm as suas configurações iniciais ícone de fonte própria da biblioteca de componentes, que como você não usam componentes similares, recomenda-se aberta ou personalize um, Caso contrário, seu ícone não terá o estilo inicial
  • fontExt

    • Tipo: Matriz
    • Padrão: ['.eot', '.ttf', '.svg', '.woff', '.woff2'], ou seja, todos os downloads
    • Descrição: Extensão formato de ícone da fonte para download, única isDeveficaz é falsa
  • template

    • Tipo: String
    • Padrão:index.html
    • Descrição: o ícone gerado css será injetado automaticamente no arquivo de modelo. Depois que o ícone for gerado, ele será injetado automaticamente no arquivo de modelo de acordo com a configuração sem chamada manual. Se a injeção automática não for necessária, o valor poderá ser definido como nulo
    • NOTA: o modo de desenvolvimento css vai ser <style> ... </style>injectado sob a forma, será próxima geração modo de <link rel="stylesheet" href="./iconfont.css">injecção Modo

Sumário

  • uso e fonte códigos detalhados em meu github Webpack-qc-iconfont plugins lá, há poucos parceiros necessidade pode ir para o download
  • Por fim, analise as deficiências do plug-in:
    • Não há implementação para avaliar automaticamente o ambiente de produção e desenvolvimento de acordo com o ambiente do modo Webpack. O aprendizado não é muito bom. Encontrei muitos documentos e ainda não sei como alcançá-lo.
    • A parte do arquivo de modelo do plug-in sempre parece um pouco problemática. Inicialmente, eu queria implementar a configuração automática de acordo com a configuração de exportação do Webpack. Nenhuma configuração é necessária, mas parece ser a aparência ideal e completa e realista.
  • O que eu aprendi
    • A compreensão em profundidade da implementação do princípio da Webpack Widget mestre preliminar compilerecompilation
    • Eu estou entendendo. tapable
    • Entender que o futuro do front-end será cada vez melhor, porque mais e mais coisas podem ser alcançadas. Ao revisar as informações, eu também reconheci o front-end e encontrei muitas coisas novas e a redação de códigos que não entendi.
    • Finalmente, desejo que todo companheiro de front-end que esteja trabalhando duro para melhorar cada vez mais, continue avançando e aprendendo no caminho de front-end, não desista facilmente!

Nota: Antes deste artigo ser publicado na 52pojie, porque muitos parceiros pequenos não tinham uma conta e não podiam ver o artigo, então eu me transferi para o meu blog e o publiquei novamente.Em vista disso, tentarei postar em duas cópias ~~~~~ Hahaha

Autor: leona
descrição link: https://www.cnblogs.com/leona-d/p/12697281.html
Aviso: Este artigo pertence ao autor e Blog Total Park, bem-vindo para reimprimir, mas sem o consentimento do autor declarada por esta seção devem ser mantidos E forneça o link do texto original em uma posição óbvia na página do artigo

Acho que você gosta

Origin www.cnblogs.com/leona-d/p/12697281.html
Recomendado
Clasificación