深入浅出webpack-loader

719 阅读2分钟

webpack-loader

webpack 默认只能对js进行打包,webpack内部默认了Defaullt Loader能够去解析js,而其他文件就需要借助别的一些loader去加载,因此Webpack 实现不同种类资源模块加载的核心就是 Loader。

如何加载资源模块

如我们需要加载xxx.less文件的话,那么我们一般会选择三个loader,他们分别是less-loader,css-loader,css-loader

而他们在webpack配置文件上的配置方式是


module: {
    rules: [
      {
        test: /\.less$/,
        use: [
          'style-loader',
          'css-loader',
          'less-loader'
        ]
      }
    ]
  }

对于less文件的解析。webpack 是先使用less-loader将less文件内容转能css内容,然后使用css-loader将css内容转化成js能识别的模块包,最后使用style-loader将其插入html中

深入理解一下这三个过程

在webpack complication的过程中,webpack会递归的去读取加载文件,当读取到.less文件时,那么会依次调用 less-loader css-loader style-loader

初始化一个项目

项目的目录结构大致是

1.png

package.json

{
  "name": "lesstest",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "dev": "webpack-dev-server --progress --colors --devtool source-map --hot --inline",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "html-webpack-plugin": "^5.3.2"
  },
  "devDependencies": {
    "css-loader": "^6.2.0",
    "less": "^4.1.1",
    "less-loader": "^10.0.1",
    "style-loader": "^3.2.1",
    "webpack": "^5.1.3",
    "webpack-cli": "^3.3.12",
    "webpack-dev-server": "^3.11.0"
  }
}


webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin') // 通过 npm 安装
const path = require('path')

module.exports = {
    entry: './src/main.js',
    output: {
        filename: '[name].bundle.js',
        path: path.resolve(__dirname, 'dist'),
        clean: true
    },
    module: {
        rules: [
            {
                test: /\.less$/,
                use: ['style-loader', 'css-loader', 'less-loader']
            }
        ]
    },
    devServer: {
        contentBase: './dist',
        hot: true,
        port: 9000
    },
    plugins: [new HtmlWebpackPlugin({ template: './index.html' })]
}


main.js
console.log('1111111111')
import './assets/css/index.less'
index.less
#app {
    p {
        color: red;
    }
    a {
        font-size: 18px;
        color: green;
    }
}
最终的运行结果

2.png

less-loader过程

5.png 当我们配置好了less文件对应的less-loader时,我们可以一起看一下less-loader源码里less-loader里加载的产物和生成的产物分别是什么

加载的产物代码

#app {
    p {
        color: red;
    }
    a {
        font-size: 18px;
        color: green;
    }
}

上面不出所料就是less文件的源码

生成的产物代码
#app p {
  color: red;
}
#app a {
  font-size: 18px;
  color: green;
}

也没有什么意外,确实是转化后的css代码

css-loader过程

加载的产物代码

#app p {
  color: red;
}
#app a {
  font-size: 18px;
  color: green;
}

上面不出所料就是less-loader转化后的代码

生成的产物代码

___CSS_LOADER_EXPORT___.push([module.id, "#app p {\n  color: red;\n}\n#app a {\n  font-size: 18px;\n  color: green;\n}\n", "",{"version":3,"sources":["webpack://./src/assets/css/index.less"],"names":[],"mappings":"AAAA;EAEQ,UAAA;AAAR;AAFA;EAKQ,eAAA;EACA,YAAA;AAAR","sourcesContent":["#app {\n    p {\n        color: red;\n    }\n    a {\n        font-size: 18px;\n        color: green;\n    }\n}\n"],"sourceRoot":""}]);

css-loader 生成的代码

style-loader过程

style-loader的主要作用是讲已经生成的css用js代码包裹,然后插入html中


/* istanbul ignore next  */
function insertStyleElement(options) {
  console.log(options)
  var style = document.createElement("style");
  options.setAttributes(style, options.attributes);
  options.insert(style);
  return style;
}

module.exports = insertStyleElement;

3.png

4.png

自己手动去实现一个loader

主要的功能是讲css里面的px布局转化成rem,按一定的比例方式,如 24px 转化成0.48rem,根元素的字体为font-size为50px



module.exports = function (source) {
    source = source.replace(/\d+px/, function(str){
        return 0.02 * parseFloat(str) + "rem";
    });
    return source
}

5.png