美文网首页
webpack - loader

webpack - loader

作者: 我叫Aliya但是被占用了 | 来源:发表于2020-01-12 14:13 被阅读0次

Webpack学习笔记
webpack - 项目优化
webpack实现原理
webpack - loader
webpack - plugin
webpack - 项目优化2

    resolveLoader: {
        // loader查找规则
        modules: [path.resolve(__dirname, 'node_modules'),path.resolve(__dirname, 'loaders')],
        // loader别名
        alias: {
            txt: path.resolve(__dirname, 'loaders', 'txt.js')
        }
    },
    module: {
        rules: [
            {
                exclude: /node_modules/,
                test: /\.txt$/,
                use: [ path.resolve(__dirname, 'loaders', 'txt.js') ] 
            },
            {
                exclude: /node_modules/,
                test: /\.txt$/,
                use: 'txt'
            },
            {
                test: /\.less$/,
                use: [ 'style.js', 'less.js' ]
            }
  • exclude 不作用于此目录下文件

  • 绝对路径、alias别名、loader查找规则、第三方库(node_modules) loader的4种引入方式

  • pre -> normal(默认) -> inline -> post,loader的类型及执行顺序

            {
                test: /\.less$/,
                use: [ 'style.js', 'less.js' ],
                enforce: 'pre'  // pre loader
            }
  • loader.pitch 它是正向执行的(与loader组成一个洋葱),如果它有返回值,将会终止后续loader的执行
loader.pitch = function () { console.log('我会最早执行,即洋葱的前半部分'); return 'xxx' }
  • inline 只能在代码中使用
require('!inline-loader!./a.js')     // 不再匹配其它loader
require('-inline-loader!./a.js')     // 把pre和normal屏蔽掉
require('inline-loader!./a.js')      // 没有normal

options

            {
                exclude: /node_modules/,
                test: /\.txt$/,
                use: {
                    loader: 'txt',
                    options: { content: '明治维新燃油费' }  // 为loader配置options
                }
            },
let loaderUtils = require('loader-utils')
module.exports = function (source) {
    // this上下文相关属性和方法参见 https://www.webpackjs.com/api/loaders/
    // 读取webpack.config.js中配置的options
    // console.log(this.query) 
    // let content = this.query && this.query.content || '统一换成这个'
    
    // 好鸡肋,为什么要用
    // console.log(loaderUtils.getOptions(this))
    let query = loaderUtils.getOptions(this)
    let content = query && query.content || '统一换成这个'

    // return `module.exports = "${content}"`

    let cb = this.async()   // 将Loader变为异步loader
    setTimeout(() => cb(`module.exports = "${content}"`), 2000)
}

打包后

"./common/xx.txt": eval("module.exports = \"明治维新燃油费\"\n\n//# sourceURL=webpack:///./common/xx.txt?");

参数校验

    module: {
        rules: [
            {
                test: /\.html/,
                use: {
                    loader: 'html-minify-loader.js',
                    options: {
                        comments: false
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: './template/index.html'
        })
        // 本质上是require了index.html,所以loader会起作用
        // 可以配置嵌入的js是否有?hash、是否去掉”、是否消除空白等
    ]
// html-minify-loader.js
let Minimize = require('minimize')  // 代码压缩
let schemaUtils = require('schema-utils') // 参数校验
function loader (source) {
    let porps = {
        "type": "object",
        "properties": {
          "comments": {
            "type": "boolean"
          }
        }
    } 
    // 验证不通过会抛出异常
    schemaUtils(porps, this.query, 'html-minify-loader')

    let mini = new Minimize(this.query)
    source = mini.parse(source); 
    return `module.exports = ${JSON.stringify(source)}`
}
module.exports = loader

根据模板生成入口html文件

    module: {
        rules: [
            {
                test: /\.html/,
                use: {
                    loader: 'html-layout-loader.js',
                    options: {
                        template: path.resolve(__dirname, 'template', 'index.html'),
                        reg: /\{\{content\}\}/
                    }
                }
            }
        ]
    },
    plugins: [
        new HtmlWebpackPlugin({
            filename: 'home.html',
            template: './template/home.html'
        }),
        new HtmlWebpackPlugin({
            filename: 'login.html',
            template: './template/login.html'
        })
    ]
// html-layout-loader.js
let fs = require('fs')
// 根据模板生成入口html文件
function loader (source) {
    let {template, reg} = this.query
    let cb = this.async()
    fs.readFile(template, 'utf8', function (err, data) {
        source = data.replace(reg, source)
        cb(err, `module.exports = ${JSON.stringify(source)}`)
    })
    // return `module.exports = ${JSON.stringify(source)}`
}
module.exports = loader

npx webpack --watch 对模板进行watch

// html-layout-loader.js
    ...
    // webpack --watch 时,对模板也进行实时打包
    this.addDependency(template)    
    ...

处理图片资源

        rules: [
            {
                test: /\.png$/,
                use: {
                    loader: 'file-loader.js', // 处理引用的图片路径
                }
            }
        ]
// file-loader.js
let loaderUtils = require('loader-utils')
function loader (source) {
    // 生成新文件名,8位哈希值.原名.原扩展名
    let name = loaderUtils.interpolateName(this, `[hash:8].[name].[ext]`, { content: '哈希摘要的依据' })

    // 发射到目标文件根目录
    this.emitFile(name, source)

    return `module.exports = "${name}"`
}
loader.raw = true;  // 表示source是二进制(buffer)
module.exports = loader

打包后dist目标下出现f371901e.avatar.png,bundle中"./common/avatar.png":(function(module, exports) { eval("module.exports = \"f371901e.avatar.png\"...

  • 小于50k的文件base54化
        rules: [
            {
                test: /\.png$/,
                use: {
                    loader: 'url-loader.js',     // base64化小图
                    options: { minisize: 50 * 1024 }
                }
            }
        ]
// url-loader.js
const mime = require("mime");
function loader (source) {
    let { minisize } = this.query
    if (source.length > minisize) {
        return require('./file-loader').call(this, source)
    } else { 
        // 小于指定大小,base64化图片
        let type = mime.getType(this.resourcePath)
        return `module.exports = "data:${type};base64,${source.toString('base64')}"`
    } 
}
loader.raw = true;  // 表示source是二进制(buffer)
module.exports = loader

打包后dist/bundle.js中"./common/avatar.png":(function(module, exports) { eval("module.exports = \"data:image/png;base64,iVBORw...

相关文章

  • 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...

  • loader初识

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

  • 怎么编写一个 webpack loader

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

  • 写一个webpack-loader

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

  • 8-webpack-less-loader使用

    这里webpack中loader处理规则,问题,解决方法 一.webpack中loader处理规则 判断当前需要打...

  • webpack 之 css module

    webpack 之 css module webpack配置css-loader?modulesmodules ...

网友评论

      本文标题:webpack - loader

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