美文网首页
webpack loader知识

webpack loader知识

作者: pipu | 来源:发表于2020-10-16 10:06 被阅读0次

loader 知识相关

loader就是一个暴露特定函数的node模块,该函数将在一个资源应该被改loader转换时调用。在这个函数中可以通过上下文this来访问Loader API;

const {getOptions} = require('loader-utils');
const {promisify} = require('util');
const fs = require('fs');
const access = promisify(fs.access);
const readFile = promisify(fs.readFile);
const alertText = `
if(typeof alert ==='function'){
alert(3);
}
`
let nodeModulesPath = '';

function loader(content, map, meta) {
    const callback = this.async();
    if (!nodeModulesPath) {
        nodeModulesPath = `${this.rootContext}/node_modules`
    }
    if (this.context.startsWith(nodeModulesPath)) { // node_modules 中的文件
        callback(null, content, map, meta)
    } else {
        let trueContent = content;
        const options = getOptions(this);
        const {alert = false, comment = false} = options;
        console.log('options', options);
        console.log('this.context', this.context);
        if (alert) {
            trueContent = `${trueContent};${alertText};`;
        }
        if (comment) {
            const commentPath = this.resourcePath.replace(/\.jsx?$/, '.cm');
            console.log('commentPath', commentPath);
            readFile(commentPath,'utf-8').then(function (commentText) {
                console.log('commentText', commentText);
                trueContent = `${trueContent}/*${commentText}*/`;
                callback(null, trueContent, map, meta);
            }).catch(function () {
                console.log('not found comment file')
                callback(null, trueContent, map, meta);
            })
        } else {
            callback(null, trueContent, map, meta);
        }
    }
}

module.exports = loader;

一些准侧

一些关于创建一个loader的准则
Keep them simple.
Utilize chaining.
Emit modular output.
Make sure they're stateless.
Employ loader utilities.
Mark loader dependencies.
Resolve module dependencies.
Extract common code.
Avoid absolute paths.
Use peer dependencies.

  • Simple 简单 单一任务
  • Chaining 链式调用
  • Modular 模块化
  • Stateless 无状态
  • Loader Utilites 使用loader-utils 包中提供的工具方法
  • Loader Dependencies 外部依赖添加
  • Module Dependencies
    根据模块类型的不同,确定依赖的模式也会不同。例如在css中,使用@importlurl(...)声明。这些依赖应该被模块系统解决。
    这有两种方式解决:
  • 将其转换为 require 声明
  • 使用 this.resolve方法解决依赖路径
  • Common Code 公共代码
  • Absolute Paths 绝对路径 可以使用loader-utils 中的stringifyRequest 方法来将绝对路径转为相对领
  • Peer Dependencies 如果改loader是其他包外壳

file-loader

filte-loader 源码简单分析,查看加载资源,将资源输出到生产文件中去
调用interpolateName方法生成插入的文件名称,可以包含文件路径,插入的文件名称是在不考虑发布路径(publicPath)的情况下的引用路径。

import { getOptions, interpolateName } from 'loader-utils';
  const url = interpolateName(this, name, {
    context,
    content,
    regExp: options.regExp,
  });

根据用户设置了输出路径,来调整输出路径

  let outputPath = url;

  if (options.outputPath) {
    if (typeof options.outputPath === 'function') {
      outputPath = options.outputPath(url, this.resourcePath, context);
    } else {
      outputPath = path.posix.join(options.outputPath, url);
    }
  }

确定发布的路径

  let publicPath = `__webpack_public_path__ + ${JSON.stringify(outputPath)}`;

  if (options.publicPath) {
    if (typeof options.publicPath === 'function') {
      publicPath = options.publicPath(url, this.resourcePath, context);
    } else {
      publicPath = `${
        options.publicPath.endsWith('/')
          ? options.publicPath
          : `${options.publicPath}/`
      }${url}`;
    }

    publicPath = JSON.stringify(publicPath);
  }

  if (options.postTransformPublicPath) {
    publicPath = options.postTransformPublicPath(publicPath);
  }

输出路径将文件放置到相应的输出目录中去,发布路径将告知模块系统如何加载对应的文件资源


  if (typeof options.emitFile === 'undefined' || options.emitFile) {
   this.emitFile(outputPath, content, null, { immutable });
  }

  const esModule =
    typeof options.esModule !== 'undefined' ? options.esModule : true;

  return `${esModule ? 'export default' : 'module.exports ='} ${publicPath};`;
}

通过查看file-loader的原码可以看出,file-loader的功能就是将通过该loader处理的资源文件做复制处理并获得文件最终的路径告知webpack模块系统其正确的加载路径。同时也能看出在编写该loader中的一些符合webpack推荐的规则:

  • 单一指责 只负责处理文件模块化依赖 当然也响应符合链式调用规则
  • 使用loader-utils中的方法, getOptions,interpolatename, 已经常见的schema-utils的使用
  • 通过访问上下文,获取资源的路径信息,内容和文件的输出处理

参考文章

深入浅出 Webpack

相关文章

  • webpack loader知识

    loader 知识相关 loader就是一个暴露特定函数的node模块,该函数将在一个资源应该被改loader转换...

  • 7 webpack + vue-loader

    vue-loader vue-loader基于webpack webpack+vue-loader

  • webpack4打包css,html

    webpack安装 webpack打包css 安装style-loader css-loader webpack打...

  • webpack

    webpack 唯一功能:打包loader,没有loader,webpack只能打包js,有了loader,可以打...

  • Webpack Loader源码导读之css-loader

    原文地址:Webpack Loader源码导读之css-loader 在上一篇Webpack Loader源码导读...

  • webpack(壹)

    常用webpack 插件 html-webpack-plugin css-loader style-loader...

  • webpack 打包html img src问题

    最近,在看webpack打包图片的一些知识,首先webpack打包图片用的是url-loader; 当前loade...

  • loader初识

    loader 介绍 loader让webpack能够去处理那些非JavaScript文件(webpack自身只理解...

  • 怎么编写一个 webpack loader

    编写 loader 前需要知道 webpack loader 的执行循序?从右到左执行。 为什么 webpack ...

  • 写一个webpack-loader

    都知道webpack的loader,可是你写过一个loader吗?最近有空写了一个webpack-loader,如...

网友评论

      本文标题:webpack loader知识

      本文链接:https://www.haomeiwen.com/subject/exfzpktx.html