最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 你真的了解webpack中的loader么?

    正文概述 掘金(我系小艾)   2021-03-23   632

    什么是Loader

    webpack官网原话:

    webpack only understands JavaScript and JSON files. Loaders allow webpack to process other types of files and convert them into valid modules that can be consumed by your application and added to the dependency graph.(简单说就是webpack只支持js和json,对于不支持的其类型文件的处理就需要依赖各种Loader来转化文件为webpack支持的模块了。嗯,Loader 字面意思不就是加载器么)

    曾经了解的loader

    为不同资源类型配置正确的loader很重要!X 3(重要的事说三遍),使用webpack打包项目时需要为js(x), less等配置对应的loader,还有其他资源对应的loader,参照配置的格式,选用对的loader就可以,唯一需要注意的是loader的顺序是从右到左的。so easy,参考官网哐哐哐就可以配置可以使用的loader了。

    //webpack.config.js
        ...
        module: {
            rules: [
                {
                    test: /\.jsx?$/,
                    use: [
                        {
                            loader: 'thread-loader',
                            options: {
                                workers: 3
                            }
                        },
                        'babel-loader?cacheDirectory=true'
                    ]
                },
                {
                    test: /\.less$/,
                    use: [
                        'style-loader',
                        'css-loader',
                        'less-loader',
                        'postcss-loader',
                        {
                            loader: 'px2rem-loader',
                            options: {
                                remUnit: 75,
                                percisson: 8
                            }
                        }
                    ]
                }
                ...
            ]
        },
    

    揭开loader的神秘面纱

    loader其实就是一个函数,接收一个字符串,返回一个字符串(注意格式,需要是个模块格式)。webpack中loader runner会调用这个loader(函数),并且把前一个loader的返回作为入参传入当前loader,loader 函数内的会被webpack和loader runner注入上下文,有很多有用的 API,可以使用this返回,如this.callback, this.async等。

    /**
     *
     * @param {string|Buffer} content Content of the resource file
     * @param {object} [map] SourceMap data consumable by https://github.com/mozilla/source-map
     * @param {any} [meta] Meta data, could be anything
     */
    function webpackLoader(content, map, meta) {
      // 转换逻辑
      return `export default ${JSON.stringify(content)}`
    }
    
    

    同步loader 和异步loader

    同步的loader如果只有一个返回结果,可以使用return或者this.callback的方式,如果有多个返回则只能使用this.callback。⚠️使用this.callback之后需要返回undefined (return;)

    // 主要关注 err 和 content
    this.callback(
      err: Error | null, // 用于报错
      content: string | Buffer,// 返回内容
      sourceMap?: SourceMap, // sourcemap
      meta?: any // meta
    );
    
    function webpackLoader(content, map, meta) {
      // 转换逻辑
      this.callback(null, content, map, meta);
      return; //always return undefined when calling callback()
    }
    
    

    异步loader的返回则需要先调用this.async()(通知loader-runner需要异步调用)并返回this .callback。

    function webpackLoader(content, map, meta) {
        const callback = this.async();
        // 转换逻辑
        // 异步操作  
        someAsyncOperation(content, function (err, result) {
        if (err) return callback(err);
        callback(null, result, map, meta);
      });
      
    }
    

    loader-runner 可用于调试

    runLoaders两个参数,第一个是配置options,另一个是回调函数,用于接收loader的返回和异常信息。

    const loaderRunner = require('loader-runner');
    const path = require('path');
    
    // 注意使用runLoaders, loader中无法使用this.emitFile生成文件,需要用fs.writeFile
    loaderRunner.runLoaders({
        resource: path.join(__dirname, 'source.txt'), // 目标文件绝对路径
        loaders: [
            {
                loader: path.join(__dirname, 'index.js'),// loader绝对路径
                options: {name: 'hello'}// 传入的参数,loader中可以使用loader-utils获取
            }
         ]
    }, (err, result) => {
        // err loader中的异常信息
        err && console.log(err);
        console.log('result', result);
    })
    

    重点来说一下回调函数中的两个参数,err和result。err是loader的异常,如果loader中直接throw new Error('error') 或者this.callback(new Error('error')),那么将会传到err中。 第二个参数result是包含一些返回结果相关的信息,主要看result.result,存放的是返回的结果,来个简单的demo吧

    // 需要安装loader-runner 和loader-utils
    //source.txt
    hello world
    
    //demo-loader.js
    const loaderUtils = require('loader-utils');
    // loader 格式 (source: string) => string
    module.exports = function(source) {
        const { name } = loaderUtils.getOptions(this);
        console.log('name', name)
        console.log('loader is working, but do nothing');
        return `export default ${JSON.stringify(source)}`;
    }
    
    // test.js
    const loaderRunner = require('loader-runner');
    const path = require('path');
    
    // 使用runLoaders 无法使用emitFile生成文件
    loaderRunner.runLoaders({
        resource: path.join(__dirname, 'source.txt'),
        loaders: [{loader: path.join(__dirname, 'index.js'), options: {name: 'hello'}}]
    }, (err, result) => {
        err && console.log(err);
        console.log('result', result);
    })
    

    你真的了解webpack中的loader么?

    以下是copy来的备注

    	// err: Error?
    
    	// result.result: Buffer | String 此处是个数组
    	// The result
    	// only available when no error occured
    
    	// result.resourceBuffer: Buffer
    	// The raw resource as Buffer (useful for SourceMaps)
    	// only available when no error occured
    
    	// result.cacheable: Bool
    	// Is the result cacheable or do it require reexecution?
    
    	// result.fileDependencies: String[]
    	// An array of paths (existing files) on which the result depends on
    
    	// result.missingDependencies: String[]
    	// An array of paths (not existing files) on which the result depends on
    
    	// result.contextDependencies: String[]
    	// An array of paths (directories) on which the result depends on
    

    先记录这么多,未完待续。。。


    起源地下载网 » 你真的了解webpack中的loader么?

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元