美文网首页
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...

    相关文章

      网友评论

          本文标题:webpack - loader

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